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

ekalda 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 94f6b37b06 [Relay][TFLite] Fix in qnn.conv2d when parameter groups not 
equal to 1 (#15472)
94f6b37b06 is described below

commit 94f6b37b063d10fceea561288b3674d9ed32cfcd
Author: padreofthegame <[email protected]>
AuthorDate: Mon Aug 14 12:20:32 2023 +0200

    [Relay][TFLite] Fix in qnn.conv2d when parameter groups not equal to 1 
(#15472)
    
    Currently, qnn.conv2d only supports parameter GROUPS to be equal 1 or depth 
of the input tensor,
    while in any other case (which is valid for parameter GROUPS) it results in 
Relay type checker
    mismatch error related to types[5] argument.
    
    This fix expands qnn.conv2d functionality for other valid values of 
parameter GROUPS.
---
 src/relay/qnn/op/convolution.cc              | 17 +++++++++++---
 tests/python/frontend/tflite/test_forward.py | 35 +++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/src/relay/qnn/op/convolution.cc b/src/relay/qnn/op/convolution.cc
index f5ac6af1df..2ce5523764 100644
--- a/src/relay/qnn/op/convolution.cc
+++ b/src/relay/qnn/op/convolution.cc
@@ -75,13 +75,24 @@ bool QnnConv2DRel(const Array<Type>& types, int num_inputs, 
const Attrs& attrs,
     ICHECK(axis != std::string::npos) << "Kernel layout attribute is not 
defined";
     AssignType(types[5], DataType::Float(32), weight->shape[axis], reporter);  
// weight_scale
   } else {
-    // Here, total number of output channels depend on depth multiplier.
     size_t o_axis = param->kernel_layout.operator std::string().find('O');
     size_t i_axis = param->kernel_layout.operator std::string().find('I');
+    size_t d_axis = param->data_layout.operator std::string().find('C');
     ICHECK(o_axis != std::string::npos || i_axis != std::string::npos)
         << "Kernel layout attribute is not defined";
-    AssignType(types[5], DataType::Float(32), weight->shape[i_axis] * 
weight->shape[o_axis],
-               reporter);  // weight_scale
+    ICHECK(d_axis != std::string::npos) << "Data layout attribute is not 
defined";
+    if (param->channels.defined() &&
+        tvm::tir::ExprDeepEqual()(param->groups, data->shape[d_axis]) &&
+        tvm::tir::ExprDeepEqual()(param->channels, weight->shape[i_axis])) {
+      // This is depthwise convolution
+      // Here, total number of output channels depend on depth multiplier.
+      AssignType(types[5], DataType::Float(32), weight->shape[i_axis] * 
weight->shape[o_axis],
+                 reporter);  // weight_scale
+    } else {
+      // This is grouped convolution
+      AssignType(types[5], DataType::Float(32), param->channels,
+                 reporter);  // weight_scale
+    }
   }
 
   // Collect the input tensor and output tensor devoid of scale and zero 
points to reuse Relay
diff --git a/tests/python/frontend/tflite/test_forward.py 
b/tests/python/frontend/tflite/test_forward.py
index f00624dc03..567139d0c2 100644
--- a/tests/python/frontend/tflite/test_forward.py
+++ b/tests/python/frontend/tflite/test_forward.py
@@ -1001,7 +1001,13 @@ def test_forward_l2_pool2d():
 
 
 def _test_tflite2_quantized_convolution(
-    input_shape, kernel_shape, filters, padding="valid", data_format=None, 
int_quant_dtype=tf.int8
+    input_shape,
+    kernel_shape,
+    filters,
+    padding="valid",
+    data_format=None,
+    int_quant_dtype=tf.int8,
+    groups=1,
 ):
     """One iteration of TFLite2 quantized convolution with given shapes and 
attributes"""
     data_format = "channels_last" if data_format == "NHWC" else 
"channels_first"
@@ -1015,6 +1021,7 @@ def _test_tflite2_quantized_convolution(
         activation=tf.nn.relu,
         padding=padding,
         data_format=data_format,
+        groups=groups,
     )(data_in)
     keras_model = tf.keras.models.Model(data_in, conv)
 
@@ -1076,6 +1083,32 @@ def test_forward_quantized_convolution():
             int_quant_dtype=int_quant_dtype,
         )
 
+        _test_tflite2_quantized_convolution(
+            (64, 2, 28, 28),
+            (1, 1),
+            12,
+            data_format="NCWH",
+            int_quant_dtype=int_quant_dtype,
+        )
+
+        _test_tflite2_quantized_convolution(
+            (1, 16, 10, 10),
+            (3, 3),
+            2,
+            data_format="NCWH",
+            int_quant_dtype=int_quant_dtype,
+            groups=2,
+        )
+
+        _test_tflite2_quantized_convolution(
+            (2, 32, 28, 28),
+            (1, 1),
+            16,
+            data_format="NCWH",
+            int_quant_dtype=int_quant_dtype,
+            groups=8,
+        )
+
 
 def test_forward_quantized_depthwise_convolution():
     for int_quant_dtype in [tf.int8, tf.int16]:

Reply via email to