aboutsummaryrefslogtreecommitdiff
path: root/chapters/pseudocode.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'chapters/pseudocode.adoc')
-rw-r--r--chapters/pseudocode.adoc210
1 files changed, 21 insertions, 189 deletions
diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
index 55c35d4..422188a 100644
--- a/chapters/pseudocode.adoc
+++ b/chapters/pseudocode.adoc
@@ -1,7 +1,7 @@
//
// This confidential and proprietary software may be used only as
// authorised by a licensing agreement from ARM Limited
-// (C) COPYRIGHT 2021-2023 ARM Limited
+// (C) COPYRIGHT 2021-2022 ARM Limited
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorised
// copies and copies may only be made to the extent permitted
@@ -94,12 +94,6 @@ size_t tensor_size(dim_t shape) {
}
return size;
}
-
-// Return the size of the tensor in the given axis
-// For a rank=0 tensor, returns 1 for all axes
-size_t shape_dim(dim_t shape, int axis) {
- return (axis >= rank(shape)) ? 1 : shape[axis];
-}
----
==== Tensor Read
@@ -131,45 +125,6 @@ void tensor_write<type>(<type> *address, dim_t shape, dim_t index, <type> value)
}
----
-==== Variable Tensor Allocate
-
-variable_tensor_allocate allocates the mutable persistent memory block for storing variable tensors.
-The shape argument contains the shape of the allocated memory block for the variable_tensor.
-The uid argument is a globally unique identifier for variable tensors.
-
-[source,c++]
-----
-tensor_t* variable_tensor_allocate<in_t>(dim_t shape, int32_t uid) {
- size_t size = tensor_size(shape);
- tensor_t *allocated_tensor = new tensor_t;
- allocated_tensor->data = new in_t[size];
- allocated_tensor->uid = uid;
- allocated_tensor->is_written = false;
- allocated_tensor->shape = shape;
- allocated_tensor->type = in_t;
- return allocated_tensor;
-}
-----
-
-==== Variable Tensor Lookup
-
-variable_tensor_lookup checks whether a variable tensor has been allocated or not.
-The uid argument is a globally unique identifier for variable tensors.
-
-[source,c++]
-----
-tensor_t variable_tensor_lookup(int32_t uid) {
- // The global all_allocated_variable_tensors was instantiated at the first
- // time of executing the tosa graph
- for_each(tensor_t allocated_tensor in all_allocated_variable_tensors) {
- if (allocated_tensor.uid == uid) {
- return allocated_tensor;
- }
- }
- return NULL;
-}
-----
-
==== Broadcast Helpers
The following function derives the broadcast output shape from the input shapes.
@@ -221,44 +176,21 @@ The following functions provide arithmetic while defining requirements such that
[source,c++]
----
-in_t apply_add_s<in_t>(in_t a, in_t b) {
- if (is_floating_point(in_t)) return a + b;
- int64_t c = sign_extend<int64_t>(a) + sign_extend<int64_t>(b);
- REQUIRE(c >= minimum_s<in_t> && c <= maximum_s<in_t>);
- return static_cast<in_t>(c);
-}
-
-in_t apply_add_u<in_t>(in_t a, in_t b) {
+in_t apply_add<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) return a + b;
- uint64_t c = zero_extend<uint64_t>(a) + zero_extend<uint64_t>(b);
- REQUIRE(c >= minimum_u<in_u_t> && c <= maximum_u<in_u_t>);
- return truncate<in_t>(c);
-}
-
-in_t apply_arith_rshift<in_t>(in_t a, in_t b) {
- int32_t c = sign_extend<int32_t>(a) >> sign_extend<int32_t>(b);
- return static_cast<in_t>(c);
-}
-
-in_t apply_intdiv_s<in_t>(in_t a, in_t b) {
- int64_t c = sign_extend<int64_t>(a) / sign_extend<int64_t>(b);
- REQUIRE(c >= minimum_s<in_t> && c <= maximum_s<in_t>);
- return static_cast<in_t>(c);
+ int64_t c = (int64_t)a + (int64_t)b;
+ REQUIRE(c >= minimum<in_t> && c <= maximum<in_t>);
+ return (in_t)c;
}
in_t apply_ceil<in_t>(in_t input) {
return input value rounded up to nearest integer
}
-in_t apply_clip_s<in_t>(in_t value, in_t min_val, in_t max_val) {
- if (is_floating_point(in_t>) {
- REQUIRE(min_val <= max_val);
- }
- else {
- REQUIRE(sign_extend<int64_t>(min_val) <= sign_extend<int64_t>(max_val));
- }
- value = apply_max_s<in_t>(value, min_val);
- value = apply_min_s<in_t>(value, max_val);
+in_t apply_clip<in_t>(in_t value, in_t min_val, in_t max_val) {
+ REQUIRE(min_val <= max_val);
+ value = apply_max(value, min_val);
+ value = apply_min(value, max_val);
return value;
}
@@ -280,37 +212,22 @@ in_t apply_log<in_t>(in_t input) {
return the natural logarithm of input
}
-in_t apply_logical_rshift<in_t>(in_t a, in_t b) {
- uint64_t c = zero_extend<uint32_t>(a) >> zero_extend<uint32_t>(b);
- return static_cast<in_t>(c);
-}
-
-in_t apply_max_s<in_t>(in_t a, in_t b) {
+in_t apply_max<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) {
if (isNaN(a) || isNaN(b)) {
return NaN;
}
- if (a >= b) return a; else return b;
}
- // Integer version
- if (sign_extend<int64_t>(a) >= sign_extend<int64_t>(b)) return a; else return b;
+ if (a >= b) return a; else return b;
}
-in_t apply_min_s<in_t>(in_t a, in_t b) {
+in_t apply_min<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) {
if (isNaN(a) || isNaN(b)) {
return NaN;
}
- if (a < b) return a; else return b;
}
- // Integer version
- if (sign_extend<int64_t>(a) < sign_extend<int64_t>(b)) return a; else return b;
-}
-
-in_t apply_mul_s<in_t>(in_t a, in_t b) {
- if (is_floating_point(in_t)) return a * b;
- int64_t c = sign_extend<int64_t>(a) * sign_extend<int64_t>(b);
- return static_cast<in_t>(c);
+ if (a < b) return a; else return b;
}
in_t apply_pow<in_t>(in_t a, in_t b) {
@@ -321,17 +238,11 @@ in_t apply_sqrt<in_t>(in_t input) {
return the square root of input
}
-in_t apply_sub_s<in_t>(in_t a, in_t b) {
+in_t apply_sub<in_t>(in_t a, in_t b) {
if (is_floating_point(in_t)) return a - b;
- int64_t c = sign_extend<int64_t>(a) - sign_extend<int64_t>(b);
- REQUIRE(c >= minimum_s<in_t> && c <= maximum_s<in_t>);
- return static_cast<in_t>(c);
-}
-
-in_t apply_sub_u<in_t>(in_t a, in_t b) {
- uint64_t c = zero_extend<uint64_t>(a) - zero_extend<uint64_t>(b);
- REQUIRE(c >= minimum_u<in_u_t> && c <= maximum_u<in_u_t>);
- return truncate<in_t>(c);
+ int64_t c = (int64_t)a - (int64_t)b;
+ REQUIRE(c >= minimum<in_t> && c <= maximum<in_t>);
+ return (in_t)c;
}
int32_t count_leading_zeros(int32_t a) {
@@ -349,69 +260,6 @@ int32_t count_leading_zeros(int32_t a) {
}
----
-==== Type Conversion Helpers
-
-The following definitions indicate the type to be used when the given parameters are provided.
-
-[source,c++]
-----
-
-// Returns a signed version of the given type
-// A no-op for floating-point types
-Type make_signed(Type in_t)
-{
- switch(in_t) {
- case bool_t:
- return bool_t;
- case i8_t:
- return int8_t;
- case i16_t:
- return int16_t;
- case i32_t:
- return int32_t;
- case i48_t:
- return int48_t;
- case fp16_t:
- return fp16_t;
- case bf16_t:
- return bf16_t;
- case fp32_t:
- return fp32_t;
- }
-}
-
-// Returns the usigned type of the given type
-// Error to call this with anything but i8_t or i16_t
-
-Type make_unsigned(Type in_t)
-{
- ERROR_IF(in_t != i8_t && in_t != i16_t);
- switch(in_t) {
- case i8_t:
- return uint8_t;
- case i16_t:
- return uint16_t;
- }
-}
-
-out_t static_cast<out_t>(in_t value)
-{
- // Operates similar to the c++ standard static_cast
- // Limited to simple numeric conversion for TOSA.
- // Sign extends signed integer input types if needed
- // Zero extends unsigned integer input types if needed
- // Truncates when converting to a smaller width data type
- // Conversion from integer to floating-point is exact if possible
- // If converting between signless integer types, treated as signed integer
-}
-
-out_t bitcast<out_t>(in_t value)
-{
- // Treats the bits of value as if they were of type out_t
- // Only supported for integer types of the same bit width
-}
-----
-
==== Numeric Conversion Helpers
The following definitions are used in pseudocode to do numeric conversions.
@@ -428,17 +276,13 @@ float_t round_to_nearest_float(in_t f)
Converts the input value into floating-point, rounding to the nearest representable value.
For the required precision see the section: Main inference precision requirements.
-out_t sign_extend<out_t>(in_t input)
- Floating point values are unchanged.
- For two's complement integer values where out_t has more bits than in_t, replicate the top bit of input for all bits between the top bit of input and the top bit of output.
-
-out_t zero_extend<out_t>(in_t input)
- Floating point values are unchanged.
- For two's complement integer values where out_t has more bits than in_t, insert zero values for all bits between the top bit of input and the top bit of output.
+out_t sign_extend(in_t input)
+ Only valid for two's complement integer values where out_t has more bits than in_t.
+ Output = input
+ Replicate the top bit of input for all bits between the top bit of input and the top bit of output.
out_t truncate(in_t input)
output is the sizeof(out_t) least significant bits in input.
- Nop for floating-point types
----
The following definition is used to flatten a list of lists into a single list.
@@ -500,16 +344,4 @@ float_t cos(angle)
bool power_of_two(int32_t value)
return true if value is a power of two, false otherwise
-
-in_out_t maximum_s<Type T>
- return the maximum value when interpreting type T as a signed value as returned by the make_signed helper.
-
-in_out_t minimum_s<Type T>
- return the minimum value when interpreting type T as a signed value as returned by the make_signed helper.
-
-in_out_t maximum_u<Type T>
- return the maximum value when interpreting type T as an unsigned value as returned by the make_unsigned helper.
-
-in_out_t minimum_u<Type T>
- return the minimum value when interpreting type T as an unsigned value as returned by the make_unsigned helper.
----