aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Kunze <eric.kunze@arm.com>2022-07-01 16:56:09 -0700
committerEric Kunze <eric.kunze@arm.com>2022-08-26 00:01:49 +0000
commitc1a978391b16dbbe634bc3338562066a75a6c678 (patch)
treef871bb95067bfc9c8df3278a3931eca2393c2c9f
parent4fb70ed713d49515040b041eff3639c36be17ac8 (diff)
downloadreference_model-c1a978391b16dbbe634bc3338562066a75a6c678.tar.gz
Align padding for transpose_conv2d to match spec
Increasing out pad values now leads to increasing pad. Reference model changes, and test generator changes to match specification definition Change-Id: I4f3ebfbca5048354fb15bedc7ab640ff28ed853a Signed-off-by: Eric Kunze <eric.kunze@arm.com> Signed-off-by: Jeremy Johnson <jeremy.johnson@arm.com>
-rw-r--r--reference_model/src/ops/tensor_ops.cc22
-rw-r--r--verif/generator/tosa_arg_gen.py22
-rw-r--r--verif/generator/tosa_error_if.py47
-rw-r--r--verif/generator/tosa_test_gen.py2
4 files changed, 62 insertions, 31 deletions
diff --git a/reference_model/src/ops/tensor_ops.cc b/reference_model/src/ops/tensor_ops.cc
index 03cb9fb..ef6dfa7 100644
--- a/reference_model/src/ops/tensor_ops.cc
+++ b/reference_model/src/ops/tensor_ops.cc
@@ -1498,14 +1498,7 @@ int OpTransposeConv2d<InDtype, WeightDtype>::checkTensorAttributes()
return 1;
}
- for (int32_t i : attribute->out_pad())
- {
- if (i < 0)
- {
- printNodeValidationError("OpTransposeConv2d: At least one pad is smaller than zero");
- return 1;
- }
- }
+
for (int32_t i : attribute->stride())
{
@@ -1540,8 +1533,13 @@ int OpTransposeConv2d<InDtype, WeightDtype>::checkTensorAttributes()
int32_t out_pad_left = attribute->out_pad()[2];
int32_t out_pad_right = attribute->out_pad()[3];
- int32_t H = (IH - 1) * stride_y - out_pad_top - out_pad_bottom + kernel_h;
- int32_t W = (IW - 1) * stride_x - out_pad_left - out_pad_right + kernel_w;
+ for (size_t i = 0; i < attribute->out_pad().size(); i++)
+ {
+ ERROR_IF(attribute->out_pad()[i] <= -(weight->getShape()[(i / 2) + 1]), "OpTransposeConv2d: At least one out_pad value is larger than kernel size");
+ }
+
+ int32_t H = (IH - 1) * stride_y + out_pad_top + out_pad_bottom + kernel_h;
+ int32_t W = (IW - 1) * stride_x + out_pad_left + out_pad_right + kernel_w;
if ((OH != H) || (OW != W))
{
@@ -1632,8 +1630,8 @@ int OpTransposeConv2d<InDtype, WeightDtype>::eval()
{
for (int iw = 0; iw < in_width; iw++)
{
- out_x_origin = iw * stride_w - out_pad_left;
- out_y_origin = ih * stride_h - out_pad_top;
+ out_x_origin = iw * stride_w + out_pad_left;
+ out_y_origin = ih * stride_h + out_pad_top;
for (int ic = 0; ic < in_channels; ic++)
{
for (int fh = 0; fh < f_height; fh++)
diff --git a/verif/generator/tosa_arg_gen.py b/verif/generator/tosa_arg_gen.py
index 2596bec..ef84762 100644
--- a/verif/generator/tosa_arg_gen.py
+++ b/verif/generator/tosa_arg_gen.py
@@ -1111,10 +1111,15 @@ class TosaArgGen:
# Generate comprehensive argument lists
# - except for named errors, which use specific invalid value(s)
- if error_name == ErrorIf.PadSmallerZero:
- p_vals = [testGen.rng.choice(range(-5, 0))]
+ smallest_padding_size = -min(filter_shape[1], filter_shape[2]) + 1
+ if error_name == ErrorIf.PadLargerEqualKernel:
+ max_filter_size = -max(filter_shape[1], filter_shape[2])
+ p_vals = [testGen.rng.choice(range(max_filter_size - 10, max_filter_size))]
else:
- p_vals = [x for x in range(0, testGen.args.max_conv_padding + 1)]
+ p_vals = [
+ x
+ for x in range(smallest_padding_size, testGen.args.max_conv_padding + 1)
+ ]
paddings = {x for x in itertools.product(*([p_vals] * 4))}
if error_name == ErrorIf.StrideSmallerOne:
# Can't use stride=0, as it is used to derive output shape, as a divisor
@@ -1128,7 +1133,12 @@ class TosaArgGen:
if max(ifm_shape) < 64:
bigPadding = 9
paddings.update(
- {x for x in itertools.product(*([[0, bigPadding]] * 4))}
+ {
+ x
+ for x in itertools.product(
+ *([[smallest_padding_size, bigPadding]] * 4)
+ )
+ }
)
bigStride = 8
strides.update({x for x in itertools.product(*([[1, bigStride]] * 2))})
@@ -1150,8 +1160,8 @@ class TosaArgGen:
for p in sorted(list(paddings)):
if n % sparsity == 0:
# Determine the output shape
- oh = (ifm_shape[1] - 1) * s[0] - p[0] - p[1] + filter_shape[1]
- ow = (ifm_shape[2] - 1) * s[1] - p[2] - p[3] + filter_shape[2]
+ oh = (ifm_shape[1] - 1) * s[0] + p[0] + p[1] + filter_shape[1]
+ ow = (ifm_shape[2] - 1) * s[1] + p[2] + p[3] + filter_shape[2]
os = [ifm_shape[0], oh, ow, filter_shape[0]]
arg_list.append(
(
diff --git a/verif/generator/tosa_error_if.py b/verif/generator/tosa_error_if.py
index e4e60b7..f9a00f9 100644
--- a/verif/generator/tosa_error_if.py
+++ b/verif/generator/tosa_error_if.py
@@ -1261,15 +1261,28 @@ class TosaErrorValidator:
if check:
pad = kwargs["pad"]
- kernel = kwargs["kernel"]
- if min(pad) > 0 and min(kernel) > 1:
+ op = kwargs["op"]
+ if op["op"] == Op.TRANSPOSE_CONV2D:
+ # transpose_conv2d
+ kernel = kwargs["weight_shape"][1:-1]
if (
- pad[0] >= kernel[0]
- or pad[1] >= kernel[0]
- or pad[2] >= kernel[1]
- or pad[3] >= kernel[1]
+ pad[0] <= -kernel[0]
+ or pad[1] <= -kernel[0]
+ or pad[2] <= -kernel[1]
+ or pad[3] <= -kernel[1]
):
error_result = True
+ else:
+ # pooling op
+ kernel = kwargs["kernel"]
+ if min(pad) > 0 and min(kernel) > 1:
+ if (
+ pad[0] >= kernel[0]
+ or pad[1] >= kernel[0]
+ or pad[2] >= kernel[1]
+ or pad[3] >= kernel[1]
+ ):
+ error_result = True
info_dict = {
"error_name": error_name,
@@ -1400,12 +1413,22 @@ class TosaErrorValidator:
return info_dict
@staticmethod
- def checkConvParams(weight_shape, stride, pad, dilation):
+ def checkConvParams(op, weight_shape, stride, pad, dilation):
+ if op == Op.TRANSPOSE_CONV2D:
+ pad_ok = (
+ pad[0] > -weight_shape[1]
+ and pad[1] > -weight_shape[1]
+ and pad[2] > -weight_shape[2]
+ and pad[3] > -weight_shape[2]
+ )
+ else:
+ pad_ok = min(pad) >= 0
+
return (
# Check kernel sizes
min(weight_shape[1:-1]) >= 1
and min(stride) >= 1
- and min(pad) >= 0
+ and pad_ok
and (dilation is None or min(dilation) >= 1)
)
@@ -1437,8 +1460,8 @@ class TosaErrorValidator:
if op["op"] == Op.TRANSPOSE_CONV2D:
dims_correct.append(
(input_shape[index + 1] - 1) * stride[index]
- - pad[pad_offset]
- - pad[pad_offset + 1]
+ + pad[pad_offset]
+ + pad[pad_offset + 1]
+ weight_shape[index + kernel_offset]
)
else:
@@ -1457,7 +1480,7 @@ class TosaErrorValidator:
# ensure parameters are valid
params_valid = TosaErrorValidator.checkConvParams(
- weight_shape, stride, pad, dilation
+ op["op"], weight_shape, stride, pad, dilation
)
if params_valid and output_shape[1:-1] != dims_correct:
@@ -1507,7 +1530,7 @@ class TosaErrorValidator:
# ensure parameters are valid
params_valid = TosaErrorValidator.checkConvParams(
- weight_shape, stride, pad, dilation
+ op["op"], weight_shape, stride, pad, dilation
)
if params_valid and max(remainders) > 0:
error_result = True
diff --git a/verif/generator/tosa_test_gen.py b/verif/generator/tosa_test_gen.py
index 53d38dd..ce3f81f 100644
--- a/verif/generator/tosa_test_gen.py
+++ b/verif/generator/tosa_test_gen.py
@@ -2605,7 +2605,7 @@ class TosaTestGen:
TosaErrorValidator.evWrongOutputList,
TosaErrorValidator.evInputZeroPointNotZero,
TosaErrorValidator.evWeightZeroPointNotZero,
- TosaErrorValidator.evPadSmallerZero,
+ TosaErrorValidator.evPadLargerEqualKernel,
TosaErrorValidator.evStrideSmallerOne,
TosaErrorValidator.evWrongRank,
TosaErrorValidator.evConvOutputShapeMismatch,