diff options
author | Eric Kunze <eric.kunze@arm.com> | 2021-06-17 18:01:09 -0700 |
---|---|---|
committer | Eric Kunze <eric.kunze@arm.com> | 2021-06-24 12:18:14 -0700 |
commit | a9101530d8ea7a3cb470b722bc6cf8745ab283ac (patch) | |
tree | 2918f0c0e16515295ef6d112c279902fdddd44fb /chapters/introduction.adoc | |
parent | f19e594f71e04c72ecf937419333b57dc7dcb873 (diff) | |
download | specification-a9101530d8ea7a3cb470b722bc6cf8745ab283ac.tar.gz |
Replace assert with REQUIRE()
REQUIRE is a direct replacement for the asserts, and uses
the unpredictable() function in pseudocode to describe the required
conditions for operators
Change-Id: I35dc81e083d8e41f16728d992bdb8b06b0271226
Signed-off-by: Eric Kunze <eric.kunze@arm.com>
Diffstat (limited to 'chapters/introduction.adoc')
-rw-r--r-- | chapters/introduction.adoc | 119 |
1 files changed, 14 insertions, 105 deletions
diff --git a/chapters/introduction.adoc b/chapters/introduction.adoc index d410121..33ebea1 100644 --- a/chapters/introduction.adoc +++ b/chapters/introduction.adoc @@ -197,17 +197,17 @@ The padding array represents the before and after pair for each dimension. [source,c++] ---- -assert((pad == NULL) || size(pad) == 2 * size(shape)); +REQUIRE((pad == NULL) || size(pad) == 2 * size(shape)); out_t tensor_read<in_t>(in_t *address, dim_t shape, dim_t index, in_t zero_point=0, dim_t pad=NULL) { - assert(in_t == int8_t || zero_point == 0) + REQUIRE(in_t == int8_t || zero_point == 0) unsigned offset = 0; for (i = 0; i < rank(shape); i++) { if (index[i] < 0) { - assert(pad && pad[2 * i] + index[i] >= 0); + REQUIRE(pad && pad[2 * i] + index[i] >= 0); return 0; } if (index[i] >= shape[i]) { - assert(pad && index[i] < shape[i] + pad[2 * i + 1]); + REQUIRE(pad && index[i] < shape[i] + pad[2 * i + 1]); return 0; } offset = offset * shape[i] + index[i]; @@ -223,7 +223,7 @@ out_t tensor_read<in_t>(in_t *address, dim_t shape, dim_t index, in_t zero_point tensor_write<type>(<type> *address, dim_t shape, dim_t index, <type> value) { unsigned offset = 0; for (i = 0; i < rank(shape); i++) { - assert (index[i] >= 0 && index[i] < shape[i]); + REQUIRE(index[i] >= 0 && index[i] < shape[i]); offset = offset * shape[i] + index[i]; } address[offset] = value; @@ -242,10 +242,10 @@ The following function maps an index in the output tensor to an index in the inp [source,c++] ---- dim_t apply_broadcast(dim_t out_shape, dim_t in_shape, dim_t index) { - assert(rank(out_shape) == rank(in_shape)); + REQUIRE(rank(out_shape) == rank(in_shape)); for (i = 0; i < rank(out_shape); i++) { if (out_shape[i] != in_shape[i]) { - assert(in_shape[i] == 1); + REQUIRE(in_shape[i] == 1); index[i] = 0; } } @@ -285,8 +285,8 @@ The apply_scale functions provide a scaling of approximately (multiplier * 2^-sh [source,c++] ---- int32_t apply_scale_32(int32_t value, int32_t multipler, uint6_t shift, bool_t double_round=false) { - assert(multiplier >= 0); - assert(2 <= shift && shift <= 62); + REQUIRE(multiplier >= 0); + REQUIRE(2 <= shift && shift <= 62); int64_t round = 1 << (shift - 1); if (double_round) { if (shift > 31 && value >= 0) round += 1<<30; @@ -294,17 +294,17 @@ int32_t apply_scale_32(int32_t value, int32_t multipler, uint6_t shift, bool_t d } int64_t result = (int64_t)value * multiplier + round; result = result >> shift; - assert(result >= minimum<int32_t> && result <= maximum<int32_t>); + REQUIRE(result >= minimum<int32_t> && result <= maximum<int32_t>); return (int32_t)result; } int32_t apply_scale_16(int48_t value, int16_t multipler, uint6_t shift) { - assert(multiplier >= 0); - assert(2 <= shift && shift <= 62); + REQUIRE(multiplier >= 0); + REQUIRE(2 <= shift && shift <= 62); int64_t round = (1 << (shift - 1)); int64_t result = (int64_t)value * multiplier + round; result = result >> shift; - assert(result >= minimum<int32_t> && result <= maximum<int32_t>); + REQUIRE(result >= minimum<int32_t> && result <= maximum<int32_t>); return (int32_t)result; } ---- @@ -324,7 +324,7 @@ In places where a divide is required, we also use the function below to calculat [source,c++] ---- scale_t reciprocal_scale(uint32_t value) { - assert(value > 0); + REQUIRE(value > 0); scale_t scale; int k = 32 - count_leading_zeros(value - 1); // (1 << k) / 2 < value <= (1 << k) int64_t numerator = ((1 << 30) + 1) << k; @@ -419,94 +419,3 @@ These features ensure that detection of overflow and other exceptional condition |=== -=== General Pseudocode Helpers - -This section contains general pseudocode utility functions used throughout the specification. - -The following functions provide basic arithmetic with asserts that values stay in the valid range supported by TOSA. - -[source,c++] ----- -acc_t apply_add<acc_t>(acc_t a, acc_t b) { - if (acc_t == float_t) return a + b; - int64_t c = (int64_t)a + (int64_t)b; - assert(c >= minimum<acc_t> && c <= maximum<acc_t>); - return (acc_t)c; -} - -acc_t apply_sub<acc_t>(acc_t a, acc_t b) { - if (acc_t == float_t) return a - b; - int64_t c = (int64_t)a - (int64_t)b; - assert(c >= minimum<acc_t> && c <= maximum<acc_t>); - return (acc_t)c; -} ----- - -The following functions are used in the pseudocode to take maximum, -minimum, clip values to a range, or count leading zeros. -[[count_leading_zeros]] -[source,c++] ----- -<type> apply_max<type>(<type> a, <type> b) { - if (a >= b) return a; else return b; -} - -<type> apply_min<type>(<type> a, <type> b) { - if (a < b) return a; else return b; -} - -<type> apply_clip<type>(<type> value, <type> min_val, <type> max_val) { - assert(min_val <= max_val); - value = apply_max(value, min_val); - value = apply_min(value, max_val); - return value; -} - -int32_t count_leading_zeros(int32_t a) { - int32_t acc = 32; - if (a != 0) { - uint32_t mask; - mask = 1 << (32 - 1); // width of int32_t - 1 - acc = 0; - while ((mask & a) == 0) { - mask = mask >> 1; - acc = acc + 1; - } - } - return acc; -} ----- - -The following definitions are used in pseudocode to do numeric conversions. - -[source,c++] ----- -int round_to_nearest_int(float_t f) - Converts the floating-point value to f, with rounding to the nearest integer value. - -float_t round_to_nearest_float(in_t f) - Converts the input value into floating-point, rounding to the nearest representable value. - The behavior for ties is implementation dependent. - -out_t sign_extend(in_t input) - Only valid for twos 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. ----- - -The following definition is used to flatten a list of lists into a single list - -[source,c++] ----- -in_t* flatten(in_t lists[]) { - in_t output = []; - for_each(list in lists) { - for_each(element in list) { - output.append(element); - } - } -} ----- |