diff options
author | Eric Kunze <eric.kunze@arm.com> | 2024-01-12 17:18:42 -0800 |
---|---|---|
committer | Eric Kunze <eric.kunze@arm.com> | 2024-01-31 06:00:03 +0000 |
commit | 526f6c7b5d20e967109ca92c8fc54c26c0438135 (patch) | |
tree | 7186a2dec336db8389cdf0cf8bacd60f9da4cf64 /pseudocode | |
parent | 7e5d187c612fcc715ea3f7f0c900eb13af75a660 (diff) | |
download | specification-526f6c7b5d20e967109ca92c8fc54c26c0438135.tar.gz |
Add section of shape operatorsv0.90.0
Rework of the shape operations. Shape operations are now done in shape specific
operators rather than being based on type.
shape_t is reworked to a list of size_t values.
Signed-off-by: Eric Kunze <eric.kunze@arm.com>
Change-Id: I2fca0728f9caa6a6fc34a8ce9e389bb581eea959
Diffstat (limited to 'pseudocode')
35 files changed, 176 insertions, 125 deletions
diff --git a/pseudocode/operators/ADD.tosac b/pseudocode/operators/ADD.tosac index 61db3f6..82379e9 100644 --- a/pseudocode/operators/ADD.tosac +++ b/pseudocode/operators/ADD.tosac @@ -7,20 +7,12 @@ // copies and copies may only be made to the extent permitted // by a licensing agreement from ARM Limited. -if (in_out_t == shape_t) { - ERROR_IF(rank(shape) != 0 || rank(shape1) != 0 || rank(shape2) != 0); - shape_t value1 = tensor_read<shape_t>(input1, [], []); - shape_t value2 = tensor_read<shape_t>(input2, [], []); - shape_t result = apply_add_s<shape_t>(value1, value2); - tensor_write<shape_t>(output, [], [], result); -} else { - ERROR_IF(shape != broadcast_shape(shape1, shape2)); - for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); - in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); - in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); - in_out_t result = apply_add_s<in_out_t>(value1, value2); - tensor_write<in_out_t>(output, shape, index, result); - } +ERROR_IF(shape != broadcast_shape(shape1, shape2)); +for_each(index in shape) { + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); + in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); + in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); + in_out_t result = apply_add_s<in_out_t>(value1, value2); + tensor_write<in_out_t>(output, shape, index, result); } diff --git a/pseudocode/operators/ADD_SHAPE.tosac b/pseudocode/operators/ADD_SHAPE.tosac new file mode 100644 index 0000000..edb7c20 --- /dev/null +++ b/pseudocode/operators/ADD_SHAPE.tosac @@ -0,0 +1,14 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +ERROR_IF(length(input1) != length(input2)); + +for(int32_t index=0; index < rank(input1); index++) { + output[index] = apply_add_s<size_t>(input1[index], input2[index]); +} diff --git a/pseudocode/operators/ARGMAX.tosac b/pseudocode/operators/ARGMAX.tosac index 982957a..73b74a0 100644 --- a/pseudocode/operators/ARGMAX.tosac +++ b/pseudocode/operators/ARGMAX.tosac @@ -24,14 +24,14 @@ for_each(left_index in left_shape) { in_t max_value = minimum_s<in_t>; out_t max_index = 0; for (i = 0; i < shape1[axis]; i++) { - dim_t index = flatten(left_index, [i], right_index); + shape_t index = flatten(left_index, [i], right_index); in_t value = tensor_read<in_t>(input, shape1, index); if (apply_max_s<in_t>(value, max_value) != max_value) { max_value = value; max_index = i; } } - dim_t index = flatten(left_index, right_index); + shape_t index = flatten(left_index, right_index); tensor_write<out_t>(output, shape, index, max_index); } } diff --git a/pseudocode/operators/ARITHMETIC_RIGHT_SHIFT.tosac b/pseudocode/operators/ARITHMETIC_RIGHT_SHIFT.tosac index 7ed4886..dd07fc5 100644 --- a/pseudocode/operators/ARITHMETIC_RIGHT_SHIFT.tosac +++ b/pseudocode/operators/ARITHMETIC_RIGHT_SHIFT.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); diff --git a/pseudocode/operators/BITWISE_AND.tosac b/pseudocode/operators/BITWISE_AND.tosac index 5efe3ee..f3b647b 100644 --- a/pseudocode/operators/BITWISE_AND.tosac +++ b/pseudocode/operators/BITWISE_AND.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 & value2; diff --git a/pseudocode/operators/BITWISE_OR.tosac b/pseudocode/operators/BITWISE_OR.tosac index b2b7fc6..10afb19 100644 --- a/pseudocode/operators/BITWISE_OR.tosac +++ b/pseudocode/operators/BITWISE_OR.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 | value2; diff --git a/pseudocode/operators/BITWISE_XOR.tosac b/pseudocode/operators/BITWISE_XOR.tosac index 98f0d2c..45e8a0a 100644 --- a/pseudocode/operators/BITWISE_XOR.tosac +++ b/pseudocode/operators/BITWISE_XOR.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 ^ value2; diff --git a/pseudocode/operators/CONCAT.tosac b/pseudocode/operators/CONCAT.tosac index f9329af..ca26f26 100644 --- a/pseudocode/operators/CONCAT.tosac +++ b/pseudocode/operators/CONCAT.tosac @@ -9,7 +9,6 @@ ERROR_IF(axis < 0 || axis >= max(1,rank(shapes1[0]))); ERROR_IF(shape[axis] != sum(shape_dim(shapes1[k], axis) for all k)) -ERROR_IF(in_out_t == shape_t && rank(shape) > 1); // The following checks ensure all inputs are compatible for concatenation for_each(input_shape in shapes1) { ERROR_IF(rank(input_shape) != rank(shapes1[0])); @@ -18,7 +17,7 @@ for_each(input_shape in shapes1) { } } for_each(index1 in shape) { - dim_t index2 = index1; + shape_t index2 = index1; for (tensor t = 0; t < length(input1); t++) { // Continue to concatenate along axis from each tensor // For each output location, we are looking for the @@ -30,3 +29,4 @@ for_each(index1 in shape) { index2[axis] = index2[axis] - shape_dim(shapes1[t], axis); } } + diff --git a/pseudocode/operators/CONCAT_SHAPE.tosac b/pseudocode/operators/CONCAT_SHAPE.tosac new file mode 100644 index 0000000..4b6def6 --- /dev/null +++ b/pseudocode/operators/CONCAT_SHAPE.tosac @@ -0,0 +1,18 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +ERROR_IF(length(output) != sum(length(input1[k]) for all k)); + +size_t index = 0; +for (int32_t i=0; i < length(input1); i++) { + for (int32_t j=0; j < length(input1[i]); j++) { + output[index] = input1[i][j]; + index++; + } +} diff --git a/pseudocode/operators/CONST_SHAPE.tosac b/pseudocode/operators/CONST_SHAPE.tosac new file mode 100644 index 0000000..d14ead2 --- /dev/null +++ b/pseudocode/operators/CONST_SHAPE.tosac @@ -0,0 +1,10 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +output = values; diff --git a/pseudocode/operators/DIM.tosac b/pseudocode/operators/DIM.tosac index 7131173..2105c62 100644 --- a/pseudocode/operators/DIM.tosac +++ b/pseudocode/operators/DIM.tosac @@ -8,4 +8,4 @@ // by a licensing agreement from ARM Limited. ERROR_IF(axis >= rank(shape)); -tensor_write<shape_t>(output, [], [], shape_dim(shape, axis)); +output[0] = shape_dim(shape, axis); diff --git a/pseudocode/operators/DIV_SHAPE.tosac b/pseudocode/operators/DIV_SHAPE.tosac new file mode 100644 index 0000000..3f73c24 --- /dev/null +++ b/pseudocode/operators/DIV_SHAPE.tosac @@ -0,0 +1,14 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +ERROR_IF(length(input1) != length(input2)); + +for(int32_t index=0; index < rank(input1); index++) { + output[index] = apply_intdiv_s<size_t>(input1[index], input2[index]); +} diff --git a/pseudocode/operators/EQUAL.tosac b/pseudocode/operators/EQUAL.tosac index 3445e27..bcbce33 100644 --- a/pseudocode/operators/EQUAL.tosac +++ b/pseudocode/operators/EQUAL.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_t value1 = tensor_read<in_t>(input1, shape1, index1); in_t value2 = tensor_read<in_t>(input2, shape2, index2); out_t result; diff --git a/pseudocode/operators/GREATER.tosac b/pseudocode/operators/GREATER.tosac index 3155f23..6874bd0 100644 --- a/pseudocode/operators/GREATER.tosac +++ b/pseudocode/operators/GREATER.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_t value1 = tensor_read<in_t>(input1, shape1, index1); in_t value2 = tensor_read<in_t>(input2, shape2, index2); out_t result; diff --git a/pseudocode/operators/GREATER_EQUAL.tosac b/pseudocode/operators/GREATER_EQUAL.tosac index 2f43d40..2a63077 100644 --- a/pseudocode/operators/GREATER_EQUAL.tosac +++ b/pseudocode/operators/GREATER_EQUAL.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_t value1 = tensor_read<in_t>(input1, shape1, index1); in_t value2 = tensor_read<in_t>(input2, shape2, index2); out_t result; diff --git a/pseudocode/operators/INTDIV.tosac b/pseudocode/operators/INTDIV.tosac index b6d46cc..bf3126b 100644 --- a/pseudocode/operators/INTDIV.tosac +++ b/pseudocode/operators/INTDIV.tosac @@ -7,25 +7,16 @@ // copies and copies may only be made to the extent permitted // by a licensing agreement from ARM Limited. -if (in_out_t == shape_t) { - ERROR_IF(rank(shape) != 0 || rank(shape1) != 0 || rank(shape2) != 0); - shape_t value1 = tensor_read<shape_t>(input1, [], []); - shape_t value2 = tensor_read<shape_t>(input2, [], []); +ERROR_IF(shape != broadcast_shape(shape1, shape2)); +for_each(index in shape) { + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); + in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); + in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); REQUIRE(value2 != 0); - shape_t result = value1 / value2; - tensor_write<shape_t>(output, [], [], result); -} else { - ERROR_IF(shape != broadcast_shape(shape1, shape2)); - for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); - in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); - in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); - REQUIRE(value2 != 0); - // This catches the case where we divide minimum<in_out_t> by -1 - // which is not representable in two's complement - REQUIRE(static_cast<int64_t>(value1) / static_cast<int64_t>(value2) <= maximum_s<in_out_t>); - in_out_t result = apply_intdiv_s<in_out_t>(value1, value2); - tensor_write<in_out_t>(output, shape, index, result); - } + // This catches the case where we divide minimum<in_out_t> by -1 + // which is not representable in two's complement + REQUIRE(static_cast<int64_t>(value1) / static_cast<int64_t>(value2) <= maximum_s<in_out_t>); + in_out_t result = apply_intdiv_s<in_out_t>(value1, value2); + tensor_write<in_out_t>(output, shape, index, result); } diff --git a/pseudocode/operators/LOGICAL_AND.tosac b/pseudocode/operators/LOGICAL_AND.tosac index ff03804..23bda8d 100644 --- a/pseudocode/operators/LOGICAL_AND.tosac +++ b/pseudocode/operators/LOGICAL_AND.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 && value2; diff --git a/pseudocode/operators/LOGICAL_LEFT_SHIFT.tosac b/pseudocode/operators/LOGICAL_LEFT_SHIFT.tosac index 4057163..c8b2862 100644 --- a/pseudocode/operators/LOGICAL_LEFT_SHIFT.tosac +++ b/pseudocode/operators/LOGICAL_LEFT_SHIFT.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); REQUIRE(0 <= value2 && value2 <= 31); diff --git a/pseudocode/operators/LOGICAL_OR.tosac b/pseudocode/operators/LOGICAL_OR.tosac index 4e3aa9e..de09fed 100644 --- a/pseudocode/operators/LOGICAL_OR.tosac +++ b/pseudocode/operators/LOGICAL_OR.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 || value2; diff --git a/pseudocode/operators/LOGICAL_RIGHT_SHIFT.tosac b/pseudocode/operators/LOGICAL_RIGHT_SHIFT.tosac index 5e80211..2896b0f 100644 --- a/pseudocode/operators/LOGICAL_RIGHT_SHIFT.tosac +++ b/pseudocode/operators/LOGICAL_RIGHT_SHIFT.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); REQUIRE(0 <= static_cast<int32_t>(value2) && static_cast<int32_t>(value2) <= 31); diff --git a/pseudocode/operators/LOGICAL_XOR.tosac b/pseudocode/operators/LOGICAL_XOR.tosac index fbb485b..08fa6bd 100644 --- a/pseudocode/operators/LOGICAL_XOR.tosac +++ b/pseudocode/operators/LOGICAL_XOR.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = value1 != value2; diff --git a/pseudocode/operators/MAXIMUM.tosac b/pseudocode/operators/MAXIMUM.tosac index 0f4f3b7..c34e2ba 100644 --- a/pseudocode/operators/MAXIMUM.tosac +++ b/pseudocode/operators/MAXIMUM.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = apply_max_s<in_out_t>(value1, value2); diff --git a/pseudocode/operators/MINIMUM.tosac b/pseudocode/operators/MINIMUM.tosac index fa47b03..659cba6 100644 --- a/pseudocode/operators/MINIMUM.tosac +++ b/pseudocode/operators/MINIMUM.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = apply_min_s(value1, value2); diff --git a/pseudocode/operators/MUL.tosac b/pseudocode/operators/MUL.tosac index 078525e..5cc9f80 100644 --- a/pseudocode/operators/MUL.tosac +++ b/pseudocode/operators/MUL.tosac @@ -7,31 +7,23 @@ // copies and copies may only be made to the extent permitted // by a licensing agreement from ARM Limited. -if (in_out_t == shape_t) { - ERROR_IF(rank(shape) != 0 || rank(shape1) != 0 || rank(shape2) != 0); - shape_t value1 = tensor_read<shape_t>(input1, [], []); - shape_t value2 = tensor_read<shape_t>(input2, [], []); - shape_t result = value1 * value2; - tensor_write<shape_t>(output, [], [], result); -} else { - REQUIRE(0 <= shift && shift <= 63); - REQUIRE(in_t == int32_t || shift == 0); - ERROR_IF(shape != broadcast_shape(shape1, shape2)); - for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); - in_t value1 = tensor_read<in_t>(input1, shape1, index1); - in_t value2 = tensor_read<in_t>(input2, shape2, index2); - out_t result; - if (in_t == i32_t && shift > 0) { - int64_t product = sign_extend<int64_t>(value1) * sign_extend<int64_t>(value2); - int64_t round = static_cast<int64_t>(1) << (shift - 1); - product = (product + round) >> shift; - REQUIRE(product >= minimum_s<i32_t> && product <= maximum_s<i32_t>) - result = product; - } else { - result = apply_mul_s(value1, value2); // low 32-bits of result for i32_t - } - tensor_write<out_t>(output, shape, index, result); +REQUIRE(0 <= shift && shift <= 63); +REQUIRE(in_t == int32_t || shift == 0); +ERROR_IF(shape != broadcast_shape(shape1, shape2)); +for_each(index in shape) { + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); + in_t value1 = tensor_read<in_t>(input1, shape1, index1); + in_t value2 = tensor_read<in_t>(input2, shape2, index2); + out_t result; + if (in_t == i32_t && shift > 0) { + int64_t product = sign_extend<int64_t>(value1) * sign_extend<int64_t>(value2); + int64_t round = static_cast<int64_t>(1) << (shift - 1); + product = (product + round) >> shift; + REQUIRE(product >= minimum_s<i32_t> && product <= maximum_s<i32_t>) + result = product; + } else { + result = apply_mul_s(value1, value2); // low 32-bits of result for i32_t } + tensor_write<out_t>(output, shape, index, result); } diff --git a/pseudocode/operators/MUL_SHAPE.tosac b/pseudocode/operators/MUL_SHAPE.tosac new file mode 100644 index 0000000..f52f416 --- /dev/null +++ b/pseudocode/operators/MUL_SHAPE.tosac @@ -0,0 +1,14 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +ERROR_IF(length(input1) != length(input2)); + +for(int32_t index=0; index < rank(input1); index++) { + output[index] = apply_mul_s<size_t>(input1[index], input2[index]); +} diff --git a/pseudocode/operators/PAD.tosac b/pseudocode/operators/PAD.tosac index 4adf114..45ef674 100644 --- a/pseudocode/operators/PAD.tosac +++ b/pseudocode/operators/PAD.tosac @@ -10,14 +10,14 @@ // Check output shape matches the padded input shape ERROR_IF(rank(shape) != rank(shape1)); for (i = 0; i < rank(shape); i++) { - ERROR_IF(padding[i,0] < 0 || padding[i,1] < 0); - ERROR_IF(shape[i] != padding[i, 0] + shape1[i] + padding[i, 1]); + ERROR_IF(padding[i * 2] < 0 || padding[(i * 2) + 1] < 0); + ERROR_IF(shape[i] != padding[i * 2] + shape1[i] + padding[(i * 2) + 1]); } for_each(index in shape) { - dim_t index1 = index; + shape_t index1 = index; bool_t is_pad = false; for(i = 0; i < rank(shape); i++) { - index1[i] = index1[i] - padding[i,0]; + index1[i] = index1[i] - padding[i * 2]; if (index1[i] < 0 || index[i] >= length(shape[i])) { is_pad = true; } diff --git a/pseudocode/operators/POW.tosac b/pseudocode/operators/POW.tosac index 6ecc8e6..482ea18 100644 --- a/pseudocode/operators/POW.tosac +++ b/pseudocode/operators/POW.tosac @@ -9,8 +9,8 @@ ERROR_IF(shape != broadcast_shape(shape1, shape2)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t result = apply_pow<in_out_t>(value1, value2); diff --git a/pseudocode/operators/RESHAPE.tosac b/pseudocode/operators/RESHAPE.tosac index 41439c3..af1be87 100644 --- a/pseudocode/operators/RESHAPE.tosac +++ b/pseudocode/operators/RESHAPE.tosac @@ -13,7 +13,7 @@ for_each(index in shape) { // Calculate flattened index for the output location (index) size_t offset = tensor_index_to_offset(shape, index); // Now convert to the location in the input - dim_t tmp_index = tensor_offset_to_index(shape1, offset); + shape_t tmp_index = tensor_offset_to_index(shape1, offset); // Now read/write the value in_out_t val = tensor_read<in_out_t>(input1, shape1, tmp_index); diff --git a/pseudocode/operators/REVERSE.tosac b/pseudocode/operators/REVERSE.tosac index 63830d2..4a39cf2 100644 --- a/pseudocode/operators/REVERSE.tosac +++ b/pseudocode/operators/REVERSE.tosac @@ -9,7 +9,7 @@ ERROR_IF(axis < 0 || axis >= rank(shape)); for_each(index in shape) { - dim_t tmp_index = index; + shape_t tmp_index = index; tmp_index[axis] = shape[axis] - 1 - index[axis]; in_out_t value = tensor_read<in_out_t>(input, shape, tmp_index); tensor_write<in_out_t>(output, shape, index, value); diff --git a/pseudocode/operators/SELECT.tosac b/pseudocode/operators/SELECT.tosac index fe8d760..c55ad8e 100644 --- a/pseudocode/operators/SELECT.tosac +++ b/pseudocode/operators/SELECT.tosac @@ -9,9 +9,9 @@ ERROR_IF(shape != broadcast_shape(broadcast_shape(shape1, shape2), shape3)); for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); - dim_t index3 = apply_broadcast(shape, shape3, index); + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); + shape_t index3 = apply_broadcast(shape, shape3, index); bool_t value1 = tensor_read<bool_t>(input1, shape1, index1); in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); in_out_t value3 = tensor_read<in_out_t>(input3, shape3, index3); diff --git a/pseudocode/operators/SLICE.tosac b/pseudocode/operators/SLICE.tosac index 0ae0214..b6f70c5 100644 --- a/pseudocode/operators/SLICE.tosac +++ b/pseudocode/operators/SLICE.tosac @@ -19,7 +19,7 @@ for_each(index in rank(shape1)) { } for_each(index in shape) { - dim_t tmp_index = index; + shape_t tmp_index = index; for(i = 0; i < rank(shape); i++) { tmp_index[i] = index[i] + start[i]; } diff --git a/pseudocode/operators/SUB.tosac b/pseudocode/operators/SUB.tosac index ac88b76..1ecc6e0 100644 --- a/pseudocode/operators/SUB.tosac +++ b/pseudocode/operators/SUB.tosac @@ -7,20 +7,12 @@ // copies and copies may only be made to the extent permitted // by a licensing agreement from ARM Limited. -if (in_out_t == shape_t) { - ERROR_IF(rank(shape) != 0 || rank(shape1) != 0 || rank(shape2) != 0); - shape_t value1 = tensor_read<shape_t>(input1, [], []); - shape_t value2 = tensor_read<shape_t>(input2, [], []); - shape_t result = apply_sub<shape_t>(value1, value2); - tensor_write<shape_t>(output, [], [], result); -} else { - ERROR_IF(shape != broadcast_shape(shape1, shape2)); - for_each(index in shape) { - dim_t index1 = apply_broadcast(shape, shape1, index); - dim_t index2 = apply_broadcast(shape, shape2, index); - in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); - in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); - in_out_t result = apply_sub_s<in_out_t>(value1, value2); - tensor_write<in_out_t>(output, shape, index, result); - } +ERROR_IF(shape != broadcast_shape(shape1, shape2)); +for_each(index in shape) { + shape_t index1 = apply_broadcast(shape, shape1, index); + shape_t index2 = apply_broadcast(shape, shape2, index); + in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index1); + in_out_t value2 = tensor_read<in_out_t>(input2, shape2, index2); + in_out_t result = apply_sub_s<in_out_t>(value1, value2); + tensor_write<in_out_t>(output, shape, index, result); } diff --git a/pseudocode/operators/SUB_SHAPE.tosac b/pseudocode/operators/SUB_SHAPE.tosac new file mode 100644 index 0000000..eff2687 --- /dev/null +++ b/pseudocode/operators/SUB_SHAPE.tosac @@ -0,0 +1,14 @@ +// +// This confidential and proprietary software may be used only as +// authorised by a licensing agreement from ARM Limited +// (C) COPYRIGHT 2024 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 +// by a licensing agreement from ARM Limited. + +ERROR_IF(length(input1) != length(input2)); + +for(int32_t index=0; index < rank(input1); index++) { + output[index] = apply_sub_s<size_t>(input1[index], input2[index]); +} diff --git a/pseudocode/operators/TILE.tosac b/pseudocode/operators/TILE.tosac index d053b8f..be1cfee 100644 --- a/pseudocode/operators/TILE.tosac +++ b/pseudocode/operators/TILE.tosac @@ -10,7 +10,7 @@ ERROR_IF(rank(shape1) != rank(shape)); for_each(index in shape) { - dim_t tmp_index = index; + shape_t tmp_index = index; for(i = 0; i < rank(shape); i++) { ERROR_IF(shape1[i] * multiples[i] != shape[i]); tmp_index[i] = index[i] % shape1[i]; diff --git a/pseudocode/operators/TRANSPOSE.tosac b/pseudocode/operators/TRANSPOSE.tosac index e75db79..3981f54 100644 --- a/pseudocode/operators/TRANSPOSE.tosac +++ b/pseudocode/operators/TRANSPOSE.tosac @@ -26,7 +26,7 @@ for(i = 0; i < rank(shape); i++) { } for_each(index in shape) { - dim_t tmp_index = index; + shape_t tmp_index = index; for(i = 0; i < rank(shape); i++) { tmp_index[perms[i]] = index[i]; } |