From 867ae40eac308bef8879dd4c1d46460ce35f79a2 Mon Sep 17 00:00:00 2001 From: srinidhigoud Date: Wed, 21 Apr 2021 00:30:28 +0000 Subject: [PATCH 1/5] SelectV2 and BroadcastArgs op support for tf2 models --- 3rdparty/vta-hw | 2 +- python/tvm/relay/frontend/tensorflow.py | 43 +++++++++++++++++-- .../frontend/tensorflow/test_forward.py | 27 ++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/3rdparty/vta-hw b/3rdparty/vta-hw index 43194178b4e5..87ce9acfae55 160000 --- a/3rdparty/vta-hw +++ b/3rdparty/vta-hw @@ -1 +1 @@ -Subproject commit 43194178b4e570a5f1dd4f3f9d37ee16fc1b65be +Subproject commit 87ce9acfae550d1a487746e9d06c2e250076e54c diff --git a/python/tvm/relay/frontend/tensorflow.py b/python/tvm/relay/frontend/tensorflow.py index 6dd164c6e35e..0de00517e9a8 100644 --- a/python/tvm/relay/frontend/tensorflow.py +++ b/python/tvm/relay/frontend/tensorflow.py @@ -1765,6 +1765,44 @@ def _impl(inputs, attr, params, mod): return _impl +def _broadcast_args(): + def _impl(inputs, attr, params, mod): + if isinstance(inputs[0], _expr.Var): + s0 = params[inputs[0].name_hint] + else: + s0 = _infer_value(inputs[0], params, mod) + if isinstance(inputs[1], _expr.Var): + s1 = params[inputs[1].name_hint] + else: + s1 = _infer_value(inputs[1], params, mod) + s0 = list(s0.asnumpy().reshape([-1])) + s1 = list(s1.asnumpy().reshape([-1])) + s0_size, s1_size = len(s0), len(s1) + from collections import deque + + out = deque([]) + for i in range(1, min(s0_size, s1_size) + 1): + if s0[s0_size - i] == s1[s1_size - i]: + out.appendleft(s0[s0_size - i]) + elif s0[s0_size - i] == 1: + out.appendleft(s1[s1_size - i]) + else: + assert s1[s1_size - i] == 1, "Incompatible broadcast type %s and %s" % ( + s0[s0_size - i], + s1[s1_size - i], + ) + out.appendleft(s0[s0_size - i]) + if s0_size < s1_size: + for i in range(s0_size + 1, s1_size + 1): + out.appendleft(s1[s1_size - i]) + if s1_size < s0_size: + for i in range(s1_size + 1, s0_size + 1): + out.appendleft(s0[s0_size - i]) + return _expr.const(list(out), attr["T"].name) + + return _impl + + def _broadcast_to(): def _impl(inputs, attr, params, mod): if isinstance(inputs[1], _expr.Var): @@ -2740,6 +2778,7 @@ def _impl(inputs, attr, params, mod): "BatchToSpaceND": _batch_to_space_nd(), "BiasAdd": _bias_add(), "BroadcastTo": _broadcast_to(), + "BroadcastArgs": _broadcast_args(), "Cast": _cast(), "Ceil": AttrCvt("ceil"), "CheckNumerics": _check_numerics(), @@ -2833,6 +2872,7 @@ def _impl(inputs, attr, params, mod): "Round": AttrCvt("round"), "Rsqrt": _rsqrt(), "Select": _where(), + "SelectV2": _where(), "Selu": _selu(), "Shape": _shape(), "Sigmoid": AttrCvt("sigmoid"), @@ -3936,7 +3976,6 @@ def _backtrack_construct(self, node_name): raise ImportError("Unable to import tensorflow which is required {}".format(e)) input_op_name = node_name.split(":")[0].split("^")[-1] - if input_op_name not in self._nodes: node = self._tf_node_map[input_op_name] attr = self._parse_attr(node.attr) @@ -3997,7 +4036,6 @@ def _backtrack_construct(self, node_name): inputs[i] = actual_input op = self._convert_operator(node.op, node.name, inputs, attr) - if isinstance(op, np.ndarray): self._params[node.name] = tvm.nd.array(op) op = [ @@ -4019,7 +4057,6 @@ def _backtrack_construct(self, node_name): tn = node_name.split(":") tensor_slot = int(tn[1]) if len(tn) > 1 else 0 return out[tensor_slot] - return out[0] diff --git a/tests/python/frontend/tensorflow/test_forward.py b/tests/python/frontend/tensorflow/test_forward.py index 8446ef3d590b..2e4237b34ab1 100644 --- a/tests/python/frontend/tensorflow/test_forward.py +++ b/tests/python/frontend/tensorflow/test_forward.py @@ -3050,6 +3050,33 @@ def test_forward_resize(): _test_resize_nearest_neighbor_dynamic_shape((1, 16, 16, 3), scale=[2, 2]) +####################################################################### +# BroadcastArgs +# ----------- + + +def _test_broadcast_args(in_shape_1, in_shape_2): + """ One iteration of broadcast_args""" + + shape_1 = np.array(in_shape_1).astype("int32") + shape_2 = np.array(in_shape_2).astype("int32") + + with tf.Graph().as_default(): + shape_1 = constant_op.constant(shape_1, shape=shape_1.shape, dtype=shape_1.dtype) + shape_2 = constant_op.constant(shape_2, shape=shape_2.shape, dtype=shape_2.dtype) + tf.raw_ops.BroadcastArgs(s0=shape_1, s1=shape_2) + + compare_tf_with_tvm(None, "", "BroadcastArgs:0", opt_level=0) + + +def test_forward_broadcast_args(): + """ Resize Bilinear """ + + _test_broadcast_args((4, 1, 32, 32), [4, 8, 32, 32]) + _test_broadcast_args((6, 32, 32, 1), [6, 32, 32, 16]) + _test_broadcast_args((32, 32, 16), [6, 32, 32, 16]) + + ####################################################################### # BroadcastTo # ----------- From 3df4763b9e247ea2211e6a9c686e635bbf7c714b Mon Sep 17 00:00:00 2001 From: srinidhigoud Date: Sat, 24 Apr 2021 00:01:38 +0000 Subject: [PATCH 2/5] moving import and referencing test for SelectV2 --- python/tvm/relay/frontend/tensorflow.py | 2 +- tests/python/frontend/tensorflow/test_forward.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/tvm/relay/frontend/tensorflow.py b/python/tvm/relay/frontend/tensorflow.py index 0de00517e9a8..50221c7baf28 100644 --- a/python/tvm/relay/frontend/tensorflow.py +++ b/python/tvm/relay/frontend/tensorflow.py @@ -19,6 +19,7 @@ """TF: Tensorflow frontend.""" import warnings from collections import defaultdict +from collections import deque # Numpy support import numpy as np @@ -1778,7 +1779,6 @@ def _impl(inputs, attr, params, mod): s0 = list(s0.asnumpy().reshape([-1])) s1 = list(s1.asnumpy().reshape([-1])) s0_size, s1_size = len(s0), len(s1) - from collections import deque out = deque([]) for i in range(1, min(s0_size, s1_size) + 1): diff --git a/tests/python/frontend/tensorflow/test_forward.py b/tests/python/frontend/tensorflow/test_forward.py index 2e4237b34ab1..f8d3e2386070 100644 --- a/tests/python/frontend/tensorflow/test_forward.py +++ b/tests/python/frontend/tensorflow/test_forward.py @@ -3620,7 +3620,7 @@ def test_forward_logical(): ####################################################################### -# Where, Select +# Where, Select, SelectV2 # ------------- def test_forward_where(): """ Where: return elements depending on conditions""" From 67c87ad43f5746985b564d7a53afee93338caf3b Mon Sep 17 00:00:00 2001 From: srinidhigoud Date: Sat, 24 Apr 2021 00:34:20 +0000 Subject: [PATCH 3/5] Revert "moving import and referencing test for SelectV2" This reverts commit 3df4763b9e247ea2211e6a9c686e635bbf7c714b. --- python/tvm/relay/frontend/tensorflow.py | 2 +- tests/python/frontend/tensorflow/test_forward.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/tvm/relay/frontend/tensorflow.py b/python/tvm/relay/frontend/tensorflow.py index 50221c7baf28..0de00517e9a8 100644 --- a/python/tvm/relay/frontend/tensorflow.py +++ b/python/tvm/relay/frontend/tensorflow.py @@ -19,7 +19,6 @@ """TF: Tensorflow frontend.""" import warnings from collections import defaultdict -from collections import deque # Numpy support import numpy as np @@ -1779,6 +1778,7 @@ def _impl(inputs, attr, params, mod): s0 = list(s0.asnumpy().reshape([-1])) s1 = list(s1.asnumpy().reshape([-1])) s0_size, s1_size = len(s0), len(s1) + from collections import deque out = deque([]) for i in range(1, min(s0_size, s1_size) + 1): diff --git a/tests/python/frontend/tensorflow/test_forward.py b/tests/python/frontend/tensorflow/test_forward.py index f8d3e2386070..2e4237b34ab1 100644 --- a/tests/python/frontend/tensorflow/test_forward.py +++ b/tests/python/frontend/tensorflow/test_forward.py @@ -3620,7 +3620,7 @@ def test_forward_logical(): ####################################################################### -# Where, Select, SelectV2 +# Where, Select # ------------- def test_forward_where(): """ Where: return elements depending on conditions""" From 02dc4b6e245f309a574d6edde08de52ca740c792 Mon Sep 17 00:00:00 2001 From: srinidhigoud Date: Sat, 24 Apr 2021 00:34:26 +0000 Subject: [PATCH 4/5] Revert "SelectV2 and BroadcastArgs op support for tf2 models" This reverts commit 867ae40eac308bef8879dd4c1d46460ce35f79a2. --- 3rdparty/vta-hw | 2 +- python/tvm/relay/frontend/tensorflow.py | 43 ++----------------- .../frontend/tensorflow/test_forward.py | 27 ------------ 3 files changed, 4 insertions(+), 68 deletions(-) diff --git a/3rdparty/vta-hw b/3rdparty/vta-hw index 87ce9acfae55..43194178b4e5 160000 --- a/3rdparty/vta-hw +++ b/3rdparty/vta-hw @@ -1 +1 @@ -Subproject commit 87ce9acfae550d1a487746e9d06c2e250076e54c +Subproject commit 43194178b4e570a5f1dd4f3f9d37ee16fc1b65be diff --git a/python/tvm/relay/frontend/tensorflow.py b/python/tvm/relay/frontend/tensorflow.py index 0de00517e9a8..6dd164c6e35e 100644 --- a/python/tvm/relay/frontend/tensorflow.py +++ b/python/tvm/relay/frontend/tensorflow.py @@ -1765,44 +1765,6 @@ def _impl(inputs, attr, params, mod): return _impl -def _broadcast_args(): - def _impl(inputs, attr, params, mod): - if isinstance(inputs[0], _expr.Var): - s0 = params[inputs[0].name_hint] - else: - s0 = _infer_value(inputs[0], params, mod) - if isinstance(inputs[1], _expr.Var): - s1 = params[inputs[1].name_hint] - else: - s1 = _infer_value(inputs[1], params, mod) - s0 = list(s0.asnumpy().reshape([-1])) - s1 = list(s1.asnumpy().reshape([-1])) - s0_size, s1_size = len(s0), len(s1) - from collections import deque - - out = deque([]) - for i in range(1, min(s0_size, s1_size) + 1): - if s0[s0_size - i] == s1[s1_size - i]: - out.appendleft(s0[s0_size - i]) - elif s0[s0_size - i] == 1: - out.appendleft(s1[s1_size - i]) - else: - assert s1[s1_size - i] == 1, "Incompatible broadcast type %s and %s" % ( - s0[s0_size - i], - s1[s1_size - i], - ) - out.appendleft(s0[s0_size - i]) - if s0_size < s1_size: - for i in range(s0_size + 1, s1_size + 1): - out.appendleft(s1[s1_size - i]) - if s1_size < s0_size: - for i in range(s1_size + 1, s0_size + 1): - out.appendleft(s0[s0_size - i]) - return _expr.const(list(out), attr["T"].name) - - return _impl - - def _broadcast_to(): def _impl(inputs, attr, params, mod): if isinstance(inputs[1], _expr.Var): @@ -2778,7 +2740,6 @@ def _impl(inputs, attr, params, mod): "BatchToSpaceND": _batch_to_space_nd(), "BiasAdd": _bias_add(), "BroadcastTo": _broadcast_to(), - "BroadcastArgs": _broadcast_args(), "Cast": _cast(), "Ceil": AttrCvt("ceil"), "CheckNumerics": _check_numerics(), @@ -2872,7 +2833,6 @@ def _impl(inputs, attr, params, mod): "Round": AttrCvt("round"), "Rsqrt": _rsqrt(), "Select": _where(), - "SelectV2": _where(), "Selu": _selu(), "Shape": _shape(), "Sigmoid": AttrCvt("sigmoid"), @@ -3976,6 +3936,7 @@ def _backtrack_construct(self, node_name): raise ImportError("Unable to import tensorflow which is required {}".format(e)) input_op_name = node_name.split(":")[0].split("^")[-1] + if input_op_name not in self._nodes: node = self._tf_node_map[input_op_name] attr = self._parse_attr(node.attr) @@ -4036,6 +3997,7 @@ def _backtrack_construct(self, node_name): inputs[i] = actual_input op = self._convert_operator(node.op, node.name, inputs, attr) + if isinstance(op, np.ndarray): self._params[node.name] = tvm.nd.array(op) op = [ @@ -4057,6 +4019,7 @@ def _backtrack_construct(self, node_name): tn = node_name.split(":") tensor_slot = int(tn[1]) if len(tn) > 1 else 0 return out[tensor_slot] + return out[0] diff --git a/tests/python/frontend/tensorflow/test_forward.py b/tests/python/frontend/tensorflow/test_forward.py index 2e4237b34ab1..8446ef3d590b 100644 --- a/tests/python/frontend/tensorflow/test_forward.py +++ b/tests/python/frontend/tensorflow/test_forward.py @@ -3050,33 +3050,6 @@ def test_forward_resize(): _test_resize_nearest_neighbor_dynamic_shape((1, 16, 16, 3), scale=[2, 2]) -####################################################################### -# BroadcastArgs -# ----------- - - -def _test_broadcast_args(in_shape_1, in_shape_2): - """ One iteration of broadcast_args""" - - shape_1 = np.array(in_shape_1).astype("int32") - shape_2 = np.array(in_shape_2).astype("int32") - - with tf.Graph().as_default(): - shape_1 = constant_op.constant(shape_1, shape=shape_1.shape, dtype=shape_1.dtype) - shape_2 = constant_op.constant(shape_2, shape=shape_2.shape, dtype=shape_2.dtype) - tf.raw_ops.BroadcastArgs(s0=shape_1, s1=shape_2) - - compare_tf_with_tvm(None, "", "BroadcastArgs:0", opt_level=0) - - -def test_forward_broadcast_args(): - """ Resize Bilinear """ - - _test_broadcast_args((4, 1, 32, 32), [4, 8, 32, 32]) - _test_broadcast_args((6, 32, 32, 1), [6, 32, 32, 16]) - _test_broadcast_args((32, 32, 16), [6, 32, 32, 16]) - - ####################################################################### # BroadcastTo # ----------- From e89532db30f0b6b59c7b7850919413a6ece1be7c Mon Sep 17 00:00:00 2001 From: srinidhigoud Date: Sat, 24 Apr 2021 00:39:08 +0000 Subject: [PATCH 5/5] Reapplying support for SelectV2 and BroadcastArgs op with selective changes --- python/tvm/relay/frontend/tensorflow.py | 43 +++++++++++++++++-- .../frontend/tensorflow/test_forward.py | 29 ++++++++++++- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/python/tvm/relay/frontend/tensorflow.py b/python/tvm/relay/frontend/tensorflow.py index 6dd164c6e35e..50221c7baf28 100644 --- a/python/tvm/relay/frontend/tensorflow.py +++ b/python/tvm/relay/frontend/tensorflow.py @@ -19,6 +19,7 @@ """TF: Tensorflow frontend.""" import warnings from collections import defaultdict +from collections import deque # Numpy support import numpy as np @@ -1765,6 +1766,43 @@ def _impl(inputs, attr, params, mod): return _impl +def _broadcast_args(): + def _impl(inputs, attr, params, mod): + if isinstance(inputs[0], _expr.Var): + s0 = params[inputs[0].name_hint] + else: + s0 = _infer_value(inputs[0], params, mod) + if isinstance(inputs[1], _expr.Var): + s1 = params[inputs[1].name_hint] + else: + s1 = _infer_value(inputs[1], params, mod) + s0 = list(s0.asnumpy().reshape([-1])) + s1 = list(s1.asnumpy().reshape([-1])) + s0_size, s1_size = len(s0), len(s1) + + out = deque([]) + for i in range(1, min(s0_size, s1_size) + 1): + if s0[s0_size - i] == s1[s1_size - i]: + out.appendleft(s0[s0_size - i]) + elif s0[s0_size - i] == 1: + out.appendleft(s1[s1_size - i]) + else: + assert s1[s1_size - i] == 1, "Incompatible broadcast type %s and %s" % ( + s0[s0_size - i], + s1[s1_size - i], + ) + out.appendleft(s0[s0_size - i]) + if s0_size < s1_size: + for i in range(s0_size + 1, s1_size + 1): + out.appendleft(s1[s1_size - i]) + if s1_size < s0_size: + for i in range(s1_size + 1, s0_size + 1): + out.appendleft(s0[s0_size - i]) + return _expr.const(list(out), attr["T"].name) + + return _impl + + def _broadcast_to(): def _impl(inputs, attr, params, mod): if isinstance(inputs[1], _expr.Var): @@ -2740,6 +2778,7 @@ def _impl(inputs, attr, params, mod): "BatchToSpaceND": _batch_to_space_nd(), "BiasAdd": _bias_add(), "BroadcastTo": _broadcast_to(), + "BroadcastArgs": _broadcast_args(), "Cast": _cast(), "Ceil": AttrCvt("ceil"), "CheckNumerics": _check_numerics(), @@ -2833,6 +2872,7 @@ def _impl(inputs, attr, params, mod): "Round": AttrCvt("round"), "Rsqrt": _rsqrt(), "Select": _where(), + "SelectV2": _where(), "Selu": _selu(), "Shape": _shape(), "Sigmoid": AttrCvt("sigmoid"), @@ -3936,7 +3976,6 @@ def _backtrack_construct(self, node_name): raise ImportError("Unable to import tensorflow which is required {}".format(e)) input_op_name = node_name.split(":")[0].split("^")[-1] - if input_op_name not in self._nodes: node = self._tf_node_map[input_op_name] attr = self._parse_attr(node.attr) @@ -3997,7 +4036,6 @@ def _backtrack_construct(self, node_name): inputs[i] = actual_input op = self._convert_operator(node.op, node.name, inputs, attr) - if isinstance(op, np.ndarray): self._params[node.name] = tvm.nd.array(op) op = [ @@ -4019,7 +4057,6 @@ def _backtrack_construct(self, node_name): tn = node_name.split(":") tensor_slot = int(tn[1]) if len(tn) > 1 else 0 return out[tensor_slot] - return out[0] diff --git a/tests/python/frontend/tensorflow/test_forward.py b/tests/python/frontend/tensorflow/test_forward.py index 8446ef3d590b..f8d3e2386070 100644 --- a/tests/python/frontend/tensorflow/test_forward.py +++ b/tests/python/frontend/tensorflow/test_forward.py @@ -3050,6 +3050,33 @@ def test_forward_resize(): _test_resize_nearest_neighbor_dynamic_shape((1, 16, 16, 3), scale=[2, 2]) +####################################################################### +# BroadcastArgs +# ----------- + + +def _test_broadcast_args(in_shape_1, in_shape_2): + """ One iteration of broadcast_args""" + + shape_1 = np.array(in_shape_1).astype("int32") + shape_2 = np.array(in_shape_2).astype("int32") + + with tf.Graph().as_default(): + shape_1 = constant_op.constant(shape_1, shape=shape_1.shape, dtype=shape_1.dtype) + shape_2 = constant_op.constant(shape_2, shape=shape_2.shape, dtype=shape_2.dtype) + tf.raw_ops.BroadcastArgs(s0=shape_1, s1=shape_2) + + compare_tf_with_tvm(None, "", "BroadcastArgs:0", opt_level=0) + + +def test_forward_broadcast_args(): + """ Resize Bilinear """ + + _test_broadcast_args((4, 1, 32, 32), [4, 8, 32, 32]) + _test_broadcast_args((6, 32, 32, 1), [6, 32, 32, 16]) + _test_broadcast_args((32, 32, 16), [6, 32, 32, 16]) + + ####################################################################### # BroadcastTo # ----------- @@ -3593,7 +3620,7 @@ def test_forward_logical(): ####################################################################### -# Where, Select +# Where, Select, SelectV2 # ------------- def test_forward_where(): """ Where: return elements depending on conditions"""