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 a9df801543 [ETHOSN] Upgrade NPU driver stack to v22.05 (#11759)
a9df801543 is described below

commit a9df8015431147237868a7f72a933e1057050d41
Author: Luke Hutton <[email protected]>
AuthorDate: Tue Aug 2 09:33:10 2022 +0100

    [ETHOSN] Upgrade NPU driver stack to v22.05 (#11759)
    
    * [ETHOSN] Upgrade NPU driver stack to v22.05
    
    In updating the driver stack to v22.05 some additional things needed
    changes:
    * Prevent split being offloaded to the NPU which is not supported in
      v22.05.
    * Removes compile algorithm configuration option since this was removed
      in v22.05. Versions before v22.05 will use the default option.
    * Managing some API changes.
    * Updating network compile hashes.
    * Updating expected error message for overall scale bounds check.
    
    Change-Id: I09343c398a1f47dec44e135ff8252a6315a9b63f
    
    * fix decorator evaluation order
    
    Change-Id: Ib1a34093b4011bdc20fca47d474eb1786218de98
    
    * Return none if version doesn't exist
    
    For some reason PyTest evaluates the second skipif decorator even
    if the first one marks the test to be skipped. Thus, meaning test
    collection fails when we want to check the version. The workaround
    is to return None when the version is not available.
    
    Change-Id: I7cdd8cc70a9ee3c193e9a900f1011829538d975b
    
    * Update resnet hash after rebase
    
    Change-Id: I7555c4a4d7db4f6c7aa8d476e39277fc5cba2f0d
---
 .../install/ubuntu_install_ethosn_driver_stack.sh  |  2 +-
 python/tvm/relay/op/contrib/ethosn.py              |  7 ++
 src/relay/backend/contrib/ethosn/codegen.cc        |  2 -
 src/relay/backend/contrib/ethosn/codegen_ethosn.h  |  2 -
 .../backend/contrib/ethosn/ethosn_api_version.h    |  3 +
 src/runtime/contrib/ethosn/ethosn_device.cc        | 11 +++-
 tests/python/contrib/test_ethosn/infrastructure.py | 30 ++++++++-
 tests/python/contrib/test_ethosn/test_conv2d.py    |  7 +-
 .../contrib/test_ethosn/test_fullyconnected.py     |  7 +-
 tests/python/contrib/test_ethosn/test_networks.py  | 74 +++++++++++++---------
 tests/python/contrib/test_ethosn/test_split.py     |  8 +++
 .../python/contrib/test_ethosn/test_topologies.py  | 34 +++++++++-
 12 files changed, 139 insertions(+), 48 deletions(-)

diff --git a/docker/install/ubuntu_install_ethosn_driver_stack.sh 
b/docker/install/ubuntu_install_ethosn_driver_stack.sh
index e7878d8e4b..1f8373a839 100755
--- a/docker/install/ubuntu_install_ethosn_driver_stack.sh
+++ b/docker/install/ubuntu_install_ethosn_driver_stack.sh
@@ -22,7 +22,7 @@ set -o pipefail
 
 repo_url="https://github.com/Arm-software/ethos-n-driver-stack";
 repo_dir="ethosn-driver"
-repo_revision="21.11"
+repo_revision="22.05"
 install_path="/opt/arm/$repo_dir"
 
 tmpdir=$(mktemp -d)
diff --git a/python/tvm/relay/op/contrib/ethosn.py 
b/python/tvm/relay/op/contrib/ethosn.py
index b3540a9433..2b1d7b13ce 100644
--- a/python/tvm/relay/op/contrib/ethosn.py
+++ b/python/tvm/relay/op/contrib/ethosn.py
@@ -46,6 +46,11 @@ def ethosn_available():
     return Available.SW_AND_HW if hw else Available.SW_ONLY
 
 
+def ethosn_api_version():
+    """Returns the version of the driver stack api that is being used."""
+    return tvm.get_global_func("relay.ethos-n.api.version")()
+
+
 def partition_for_ethosn(mod, params=None, **opts):
     """Partition the graph greedily offloading supported
     operators to Arm Ethos-N NPU.
@@ -279,6 +284,8 @@ def split(expr):
     """Check if a split is supported by Ethos-N."""
     if not ethosn_available():
         return False
+    if ethosn_api_version() == 2205:
+        return False
     if not support.split(expr):
         return False
 
diff --git a/src/relay/backend/contrib/ethosn/codegen.cc 
b/src/relay/backend/contrib/ethosn/codegen.cc
index 67ae1d20e3..b09ed68449 100644
--- a/src/relay/backend/contrib/ethosn/codegen.cc
+++ b/src/relay/backend/contrib/ethosn/codegen.cc
@@ -662,8 +662,6 @@ sl::CompilationOptions EthosnCompiler::CreateOptions() {
   options.m_EnableIntermediateCompression = 
cfg.value()->enable_intermediate_compression;
   options.m_DisableWinograd = cfg.value()->disable_winograd;
   options.m_DebugInfo.m_DebugDir = cfg.value()->debug_dir;
-  options.m_CompilerAlgorithm =
-      
sl::EthosNCompilerAlgorithmFromString(cfg.value()->compiler_algorithm.c_str());
   return options;
 }
 
diff --git a/src/relay/backend/contrib/ethosn/codegen_ethosn.h 
b/src/relay/backend/contrib/ethosn/codegen_ethosn.h
index 9da4e5b18b..d2208bd313 100644
--- a/src/relay/backend/contrib/ethosn/codegen_ethosn.h
+++ b/src/relay/backend/contrib/ethosn/codegen_ethosn.h
@@ -248,7 +248,6 @@ struct EthosnCompilerConfigNode : public 
tvm::AttrsNode<EthosnCompilerConfigNode
   bool enable_intermediate_compression;
   bool disable_winograd;
   String debug_dir;
-  String compiler_algorithm;
 
   TVM_DECLARE_ATTRS(EthosnCompilerConfigNode, 
"ext.attrs.EthosnCompilerConfigNode") {
     TVM_ATTR_FIELD(variant).describe("See Ethos-N 
documentation.").set_default("n78");
@@ -276,7 +275,6 @@ struct EthosnCompilerConfigNode : public 
tvm::AttrsNode<EthosnCompilerConfigNode
     TVM_ATTR_FIELD(enable_intermediate_compression).set_default(true);
     TVM_ATTR_FIELD(disable_winograd).set_default(false);
     TVM_ATTR_FIELD(debug_dir).set_default(".");
-    TVM_ATTR_FIELD(compiler_algorithm).set_default("NonCascadingOnly");
   }
 };
 
diff --git a/src/relay/backend/contrib/ethosn/ethosn_api_version.h 
b/src/relay/backend/contrib/ethosn/ethosn_api_version.h
index 7631c297cc..b1067679f2 100644
--- a/src/relay/backend/contrib/ethosn/ethosn_api_version.h
+++ b/src/relay/backend/contrib/ethosn/ethosn_api_version.h
@@ -35,6 +35,9 @@
  */
 
 #if ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 3 && 
ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 0 && \
+    ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 1
+#define _ETHOSN_API_VERSION_ 2205
+#elif ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 3 && 
ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 0 && \
     ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 0
 #define _ETHOSN_API_VERSION_ 2111
 #else
diff --git a/src/runtime/contrib/ethosn/ethosn_device.cc 
b/src/runtime/contrib/ethosn/ethosn_device.cc
index 9871703638..7aa8dac57e 100644
--- a/src/runtime/contrib/ethosn/ethosn_device.cc
+++ b/src/runtime/contrib/ethosn/ethosn_device.cc
@@ -163,12 +163,21 @@ bool Inference(tvm::runtime::TVMArgs args, dl::Network* 
npu,
       case 8: {
         dl::Buffer** ofms = &ofm_raw[0];
         for (DLTensor* tensor : outputs) {
-          uint8_t* source_buffer_data = (*ofms++)->GetMappedBuffer();
+          dl::Buffer* source_buffer = (*ofms++);
+#if _ETHOSN_API_VERSION_ < 2111
+          uint8_t* source_buffer_data = source_buffer->GetMappedBuffer();
+#else
+          uint8_t* source_buffer_data = source_buffer->Map();
+#endif
           uint8_t* dest_pointer = static_cast<uint8_t*>(tensor->data);
           if (source_buffer_data != dest_pointer) {
             CopyOutput<uint8_t>(ofm_raw, &outputs);
             break;
           }
+#if _ETHOSN_API_VERSION_ >= 2111
+          source_buffer->Unmap();
+#else
+#endif
         }
         break;
       }
diff --git a/tests/python/contrib/test_ethosn/infrastructure.py 
b/tests/python/contrib/test_ethosn/infrastructure.py
index e1bbcf8ad3..e551f0a929 100644
--- a/tests/python/contrib/test_ethosn/infrastructure.py
+++ b/tests/python/contrib/test_ethosn/infrastructure.py
@@ -270,6 +270,33 @@ def test_error(mod, params, err_msg):
     assert err_msg in caught, caught
 
 
+def get_overall_scale_range_expected_error_message():
+    """
+    Get the expected error message when the overall scale is out of range.
+    Different versions of the driver stack support different scale ranges,
+    so creating a unified utility to obtain the expected message.
+    """
+    if get_ethosn_api_version() >= 2205:
+        lb = "2^-32"
+    elif get_ethosn_api_version() > 2102:
+        lb = "2.328306e-10"
+    else:
+        lb = "0"
+
+    if get_ethosn_api_version() >= 2205:
+        ub = "65536"
+    else:
+        ub = "1"
+
+    lb_bracket = "(" if get_ethosn_api_version() >= 2205 else "["
+    ub_bracket = ")"
+
+    return (
+        "Overall scale (of the input * weights / output) should be in the 
range "
+        f"{lb_bracket}{lb}, {ub}{ub_bracket}"
+    )
+
+
 def get_conv2d(var, shape, dtype):
     """Standard convolution to test activation functions"""
 
@@ -333,7 +360,8 @@ def get_conv2d_qnn_params(
 
 
 def get_ethosn_api_version():
-    return tvm.get_global_func("relay.ethos-n.api.version")()
+    gf = tvm.get_global_func("relay.ethos-n.api.version", True)
+    return gf() if gf else None
 
 
 def get_ethosn_variant():
diff --git a/tests/python/contrib/test_ethosn/test_conv2d.py 
b/tests/python/contrib/test_ethosn/test_conv2d.py
index f7d8811b3a..dbf7903218 100644
--- a/tests/python/contrib/test_ethosn/test_conv2d.py
+++ b/tests/python/contrib/test_ethosn/test_conv2d.py
@@ -208,16 +208,15 @@ def test_conv2d(dtype, depthwise):
 
 @requires_ethosn
 def test_conv2d_failure():
-    lb = "2.328306e-10" if tei.get_ethosn_api_version() > 2102 else "0"
     trials = [
         (
             (1, 4, 4, 4),
             1,
             1,
             0,
-            1,
+            1024,
             0,
-            1,
+            1024,
             0,
             1,
             "none",
@@ -227,7 +226,7 @@ def test_conv2d_failure():
             "uint8",
             8,
             "HWIO",
-            f"Overall scale (of the input * weights / output) should be in the 
range [{lb}, 1)",
+            tei.get_overall_scale_range_expected_error_message(),
         ),
         (
             (1, 4, 4, 4),
diff --git a/tests/python/contrib/test_ethosn/test_fullyconnected.py 
b/tests/python/contrib/test_ethosn/test_fullyconnected.py
index 7a636561f9..4171c67272 100644
--- a/tests/python/contrib/test_ethosn/test_fullyconnected.py
+++ b/tests/python/contrib/test_ethosn/test_fullyconnected.py
@@ -111,19 +111,18 @@ def test_fullyconnected(dtype):
 
 @requires_ethosn
 def test_fullyconnected_failure():
-    lb = "2.328306e-10" if tei.get_ethosn_api_version() > 2102 else "0"
     trials = [
         (
             (1, 64),
             (1, 64),
             0,
-            1,
+            1024,
             0,
-            1,
+            1024,
             0,
             1,
             "uint8",
-            f"Overall scale (of the input * weights / output) should be in the 
range [{lb}, 1)",
+            tei.get_overall_scale_range_expected_error_message(),
         ),
         (
             (1, 1, 1, 64),
diff --git a/tests/python/contrib/test_ethosn/test_networks.py 
b/tests/python/contrib/test_ethosn/test_networks.py
index 143ec0b88d..066b2e4a9f 100644
--- a/tests/python/contrib/test_ethosn/test_networks.py
+++ b/tests/python/contrib/test_ethosn/test_networks.py
@@ -118,18 +118,21 @@ def _test_image_network(
 
 @requires_ethosn
 def test_mobilenet_v1():
-    # If this test is failing due to a hash mismatch, please notify @mbaret and
+    # If this test is failing due to a hash mismatch, please notify @lhutton1 
and
     # @Leo-arm. The hash is there to catch any changes in the behaviour of the
     # codegen, which could come about from either a change in Support Library
     # version or a change in the Ethos-N codegen. To update this requires 
running
     # on hardware that isn't available in CI.
-    _compile_hash = {"393a19dfb980345cdd3bbeddbc36424d"}
-    if tei.get_ethosn_api_version() == 2111:
+    if tei.get_ethosn_api_version() == 2205:
+        _compile_hash = {"cb12b5469d78af81f4704488e3857755"}
+    elif tei.get_ethosn_api_version() == 2111:
         _compile_hash = {"5d1c6a6bd4df8963866cc90405bf92dd"}
-    if tei.get_ethosn_api_version() == 2102:
+    elif tei.get_ethosn_api_version() == 2102:
         _compile_hash = {"46ccafc840633633aca441645e41b444"}
         if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO":
             _compile_hash = {"e4ed29dceb1187505948ab17fc3cc6d6"}
+    else:
+        _compile_hash = {"393a19dfb980345cdd3bbeddbc36424d"}
     _test_image_network(
         model_url="https://storage.googleapis.com/download.tensorflow.org/";
         "models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz",
@@ -145,40 +148,44 @@ def test_mobilenet_v1():
 
 @requires_ethosn
 def test_resnet_50_int8():
-    # If this test is failing due to a hash mismatch, please notify @mbaret and
+    # If this test is failing due to a hash mismatch, please notify @lhutton1 
and
     # @Leo-arm. The hash is there to catch any changes in the behaviour of the
     # codegen, which could come about from either a change in Support Library
     # version or a change in the Ethos-N codegen. To update this requires 
running
     # on hardware that isn't available in CI.
-    if tei.get_ethosn_api_version() > 2011:
-        if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO":
-            _compile_hash = {"c0a01c547ed1b2e3308094508fa1bfea", 
"434f0c65c41e24d5482142c88b3438fe"}
-            _test_image_network(
-                
model_url="https://raw.githubusercontent.com/dmlc/web-data/main/tensorflow/";
-                "models/Quantized/resnet_50_quantized.tflite",
-                model_sub_path="resnet_50_quantized.tflite",
-                input_dict={"input": (1, 224, 224, 3)},
-                compile_hash=_compile_hash,
-                output_count=1,
-                host_ops=11,
-                npu_partitions=2,
-            )
+    if tei.get_ethosn_api_version() == 2205:
+        _compile_hash = {"c0a01c547ed1b2e3308094508fa1bfea", 
"64905a4ff2dbde08078ccc9f44ad711d"}
+    else:
+        _compile_hash = {"c0a01c547ed1b2e3308094508fa1bfea", 
"434f0c65c41e24d5482142c88b3438fe"}
+    _test_image_network(
+        
model_url="https://raw.githubusercontent.com/dmlc/web-data/main/tensorflow/";
+        "models/Quantized/resnet_50_quantized.tflite",
+        model_sub_path="resnet_50_quantized.tflite",
+        input_dict={"input": (1, 224, 224, 3)},
+        compile_hash=_compile_hash,
+        output_count=1,
+        host_ops=11,
+        npu_partitions=2,
+    )
 
 
 @requires_ethosn
 def test_inception_v3():
-    # If this test is failing due to a hash mismatch, please notify @mbaret and
+    # If this test is failing due to a hash mismatch, please notify @lhutton1 
and
     # @Leo-arm. The hash is there to catch any changes in the behaviour of the
     # codegen, which could come about from either a change in Support Library
     # version or a change in the Ethos-N codegen. To update this requires 
running
     # on hardware that isn't available in CI.
-    _compile_hash = {"2c7ff5487e1a21e62b3b42eec624fed4"}
-    if tei.get_ethosn_api_version() == 2111:
+    if tei.get_ethosn_api_version() == 2205:
+        _compile_hash = {"85ef702ad3628c598db8c72060c70a61"}
+    elif tei.get_ethosn_api_version() == 2111:
         _compile_hash = {"e6abe33a7bc4a4170da53eefa6577bba"}
-    if tei.get_ethosn_api_version() == 2102:
+    elif tei.get_ethosn_api_version() == 2102:
         _compile_hash = {"43dc2097127eb224c0191b1a15f8acca"}
         if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO":
             _compile_hash = {"7db23387bdc5af6eaa1ae3f7d456caf0"}
+    else:
+        _compile_hash = {"2c7ff5487e1a21e62b3b42eec624fed4"}
     _test_image_network(
         model_url="https://storage.googleapis.com/download.tensorflow.org/";
         "models/tflite_11_05_08/inception_v3_quant.tgz",
@@ -193,18 +200,21 @@ def test_inception_v3():
 
 @requires_ethosn
 def test_inception_v4():
-    # If this test is failing due to a hash mismatch, please notify @mbaret and
+    # If this test is failing due to a hash mismatch, please notify @lhutton1 
and
     # @Leo-arm. The hash is there to catch any changes in the behaviour of the
     # codegen, which could come about from either a change in Support Library
     # version or a change in the Ethos-N codegen. To update this requires 
running
     # on hardware that isn't available in CI.
-    _compile_hash = {"4245dbd02e1432dc261a67fc8e632a00"}
-    if tei.get_ethosn_api_version() == 2111:
+    if tei.get_ethosn_api_version() == 2205:
+        _compile_hash = {"91a980eaf53881f4f109a1a7578e422b"}
+    elif tei.get_ethosn_api_version() == 2111:
         _compile_hash = {"42e43c323ed8202f7b720ba9029bbcb7"}
-    if tei.get_ethosn_api_version() == 2102:
+    elif tei.get_ethosn_api_version() == 2102:
         _compile_hash = {"fab6c2297502f95d33079c6ce1a737f9"}
         if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO":
             _compile_hash = {"8da68849b75613ac3dffd3fff2dd87da"}
+    else:
+        _compile_hash = {"4245dbd02e1432dc261a67fc8e632a00"}
     _test_image_network(
         model_url="https://storage.googleapis.com/download.tensorflow.org/";
         "models/inception_v4_299_quant_20181026.tgz",
@@ -219,19 +229,21 @@ def test_inception_v4():
 
 @requires_ethosn
 def test_ssd_mobilenet_v1():
-    # If this test is failing due to a hash mismatch, please notify @mbaret and
+    # If this test is failing due to a hash mismatch, please notify @lhutton1 
and
     # @Leo-arm. The hash is there to catch any changes in the behaviour of the
     # codegen, which could come about from either a change in Support Library
     # version or a change in the Ethos-N codegen. To update this requires 
running
     # on hardware that isn't available in CI.
-    _compile_hash = {"5ee8ed6af9a7f31fc14957b51a8e7423", 
"e6a91ccc47ba4c6b4614fcd676bd726f"}
-    if tei.get_ethosn_api_version() == 2111:
-        # TODO(Leo-arm): review split operator
+    if tei.get_ethosn_api_version() == 2205:
+        _compile_hash = {"d804ce3496a776c48f719b4062d5e5c3", 
"afb68ca8f452d1f4a674b457b5e30f59"}
+    elif tei.get_ethosn_api_version() == 2111:
         _compile_hash = {"a37f900601b9493bd142e8aed16205e5", 
"afb68ca8f452d1f4a674b457b5e30f59"}
-    if tei.get_ethosn_api_version() == 2102:
+    elif tei.get_ethosn_api_version() == 2102:
         _compile_hash = {"7795b6c67178da9d1f9b98063bad75b1", 
"10826406ae724e52f360a06c35ced09d"}
         if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO":
             _compile_hash = {"928dc6ae5ce49a4ad63ca87f7575970f", 
"b092f9820f7e9341fc53daa781b98772"}
+    else:
+        _compile_hash = {"5ee8ed6af9a7f31fc14957b51a8e7423", 
"e6a91ccc47ba4c6b4614fcd676bd726f"}
     _test_image_network(
         model_url="https://storage.googleapis.com/download.tensorflow.org/";
         "models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip",
diff --git a/tests/python/contrib/test_ethosn/test_split.py 
b/tests/python/contrib/test_ethosn/test_split.py
index 320172e1e3..bd75371c94 100644
--- a/tests/python/contrib/test_ethosn/test_split.py
+++ b/tests/python/contrib/test_ethosn/test_split.py
@@ -31,6 +31,10 @@ def _get_model(shape, dtype, splits, axis):
     return split.astuple()
 
 
[email protected](
+    tei.get_ethosn_api_version() == 2205,
+    reason="Split is not supported by the 22.05 release of the driver stack",
+)
 @requires_ethosn
 @pytest.mark.parametrize("dtype", ["uint8", "int8"])
 def test_split(dtype):
@@ -60,6 +64,10 @@ def test_split(dtype):
         tei.verify(outputs, dtype, 0)
 
 
[email protected](
+    tei.get_ethosn_api_version() == 2205,
+    reason="Split is not supported by the 22.05 release of the driver stack",
+)
 @requires_ethosn
 def test_split_failure():
     trials = [
diff --git a/tests/python/contrib/test_ethosn/test_topologies.py 
b/tests/python/contrib/test_ethosn/test_topologies.py
index 07cfb3ac01..baff2d61dd 100644
--- a/tests/python/contrib/test_ethosn/test_topologies.py
+++ b/tests/python/contrib/test_ethosn/test_topologies.py
@@ -73,7 +73,20 @@ def test_split_add_concat(dtype):
     for npu in [False, True]:
         model = get_model(inputs["a"].shape, dtype, iter(inputs))
         mod = tei.make_module(model, [])
-        outputs.append(tei.build_and_run(mod, inputs, 1, {}, npu=npu))
+
+        expected_host_ops = 1 if tei.get_ethosn_api_version() == 2205 else 0
+        npu_partitions = 2 if tei.get_ethosn_api_version() == 2205 else 1
+        outputs.append(
+            tei.build_and_run(
+                mod,
+                inputs,
+                1,
+                {},
+                npu=npu,
+                expected_host_ops=expected_host_ops,
+                npu_partitions=npu_partitions,
+            )
+        )
 
     tei.verify(outputs, dtype, 2)
 
@@ -202,11 +215,28 @@ def test_split_with_asym_concats(dtype):
         for npu in [False, True]:
             model = get_model(shape, dtype, splits, axis)
             mod = tei.make_module(model, {})
-            outputs.append(tei.build_and_run(mod, inputs, 2, {}, npu=npu))
+
+            expected_host_ops = 1 if tei.get_ethosn_api_version() == 2205 else 0
+            npu_partitions = 2 if tei.get_ethosn_api_version() == 2205 else 1
+            outputs.append(
+                tei.build_and_run(
+                    mod,
+                    inputs,
+                    2,
+                    {},
+                    npu=npu,
+                    expected_host_ops=expected_host_ops,
+                    npu_partitions=npu_partitions,
+                )
+            )
 
         tei.verify(outputs, dtype, 0)
 
 
[email protected](
+    tei.get_ethosn_api_version() == 2205,
+    reason="Split is not supported by the 22.05 release of the driver stack",
+)
 @requires_ethosn
 @pytest.mark.parametrize("dtype", ["uint8", "int8"])
 def test_output_tuple_propagation(dtype):

Reply via email to