You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by GitBox <gi...@apache.org> on 2022/09/27 08:53:53 UTC

[GitHub] [tvm] lhutton1 commented on a diff in pull request #12887: [ETHOSN] Support conversion of add/mul to requantize where possible

lhutton1 commented on code in PR #12887:
URL: https://github.com/apache/tvm/pull/12887#discussion_r980229549


##########
src/relay/backend/contrib/ethosn/convert_equivalent.cc:
##########
@@ -39,100 +39,117 @@ namespace relay {
 namespace contrib {
 namespace ethosn {
 
+/*!
+ * \brief Helper class to extract inputs and quantization information from binary
+ * elementwise operations ready to convert.
+ */
+class BinaryElementwiseParams {
+ public:
+  static BinaryElementwiseParams ExtractBinaryElementwiseParams(const Call& call) {
+    auto params = BinaryElementwiseParams();
+    params.input1 = call->args[0];
+    params.input2 = call->args[1];
+    params.input1_scale = call->args[2];
+    params.input1_zero_point = call->args[3];
+    params.input2_scale = call->args[4];
+    params.input2_zero_point = call->args[5];
+    // Reverse the inputs if the constant is first input
+    if (call->args[0]->IsInstance<ConstantNode>()) {
+      params.input1 = call->args[1];
+      params.input2 = call->args[0];
+      params.input1_scale = call->args[4];
+      params.input1_zero_point = call->args[5];
+      params.input2_scale = call->args[2];
+      params.input2_zero_point = call->args[3];
+    }
+    params.output_scale = call->args[6];
+    params.output_zero_point = call->args[7];
+    return params;
+  }
+
+  Expr input1;
+  Expr input2;
+  Expr input1_scale;
+  Expr input1_zero_point;
+  Expr input2_scale;
+  Expr input2_zero_point;
+  Expr output_scale;
+  Expr output_zero_point;

Review Comment:
   Good point, yep I think that makes more sense, thanks!



##########
python/tvm/relay/op/contrib/ethosn.py:
##########
@@ -328,19 +338,40 @@ def check_add(extract):
         """Check if an addition is supported by Ethos-N."""
         if not ethosn_available():
             return False
-        # Do not support scalar constants for now
-        check_scalar = lambda i: isinstance(i, tvm.relay.Constant) and len(i.data.shape) == 0
-        if check_scalar(extract.args[0]) or check_scalar(extract.args[1]):
-            return False
 
-        inputs = extract.args[0:2]
-        if any([isinstance(i, tvm.relay.Constant) for i in inputs]):
-            extract = _ethosn.ConvertQnnAdd(extract)
-            return _ethosn.conv2d(extract)
         return _ethosn.addition(extract)
 
+    def check_add_to_reinterpret_quantize(extract):
+        """Check if addition can be converted to a reinterpret quantize operation."""
+        if not ethosn_available():
+            return False
+        converted_extract = _ethosn.ConvertQnnAddToReinterpretQuantize(extract)
+        if converted_extract:
+            return _ethosn.reinterpret_quantize(converted_extract)
+        return False
+
+    def check_add_to_depthwise(extract):
+        """Check if addition can be converted to a depthwise operation."""
+        if not ethosn_available():
+            return False
+        converted_extract = _ethosn.ConvertQnnAddToDepthwise(extract)

Review Comment:
   This will just do the conversion to a depth-wise operation without any NPU specific constraints. The second part will check whether the generated depth-wise operation can actually be supported by the NPU



##########
python/tvm/relay/op/contrib/ethosn.py:
##########
@@ -328,19 +338,40 @@ def check_add(extract):
         """Check if an addition is supported by Ethos-N."""
         if not ethosn_available():
             return False
-        # Do not support scalar constants for now
-        check_scalar = lambda i: isinstance(i, tvm.relay.Constant) and len(i.data.shape) == 0
-        if check_scalar(extract.args[0]) or check_scalar(extract.args[1]):
-            return False
 
-        inputs = extract.args[0:2]
-        if any([isinstance(i, tvm.relay.Constant) for i in inputs]):
-            extract = _ethosn.ConvertQnnAdd(extract)
-            return _ethosn.conv2d(extract)
         return _ethosn.addition(extract)
 
+    def check_add_to_reinterpret_quantize(extract):
+        """Check if addition can be converted to a reinterpret quantize operation."""
+        if not ethosn_available():
+            return False
+        converted_extract = _ethosn.ConvertQnnAddToReinterpretQuantize(extract)
+        if converted_extract:
+            return _ethosn.reinterpret_quantize(converted_extract)
+        return False
+
+    def check_add_to_depthwise(extract):
+        """Check if addition can be converted to a depthwise operation."""
+        if not ethosn_available():
+            return False
+        converted_extract = _ethosn.ConvertQnnAddToDepthwise(extract)
+        if converted_extract:
+            return _ethosn.conv2d(converted_extract)
+        return False
+
     return [
-        ("ethos-n.qnn_mul", qnn_mul_pattern(), check_mul),

Review Comment:
   Mul is a bit different to addition in that the driver stack doesn't support it as an op directly



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@tvm.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org