From c949f8a3a554728ccb6ce0ee0992fde382160cda Mon Sep 17 00:00:00 2001
From: Eric Kunze <eric.kunze@arm.com>
Date: Thu, 16 Sep 2021 14:51:26 -0700
Subject: Allow PAD operator to pad with non-zero

PAD now takes an additional attribute, with the padding value.
Will generally be zero, but other values are allowed.

tensor_read now requires the coordinates to be within the
given tensor, with unpredictable behavior occurring if an access
outside of the tensor occurs. Callers of tensor_read are expected
to check the coordinates and take the appropriate action. The
primary impact of this is to move the responsibility for padding to
each operator. In practice, this is expected to not be a functional
change, but a cleanup to make the behavior more clear.

Signed-off-by: Eric Kunze <eric.kunze@arm.com>
Change-Id: I4f21ca9a13d82d422bbd66c400f23aa9a0bd2aa0
---
 chapters/data_layout.adoc | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

(limited to 'chapters/data_layout.adoc')

diff --git a/chapters/data_layout.adoc b/chapters/data_layout.adoc
index 834030c..4368474 100644
--- a/chapters/data_layout.adoc
+++ b/chapters/data_layout.adoc
@@ -57,7 +57,8 @@ for_each(index1 in shape) {
 
 ==== PAD
 
-Zero-pads a tensor along borders of each dimension.
+Pads a tensor along the borders of each dimension with a supplied value.
+Returns a new tensor with the padding included.
 
 *Arguments:*
 
@@ -66,6 +67,7 @@ Zero-pads a tensor along borders of each dimension.
 
 |Input|in_t*|input1|shape1|Input tensor
 |Attribute|int|padding|[rank(input1),2]|Amount of padding to be done
+|Attribute|in_t|pad_const|-|Constant value to be used as padding
 |Output|in_t*|output|shape|Output tensor of same type as the input tensor
 |===
 
@@ -82,16 +84,20 @@ Zero-pads a tensor along borders of each dimension.
 [source,c++]
 ----
 ERROR_IF(in_t != int8_t  && input1_zp != 0); // Zero point only allowed for int8_t
-// Pad values must be >= 0.
-for_each(value in padding) {
-    ERROR_IF(value < 0);
+// Padding sizes must be >= 0.
+for_each(pad_size in padding) {
+    ERROR_IF(pad_size < 0);
 }
 for_each(index in shape) {
     index1 = index;
+    bool_t is_pad = false;
     for(i = 0; i < rank(shape); i++) {
         index1[i] = index1[i] - padding[i,0];
+        if (index1[i] < 0 || index[i] >= length(shape[i])) {
+            is_pad = true;
+        }
     }
-    acc_t value = tensor_read<in_t>(input1, shape1, index1, input1_zp, padding);
+    acc_t value = is_pad ? pad_const : tensor_read<in_t>(input1, shape1, index1, input1_zp);
     tensor_write<in_t>(output, shape, index, value + input1_zp);
 }
 ----
-- 
cgit v1.2.1

