From 6c63c522fbcf8afb27933638f12b6b5faf77d9f4 Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 1 Jun 2022 09:16:44 +0000 Subject: [PATCH 1/2] [TFLite] Support quantized EQUAL op in TFLite frontend Support EQUAL quantization operation conversion as part of issue #9187 --- python/tvm/relay/frontend/tflite.py | 6 +----- tests/python/frontend/tflite/test_forward.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/python/tvm/relay/frontend/tflite.py b/python/tvm/relay/frontend/tflite.py index 342c4e2ae553..6e7120d66ed1 100644 --- a/python/tvm/relay/frontend/tflite.py +++ b/python/tvm/relay/frontend/tflite.py @@ -1443,11 +1443,7 @@ def convert_less_equal(self, op): def convert_equal(self, op): """Convert TFLite EQUAL""" - if self.is_quantized(op): - raise tvm.error.OpNotImplemented( - "TFlite quantized EQUAL operator is not supported yet." - ) - return self._convert_elemwise(_op.equal, op) + return self._convert_elemwise(_op.equal, op, self.is_quantized(op)) def convert_not_equal(self, op): """Convert TFLite NOT_EQUAL""" diff --git a/tests/python/frontend/tflite/test_forward.py b/tests/python/frontend/tflite/test_forward.py index 8b0244d75eda..cefb28250c60 100644 --- a/tests/python/frontend/tflite/test_forward.py +++ b/tests/python/frontend/tflite/test_forward.py @@ -2372,9 +2372,15 @@ def _test_less_equal(data): # ----- -def _test_equal(data): +def _test_equal(data, fused_activation_function=None, quantized=False, qnn_op=None): """One iteration of equal""" - return _test_elemwise(math_ops.equal, data) + return _test_elemwise( + math_ops.equal, + data, + fused_activation_function, + quantized, + qnn_op, + ) ####################################################################### From ae6defe9227e8b093d5ea46b5b2a4463226ac67b Mon Sep 17 00:00:00 2001 From: Dhruv Chauhan Date: Wed, 8 Jun 2022 16:14:49 +0000 Subject: [PATCH 2/2] [TFLite] Support quantized EQUAL op in TFLite frontend Update elementwise quantized test for EQUAL op Change-Id: I3897d1ac07051ebfc10356ad45397117b592f878 --- tests/python/frontend/tflite/test_forward.py | 71 +++++++++++++------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/tests/python/frontend/tflite/test_forward.py b/tests/python/frontend/tflite/test_forward.py index cefb28250c60..13d66763b4d2 100644 --- a/tests/python/frontend/tflite/test_forward.py +++ b/tests/python/frontend/tflite/test_forward.py @@ -2200,22 +2200,33 @@ def __test_elemwise(in_data): if None != x[0] } - out = math_op(inq_data[0], inq_data[1]) - out = with_fused_activation_function(out, fused_activation_function) - out = tf.quantization.fake_quant_with_min_max_args( - out, min=out_min, max=out_max, name="out" - ) + if math_op is math_ops.equal: + out = math_op(inq_data[0], inq_data[1]) + out = with_fused_activation_function(out, fused_activation_function) - # Note same_qnn_params uses experimental_new_converter as toco failed - compare_tflite_with_tvm( - [x[1] for x in zip(in_data, data) if None != x[0]], - [x + ":0" for x in input_range.keys()], - [x[1] for x in zip(in_data, inq_data) if None != x[0]], - [out], - quantized=True, - input_range=input_range, - experimental_new_converter=same_qnn_params, - ) + compare_tflite_with_tvm( + [x[1] for x in zip(in_data, data) if None != x[0]], + [x + ":0" for x in input_range.keys()], + [x[1] for x in zip(in_data, inq_data) if None != x[0]], + [out], + ) + else: + out = math_op(inq_data[0], inq_data[1]) + out = with_fused_activation_function(out, fused_activation_function) + out = tf.quantization.fake_quant_with_min_max_args( + out, min=out_min, max=out_max, name="out" + ) + + # Note same_qnn_params uses experimental_new_converter as toco failed + compare_tflite_with_tvm( + [x[1] for x in zip(in_data, data) if None != x[0]], + [x + ":0" for x in input_range.keys()], + [x[1] for x in zip(in_data, inq_data) if None != x[0]], + [out], + quantized=True, + input_range=input_range, + experimental_new_converter=same_qnn_params, + ) else: out = math_op( in_data[0] @@ -2380,6 +2391,7 @@ def _test_equal(data, fused_activation_function=None, quantized=False, qnn_op=No fused_activation_function, quantized, qnn_op, + same_qnn_params=True, ) @@ -2446,14 +2458,25 @@ def _test_forward_elemwise(testop): def _test_forward_elemwise_quantized(testop): - testop( - [ - np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.uint8), - np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.uint8), - ], - quantized=True, - qnn_op=testop, - ) + if testop is not _test_equal: + testop( + [ + np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.uint8), + np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.uint8), + ], + quantized=True, + qnn_op=testop, + ) + else: + # no need for fake_quant to hold tensors in float32 until conversion + testop( + [ + np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.float32), + np.array(np.random.uniform(0, 255, (3, 6)), dtype=np.float32), + ], + quantized=True, + qnn_op=testop, + ) def _test_elemwise_qnn_out_range(qnn_op): @@ -2464,6 +2487,7 @@ def _test_elemwise_qnn_out_range(qnn_op): _test_mul: (-5e3, 5e3), _test_maximum: (-112, 111), _test_minimum: (-128, 127), + _test_equal: (-150, 150), } return qnn_out_range[qnn_op] @@ -2498,6 +2522,7 @@ def test_all_elemwise(): _test_forward_elemwise(_test_less) _test_forward_elemwise(_test_less_equal) _test_forward_elemwise(_test_equal) + _test_forward_elemwise_quantized(_test_equal) _test_forward_elemwise(_test_not_equal) if package_version.parse(tf.VERSION) >= package_version.parse("1.14.0"): _test_forward_elemwise(_test_floor_divide)