This is an automated email from the ASF dual-hosted git repository.

lukhut pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 25e98dd5e4 [ACL] Enable int8 data type in pooling operators (#13488)
25e98dd5e4 is described below

commit 25e98dd5e4bd989ade14e36df1fc2e1f81be7885
Author: Leandro Nunes <[email protected]>
AuthorDate: Mon Nov 28 13:22:24 2022 +0000

    [ACL] Enable int8 data type in pooling operators (#13488)
    
    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
    
    Co-authored-by: Luke Hutton <[email protected]>
---
 python/tvm/relay/op/contrib/arm_compute_lib.py     |   6 +-
 .../contrib/test_arm_compute_lib/test_pooling.py   | 414 +++++++++++----------
 2 files changed, 228 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 97f695baca..1b9abb0948 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 
arm_compute_lib_pattern_table(disabled_ops=["concatenate"]):
 
     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":
@@ -440,7 +440,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)
 
@@ -468,7 +468,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 b174f9a788..f08fa0059d 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
[email protected](
+     
"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,77 @@ 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)
+
+
[email protected](
+    "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_global_pooling(typef, dtype, input_shape):
     Device.load("test_config.json")
 
     if skip_runtime_test():
@@ -262,118 +303,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
[email protected](
+     
"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)
+
+
[email protected](
+    "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__":

Reply via email to