From 175355a236f54d5883963695f05f5387527a1d39 Mon Sep 17 00:00:00 2001 From: Leandro Nunes Date: Fri, 25 Nov 2022 16:32:43 +0000 Subject: [PATCH 1/3] [ACL] Enable int8 data type in pooling operators This enables int8 data type to be used in Compute Library for the Arm(r) Architecture (ACL) BYOC integration. This PR covers: - nn.max_pool2d - nn.avg_pool2d - nn.l2_pool2d - nn.global_avg_pool2d - nn.global_max_pool2d Change-Id: If74f6de5f302b7fdd8d920c2d0b3633d66520637 --- .../tvm/relay/op/contrib/arm_compute_lib.py | 6 +- .../test_arm_compute_lib/test_pooling.py | 416 ++++++++++-------- 2 files changed, 230 insertions(+), 192 deletions(-) diff --git a/python/tvm/relay/op/contrib/arm_compute_lib.py b/python/tvm/relay/op/contrib/arm_compute_lib.py index d63cd8c83a93..98f248547232 100644 --- a/python/tvm/relay/op/contrib/arm_compute_lib.py +++ b/python/tvm/relay/op/contrib/arm_compute_lib.py @@ -267,7 +267,7 @@ def check_qnn_dense(extract): def check_avg_pool2d(extract): """Check average pool2d pattern is supported by ACL.""" - if extract.attrs.dtype != "uint8": + if extract.attrs.dtype not in ("uint8", "int8"): return False pool = extract.args[0] if pool.args[0].attrs.dtype != "int32": @@ -439,7 +439,7 @@ def max_pool2d(expr): if attrs.layout != "NHWC": return False typ = args[0].checked_type - if typ.dtype not in ["float32", "uint8"]: + if typ.dtype not in ["float32", "uint8", "int8"]: return False return check_dilation(attrs) @@ -467,7 +467,7 @@ def global_max_pool2d(expr): """Check if the external ACL codegen for gloval_maxpool2d should be used.""" attrs, args = expr.attrs, expr.args typ = args[0].checked_type - if typ.dtype not in ["float32", "uint8"]: + if typ.dtype not in ["float32", "uint8", "int8"]: return False if attrs.layout != "NHWC": return False diff --git a/tests/python/contrib/test_arm_compute_lib/test_pooling.py b/tests/python/contrib/test_arm_compute_lib/test_pooling.py index b174f9a78866..9f4430bf81d2 100644 --- a/tests/python/contrib/test_arm_compute_lib/test_pooling.py +++ b/tests/python/contrib/test_arm_compute_lib/test_pooling.py @@ -15,8 +15,9 @@ # specific language governing permissions and limitations # under the License. """Arm Compute Library integration pooling tests.""" - import numpy as np +import pytest + import tvm from tvm import relay, testing @@ -46,6 +47,7 @@ def _get_pooling_model( if len(padding) == 2: padding = (padding[0], padding[1], padding[0], padding[1]) out = relay.var(next(var_names), shape=shape, dtype=dtype) + qnn_dtypes = ("uint8", "int8") if typef == "nn.max_pool2d": out = relay.nn.max_pool2d( @@ -58,7 +60,7 @@ def _get_pooling_model( layout="NHWC", ) elif typef == "nn.avg_pool2d": - if dtype == "uint8": + if dtype in qnn_dtypes: out = relay.cast(out, "int32") out = relay.nn.avg_pool2d( out, @@ -70,8 +72,8 @@ def _get_pooling_model( count_include_pad=count_include_pad, layout="NHWC", ) - if dtype == "uint8": - out = relay.cast(out, "uint8") + if dtype in qnn_dtypes: + out = relay.cast(out, dtype) elif typef == "nn.l2_pool2d": out = relay.power(out, relay.const(2.0)) out = relay.nn.avg_pool2d( @@ -93,15 +95,16 @@ def _get_pooling_model( def _get_global_pooling_model(shape, dtype, typef, var_names): """Return a model and any parameters it may have.""" out = relay.var(next(var_names), shape=shape, dtype=dtype) + qnn_dtypes = ("uint8", "int8") if typef == "nn.global_max_pool2d": out = relay.nn.global_max_pool2d(out, layout="NHWC") elif typef == "nn.global_avg_pool2d": - if dtype == "uint8": + if dtype in qnn_dtypes: out = relay.cast(out, "int32") out = relay.nn.global_avg_pool2d(out, layout="NHWC") - if dtype == "uint8": - out = relay.cast(out, "uint8") + if dtype in qnn_dtypes: + out = relay.cast(out, dtype) else: raise ValueError("Function not supported") @@ -160,7 +163,59 @@ def _get_expected_global_pooling_codegen(shape, dtype, typef): return [input, node] -def test_pooling(): +def _get_low_high_atol_rtol(dtype): + if dtype == "float32": + low, high, atol, rtol = (-127, 128, 0.001, 0.001) + elif dtype == "uint8": + low, high, atol, rtol = (0, 255, 1, 0) + elif dtype == "int8": + low, high, atol, rtol = (-127, 128, 1, 0) + else: + pytest.fail(f"dtype not expected: {dtype}") + + return low, high, atol, rtol + + +# fmt: off +@pytest.mark.parametrize( + "typef,dtype,size,stride,dilation,pad,ceil_mode,count_include_pad,input_shape,expected_ops", + [ + ("nn.max_pool2d", "float32", (3, 3), (2, 2), (1, 1), (0, 0), False, False, (27, 27, 512), (0, 1),), + ("nn.max_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "float32", (3, 3), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),), + ("nn.max_pool2d", "int8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "int8", (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "int8", (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),), + ("nn.avg_pool2d", "float32", (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "float32", (3, 3), (2, 2), (3, 2), (0, 1), True, False, (15, 15, 16), (1, 0),), + # 20.05: "exclude_padding equal false is not supported for AVG Pooling with padding on quantized types" + # ["nn.avg_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), False, True, (16, 16, 16)], + ("nn.avg_pool2d", "uint8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "int8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 1), True, False, (16, 16, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (3, 3), (2, 2), (1, 1), (0, 0), False, False, (16, 16, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (2, 2), (2, 2), (1, 1), (1, 1), False, True, (15, 15, 16), (0, 1),), + + ], +) +# fmt: on +def test_pooling( + typef, + dtype, + size, + stride, + dilation, + pad, + ceil_mode, + count_include_pad, + input_shape, + expected_ops, +): Device.load("test_config.json") if skip_runtime_test(): @@ -169,91 +224,79 @@ def test_pooling(): device = Device() np.random.seed(0) - fp32_dtype = ("float32", -127, 128, 0.001, 0.001) - uint8_dtype = ("uint8", 0, 255, 1, 0) - # fmt: off - trials = [ - ["nn.max_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (0, 0), False, False, (27, 27, 512), (0, 1),], - ["nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),], - ["nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),], - ["nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", fp32_dtype, (3, 3), (2, 2), (3, 2), (0, 1), True, False, (15, 15, 16), (1, 0),], - # 20.05: "exclude_padding equal false is not supported for AVG Pooling with padding on quantized types" - # ["nn.avg_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), False, True, (16, 16, 16)], - ["nn.avg_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), True, False, (16, 16, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (0, 0), False, False, (16, 16, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, True, (15, 15, 16), (0, 1),], - ] - # fmt: on - for ( + low, high, atol, rtol = _get_low_high_atol_rtol(dtype) + tvm_ops, acl_partitions = expected_ops + + shape = (1, *input_shape) + outputs = [] + inputs = { + "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), + } + + func = _get_pooling_model( + shape, + dtype, typef, - (dtype, low, high, atol, rtol), size, stride, dilation, pad, ceil_mode, count_include_pad, - input_shape, - (tvm_ops, acl_partitions), - ) in trials: - shape = (1, *input_shape) - outputs = [] - inputs = { - "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), - } - - func = _get_pooling_model( - shape, - dtype, - typef, - size, - stride, - dilation, - pad, - ceil_mode, - count_include_pad, - iter(inputs), + iter(inputs), + ) + + config = { + "size": size, + "stride": stride, + "shape": shape, + "pooling type": typef, + "dtype": dtype, + "padding": pad, + "dilation": dilation, + "ceil_mode": ceil_mode, + "count_include_pad": count_include_pad, + "inputs": inputs, + } + verify_saturation = True if dtype == "uint8" else False + for acl in [False, True]: + outputs.append( + build_and_run( + func, + inputs, + 1, + None, + device, + enable_acl=acl, + tvm_ops=tvm_ops, + acl_partitions=acl_partitions, + config=config, + )[0] ) - config = { - "size": size, - "stride": stride, - "shape": shape, - "pooling type": typef, - "dtype": dtype, - "padding": pad, - "dilation": dilation, - "ceil_mode": ceil_mode, - "count_include_pad": count_include_pad, - "inputs": inputs, - } - verify_saturation = True if dtype == "uint8" else False - for acl in [False, True]: - outputs.append( - build_and_run( - func, - inputs, - 1, - None, - device, - enable_acl=acl, - tvm_ops=tvm_ops, - acl_partitions=acl_partitions, - config=config, - )[0] - ) - - verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation) - - -def test_global_pooling(): + verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation) + + +@pytest.mark.parametrize( + "typef,dtype,input_shape", + [ + ["nn.global_max_pool2d", "float32", (8, 8, 16)], + ["nn.global_max_pool2d", "float32", (9, 9, 16)], + ["nn.global_max_pool2d", "float32", (8, 8, 16)], + ["nn.global_max_pool2d", "uint8", (8, 8, 16)], + ["nn.global_max_pool2d", "uint8", (9, 9, 16)], + ["nn.global_max_pool2d", "int8", (8, 8, 16)], + ["nn.global_max_pool2d", "int8", (9, 9, 16)], + ["nn.global_avg_pool2d", "float32", (8, 8, 16)], + ["nn.global_avg_pool2d", "float32", (8, 8, 16)], + ["nn.global_avg_pool2d", "float32", (9, 9, 16)], + ["nn.global_avg_pool2d", "uint8", (8, 8, 16)], + ["nn.global_avg_pool2d", "uint8", (8, 8, 16)], + ["nn.global_avg_pool2d", "int8", (8, 8, 16)], + ["nn.global_avg_pool2d", "int8", (8, 8, 16)], + ], +) +def test_global_pooling(typef, dtype, input_shape): Device.load("test_config.json") if skip_runtime_test(): @@ -262,118 +305,113 @@ def test_global_pooling(): device = Device() np.random.seed(0) - fp32_dtype = ("float32", -127, 128, 0.001, 0.001) - uint8_dtype = ("uint8", 0, 255, 1, 0) - - trials = [ - ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", fp32_dtype, (9, 9, 16)], - ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", uint8_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", uint8_dtype, (9, 9, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (9, 9, 16)], - ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], - ] - - for typef, (dtype, low, high, atol, rtol), input_shape in trials: - shape = (1, *input_shape) - outputs = [] - inputs = { - "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), - } - - func = _get_global_pooling_model(shape, dtype, typef, iter(inputs)) - config = { - "shape": shape, - "pooling type": typef, - "dtype": dtype, - } - verify_saturation = True if dtype == "uint8" else False - - for acl in [False, True]: - outputs.append( - build_and_run(func, inputs, 1, None, device, enable_acl=acl, config=config)[0] - ) - - verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation) - - -def test_codegen_pooling(): - if skip_codegen_test(): - return + low, high, rtol, atol = _get_low_high_atol_rtol(dtype) - fp32_dtype = ("float32", -127, 128) - uint8_dtype = ("uint8", 0, 255) - # fmt: off - trials = [ - ["nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),], - ["nn.max_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),], - ["nn.max_pool2d", uint8_dtype, (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),], - ["nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", fp32_dtype, (3, 3), (2, 2), (3, 2), (0, 1), True, False, (15, 15, 16), (1, 0),], - ["nn.avg_pool2d", uint8_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, True, (16, 16, 16), (0, 1),], - ["nn.avg_pool2d", uint8_dtype, (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (0, 1), True, False, (15, 15, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (3, 3), (2, 2), (1, 1), (0, 0), False, False, (16, 16, 16), (0, 1),], - ["nn.l2_pool2d", fp32_dtype, (2, 2), (2, 2), (1, 1), (1, 1), False, True, (15, 15, 16), (0, 1),], - ] - # fmt: on - for ( - typef, - (dtype, low, high), - size, - stride, - dilation, - pad, - ceil_mode, - count_include_pad, - input_shape, - (tvm_ops, acl_partitions), - ) in trials: - shape = (1, *input_shape) - inputs = {"a"} - args = (shape, dtype, typef, size, stride, dilation, pad, False, False) - func = _get_pooling_model(*args, iter(inputs)) - exp_codegen = _get_expected_pooling_codegen(*args) + shape = (1, *input_shape) + outputs = [] + inputs = { + "a": tvm.nd.array(np.random.uniform(low, high, shape).astype(dtype)), + } - verify_codegen(func, exp_codegen, acl_partitions, tvm_ops) + func = _get_global_pooling_model(shape, dtype, typef, iter(inputs)) + config = { + "shape": shape, + "pooling type": typef, + "dtype": dtype, + } + verify_saturation = True if dtype in ("uint8", "int8") else False + for acl in [False, True]: + outputs.append( + build_and_run(func, inputs, 1, None, device, enable_acl=acl, config=config)[0] + ) + + verify(outputs, atol=atol, rtol=rtol, config=config, verify_saturation=verify_saturation) + + +# fmt: off +@pytest.mark.parametrize( + "typef,dtype,size,stride,dilation,pad,ceil_mode,count_include_pad,input_shape,expected_ops", + [ + ("nn.max_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "float32", (3, 3), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "uint8", (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),), + ("nn.max_pool2d", "int8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.max_pool2d", "int8", (2, 2), (2, 2), (1, 1), (1, 1), True, True, (15, 15, 16), (0, 1),), + ("nn.max_pool2d", "int8", (2, 2), (2, 2), (3, 2), (1, 1), True, True, (15, 15, 16), (1, 0),), + ("nn.avg_pool2d", "float32", (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "float32", (2, 2), (2, 2), (1, 1), (1, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 0), False, True, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "float32", (3, 3), (2, 2), (3, 2), (0, 1), True, False, (15, 15, 16), (1, 0),), + ("nn.avg_pool2d", "uint8", (2, 2), (2, 2), (1, 1), (1, 1), False, True, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "uint8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "int8", (2, 2), (2, 2), (1, 1), (1, 1), False, True, (16, 16, 16), (0, 1),), + ("nn.avg_pool2d", "int8", (3, 3), (2, 2), (1, 1), (0, 1), False, False, (16, 16, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (2, 2), (2, 2), (1, 1), (0, 1), True, False, (15, 15, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (3, 3), (2, 2), (1, 1), (0, 0), False, False, (16, 16, 16), (0, 1),), + ("nn.l2_pool2d", "float32", (2, 2), (2, 2), (1, 1), (1, 1), False, True, (15, 15, 16), (0, 1),), + ], +) +# fmt: on +def test_codegen_pooling( + typef, + dtype, + size, + stride, + dilation, + pad, + ceil_mode, + count_include_pad, + input_shape, + expected_ops, +): + if skip_codegen_test(): + return -def test_codegen_global_pooling(): + low, high, _, _ = _get_low_high_atol_rtol(dtype) + tvm_ops, acl_partitions = expected_ops + + shape = (1, *input_shape) + inputs = {"a"} + args = (shape, dtype, typef, size, stride, dilation, pad, False, False) + func = _get_pooling_model(*args, iter(inputs)) + exp_codegen = _get_expected_pooling_codegen(*args) + + verify_codegen(func, exp_codegen, acl_partitions, tvm_ops) + + +@pytest.mark.parametrize( + "typef,dtype,input_shape", + [ + ("nn.global_max_pool2d", "float32", (8, 8, 16)), + ("nn.global_max_pool2d", "float32", (9, 9, 16)), + ("nn.global_max_pool2d", "uint8", (8, 8, 16)), + ("nn.global_max_pool2d", "uint8", (9, 9, 16)), + ("nn.global_max_pool2d", "int8", (8, 8, 16)), + ("nn.global_max_pool2d", "int8", (9, 9, 16)), + ("nn.global_avg_pool2d", "float32", (8, 8, 16)), + ("nn.global_avg_pool2d", "float32", (9, 9, 16)), + ("nn.global_avg_pool2d", "uint8", (8, 8, 16)), + ("nn.global_avg_pool2d", "uint8", (9, 9, 16)), + ("nn.global_avg_pool2d", "int8", (8, 8, 16)), + ("nn.global_avg_pool2d", "int8", (9, 9, 16)), + ], +) +def test_codegen_global_pooling(typef, dtype, input_shape): if skip_codegen_test(): return - fp32_dtype = ("float32", -127, 128) - uint8_dtype = ("uint8", 0, 255) - - trials = [ - ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", fp32_dtype, (9, 9, 16)], - ["nn.global_max_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", uint8_dtype, (8, 8, 16)], - ["nn.global_max_pool2d", uint8_dtype, (9, 9, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", fp32_dtype, (9, 9, 16)], - ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], - ["nn.global_avg_pool2d", uint8_dtype, (8, 8, 16)], - ] - - for typef, (dtype, low, high), input_shape in trials: - shape = (1, *input_shape) - inputs = {"a"} - args = (shape, dtype, typef) - func = _get_global_pooling_model(*args, iter(inputs)) - exp_codegen = _get_expected_global_pooling_codegen(*args) - verify_codegen(func, exp_codegen, 1) + low, high, _, _ = _get_low_high_atol_rtol(dtype) + + shape = (1, *input_shape) + inputs = {"a"} + args = (shape, dtype, typef) + func = _get_global_pooling_model(*args, iter(inputs)) + exp_codegen = _get_expected_global_pooling_codegen(*args) + verify_codegen(func, exp_codegen, 1) if __name__ == "__main__": From d34973675e630f2bfb0e21e0e8e2e17c50c1d4a7 Mon Sep 17 00:00:00 2001 From: Leandro Nunes Date: Mon, 28 Nov 2022 09:44:40 +0000 Subject: [PATCH 2/3] Update tests/python/contrib/test_arm_compute_lib/test_pooling.py --- tests/python/contrib/test_arm_compute_lib/test_pooling.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/python/contrib/test_arm_compute_lib/test_pooling.py b/tests/python/contrib/test_arm_compute_lib/test_pooling.py index 9f4430bf81d2..573f0ed47b42 100644 --- a/tests/python/contrib/test_arm_compute_lib/test_pooling.py +++ b/tests/python/contrib/test_arm_compute_lib/test_pooling.py @@ -291,9 +291,9 @@ def test_pooling( ["nn.global_avg_pool2d", "float32", (8, 8, 16)], ["nn.global_avg_pool2d", "float32", (9, 9, 16)], ["nn.global_avg_pool2d", "uint8", (8, 8, 16)], - ["nn.global_avg_pool2d", "uint8", (8, 8, 16)], - ["nn.global_avg_pool2d", "int8", (8, 8, 16)], + ["nn.global_avg_pool2d", "uint8", (9, 9, 16)], ["nn.global_avg_pool2d", "int8", (8, 8, 16)], + ["nn.global_avg_pool2d", "int8", (9, 9, 16)], ], ) def test_global_pooling(typef, dtype, input_shape): From ec10c02ec9d44c30acf87ec8d53ac488bf73e757 Mon Sep 17 00:00:00 2001 From: Leandro Nunes Date: Mon, 28 Nov 2022 10:23:53 +0000 Subject: [PATCH 3/3] Update tests/python/contrib/test_arm_compute_lib/test_pooling.py Co-authored-by: Luke Hutton --- tests/python/contrib/test_arm_compute_lib/test_pooling.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/python/contrib/test_arm_compute_lib/test_pooling.py b/tests/python/contrib/test_arm_compute_lib/test_pooling.py index 573f0ed47b42..f08fa0059ddc 100644 --- a/tests/python/contrib/test_arm_compute_lib/test_pooling.py +++ b/tests/python/contrib/test_arm_compute_lib/test_pooling.py @@ -282,13 +282,11 @@ def test_pooling( [ ["nn.global_max_pool2d", "float32", (8, 8, 16)], ["nn.global_max_pool2d", "float32", (9, 9, 16)], - ["nn.global_max_pool2d", "float32", (8, 8, 16)], ["nn.global_max_pool2d", "uint8", (8, 8, 16)], ["nn.global_max_pool2d", "uint8", (9, 9, 16)], ["nn.global_max_pool2d", "int8", (8, 8, 16)], ["nn.global_max_pool2d", "int8", (9, 9, 16)], ["nn.global_avg_pool2d", "float32", (8, 8, 16)], - ["nn.global_avg_pool2d", "float32", (8, 8, 16)], ["nn.global_avg_pool2d", "float32", (9, 9, 16)], ["nn.global_avg_pool2d", "uint8", (8, 8, 16)], ["nn.global_avg_pool2d", "uint8", (9, 9, 16)],