From 1aa244c2496db4f54af50eeb11ccecf954cc4c68 Mon Sep 17 00:00:00 2001 From: Jeremy Johnson Date: Tue, 26 Apr 2022 10:24:06 +0100 Subject: 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 Change-Id: I0193958d7d51bf1c6915a0953daa514f86516710 --- chapters/tensor_ops.adoc | 36 +++++++++++++++++------------------- 1 file 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= 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; @@ -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(output, [N,OH,OW,OC], index, bias[index[3]]) } -- cgit v1.2.1