aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Johnson <jeremy.johnson@arm.com>2022-04-26 10:24:06 +0100
committerEric Kunze <eric.kunze@arm.com>2022-05-03 15:22:48 +0000
commit1aa244c2496db4f54af50eeb11ccecf954cc4c68 (patch)
tree8c21ec9a52d409de1df25cac0a3b3c7d25da4618
parentcb6c6b33cc85d6c40d46b1ee78bcbd6a049017d5 (diff)
downloadspecification-1aa244c2496db4f54af50eeb11ccecf954cc4c68.tar.gz
Change from assignment to a check for output dims for tensor ops
Output dimensions should have been worked out correctly by the end of the compilation to TOSA Signed-off-by: Jeremy Johnson <jeremy.johnson@arm.com> Change-Id: I0193958d7d51bf1c6915a0953daa514f86516710
-rw-r--r--chapters/tensor_ops.adoc36
1 files changed, 17 insertions, 19 deletions
diff --git a/chapters/tensor_ops.adoc b/chapters/tensor_ops.adoc
index 7f39e81..ba40e0d 100644
--- a/chapters/tensor_ops.adoc
+++ b/chapters/tensor_ops.adoc
@@ -87,9 +87,6 @@ When calculating the average, only the number of valid input tensor values, but
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OH = idiv_check(IH + pad_top + pad_bottom - kernel_y, stride_y) + 1;
-OW = idiv_check(IW + pad_left + pad_right - kernel_x, stride_x) + 1;
ERROR_IF(in_out_t != int8_t && input_zp != 0); // Zero point only for int8_t
ERROR_IF(in_out_t != int8_t && output_zp != 0); // Zero point only for int8_t
ERROR_IF(kernel_y < 1 || kernel_x < 1); // kernel size must be >= 1
@@ -99,6 +96,8 @@ ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
// a divide-by-zero.
ERROR_IF(pad_right >= kernel_x || pad_left >= kernel_x);
ERROR_IF(pad_top >= kernel_y || pad_bottom >= kernel_y);
+ERROR_IF(OH != idiv_check(IH + pad_top + pad_bottom - kernel_y, stride_y) + 1);
+ERROR_IF(OW != idiv_check(IW + pad_left + pad_right - kernel_x, stride_x) + 1);
for_each(0 <= n < N, 0 <= oy < OH, 0 <= ox < OW, 0 <= c < C ) {
in_out_t output_val;
@@ -162,14 +161,14 @@ Performs a 2D convolution over the given tensor input, using the weight tensor.
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OH = idiv_check(IH-1 + pad_top + pad_bottom - (KH-1)*dilation_y, stride_y) + 1;
-OW = idiv_check(IW-1 + pad_left + pad_right - (KW-1)*dilation_x, stride_x) + 1;
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
ERROR_IF(weight_t != int8_t && weight_zp != 0);
ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
ERROR_IF(stride_y < 1 || stride_x < 1);
ERROR_IF(dilation_y < 1 || dilation_x < 1);
+ERROR_IF(OH != idiv_check(IH - 1 + pad_top + pad_bottom - (KH - 1) * dilation_y, stride_y) + 1);
+ERROR_IF(OW != idiv_check(IW - 1 + pad_left + pad_right - (KW - 1) * dilation_x, stride_x) + 1);
+
pad = flatten([0,0], pad, [0,0]);
for_each(0 <= n < N, 0 <= oy < OH, 0 <= ox < OW; 0 <= oc < OC) {
out_t acc = 0;
@@ -226,15 +225,15 @@ Performs a 3D convolution over the given input tensor.
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OD = idiv_check(ID-1 + pad_d0 + pad_d1 - (KD-1)*dilation_d, stride_d) + 1;
-OH = idiv_check(IH-1 + pad_top + pad_bottom - (KH-1)*dilation_y, stride_y) + 1;
-OW = idiv_check(IW-1 + pad_left + pad_right - (KW-1)*dilation_x, stride_x) + 1;
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
ERROR_IF(weight_t != int8_t && weight_zp != 0);
ERROR_IF(pad_d0 < 0 || pad_d1 < 0 || pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
ERROR_IF(stride_d < 1 || stride_y < 1 || stride_x < 1);
ERROR_IF(dilation_d < 1 || dilation_y < 1 || dilation_x < 1);
+ERROR_IF(OD != idiv_check(ID - 1 + pad_d0 + pad_d1 - (KD - 1) * dilation_d, stride_d) + 1);
+ERROR_IF(OH != idiv_check(IH - 1 + pad_top + pad_bottom - (KH - 1) * dilation_y, stride_y) + 1);
+ERROR_IF(OW != idiv_check(IW - 1 + pad_left + pad_right - (KW - 1) * dilation_x, stride_x) + 1);
+
pad = flatten([0,0], pad, [0,0]);
for_each(0 <= n < N, 0 <= od < OD, 0 <= oy < OH, 0 <= ox < OW; 0 <= oc < OC) {
out_t acc = 0;
@@ -294,14 +293,14 @@ Performs 2D convolutions separately over each channel of the given tensor input,
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OH = idiv_check(IH-1 + pad_top + pad_bottom - (KH-1)*dilation_y, stride_y) + 1;
-OW = idiv_check(IW-1 + pad_left + pad_right - (KW-1)*dilation_x, stride_x) + 1;
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only for int8_t
ERROR_IF(weight_t != int8_t && weight_zp != 0);
ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
ERROR_IF(stride_y < 1 || stride_x < 1);
ERROR_IF(dilation_y < 1 || dilation_x < 1);
+ERROR_IF(OH != idiv_check(IH - 1 + pad_top + pad_bottom - (KH - 1) * dilation_y, stride_y) + 1);
+ERROR_IF(OW != idiv_check(IW - 1 + pad_left + pad_right - (KW - 1) * dilation_x, stride_x) + 1);
+
pad = flatten([0,0], pad, [0,0]);
for_each(0 <= n<N, 0 <= oy < OH, 0 <= ox < OW; 0 <= c < C, 0 <= m < M) {
out_t acc = 0;
@@ -444,9 +443,6 @@ This performs a max pooling over the given input tensor. A sliding window of siz
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OH = idiv_check(IH + pad_top + pad_bottom - kernel_y, stride_y) + 1;
-OW = idiv_check(IW + pad_left + pad_right - kernel_x, stride_x) + 1;
ERROR_IF(kernel_y < 1 || kernel_x < 1); // kernel size must be >= 1
ERROR_IF(stride_y < 1 || stride_x < 1);
ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
@@ -454,6 +450,8 @@ ERROR_IF(pad_top < 0 || pad_bottom < 0 || pad_left < 0 || pad_right < 0);
// input values will be used.
ERROR_IF(pad_right >= kernel_x || pad_left >= kernel_x);
ERROR_IF(pad_top >= kernel_y || pad_bottom >= kernel_y);
+ERROR_IF(OH != idiv_check(IH + pad_top + pad_bottom - kernel_y, stride_y) + 1);
+ERROR_IF(OW != idiv_check(IW + pad_left + pad_right - kernel_x, stride_x) + 1);
for_each(0 <= n < N, 0 <= oy < H, 0 <= ox < W, 0 <= c < C ) {
in_out_t acc = minimum_value<in_out_t>;
@@ -505,14 +503,14 @@ Performs a 2D transposed convolution over the given tensor input, using the weig
[source,c++]
----
-// Derive output dimensions from input dimensions and padding
-OH = (IH-1)*stride_y - out_pad_top - out_pad_bottom + KH;
-OW = (IW-1)*stride_x - out_pad_left - out_pad_right + KW;
ERROR_IF(in_t != int8_t && input_zp != 0); // Zero point only allowed for int8_t
ERROR_IF(weight_t != int8_t && weight_zp != 0);
ERROR_IF(out_pad_top < 0 || out_pad_bottom < 0);
ERROR_IF(out_pad_left < 0 || out_pad_right < 0);
ERROR_IF(stride_y < 1 || stride_x < 1);
+ERROR_IF(OH != (IH - 1) * stride_y - out_pad_top - out_pad_bottom + KH);
+ERROR_IF(OW != (IW - 1) * stride_x - out_pad_left - out_pad_right + KW);
+
for_each(index in out_shape) {
tensor_write<out_t>(output, [N,OH,OW,OC], index, bias[index[3]])
}