From 9d7db1e1dd2d99baa0a9d8ab680444b86efe8ab0 Mon Sep 17 00:00:00 2001 From: MonalSD Date: Sun, 10 Mar 2024 22:46:58 +0530 Subject: [PATCH 1/6] Support complex tensors for ScatterNd operations --- .../tensorflow_common/src/op/scatter_nd.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index 785e4a7f16960d..9f1faab43c50e7 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -15,15 +15,32 @@ namespace frontend { namespace tensorflow { namespace op { OutputVector translate_scatter_nd_op(const NodeContext& node) { - default_op_checks(node, 3, {"ScatterNd", "SCATTER_ND"}); + default_op_checks(node, 3, {"ScatterNd", "SCATTER_ND"},true); auto input_indices = node.get_input(0); auto updates = node.get_input(1); auto shape = node.get_input(2); + auto complex_type_mark_input_indices = as_type_ptr(input_indices.get_node_shared_ptr()); + auto complex_type_mark_updates = as_type_ptr(updates.get_node_shared_ptr()); + auto complex_type_mark_shape = as_type_ptr(shape.get_node_shared_ptr()); + auto complex_type_inputs = (complex_type_mark_input_indices || complex_type_mark_updates || complex_type_mark_shape) ? true : false; + + if(complex_type_inputs){ + input_indices = complex_type_mark_input_indices->input_value(0); + updates = complex_type_mark_updates->input_value(0); + shape = complex_type_mark_shape->input_value(0); + } + auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); auto broadcast = make_shared(input_data, shape); + auto scatter_nd = make_shared(broadcast, input_indices, updates); set_node_name(node.get_name(), scatter_nd); + if(complex_type_inputs){ + auto complex_scatter_nd = make_shared(scatter_nd,complex_type_mark_updates->get_complex_part_type()); + return {complex_scatter_nd}; + } + return {scatter_nd}; } } // namespace op From 91e480074e1b5ceba718848ecbc1ea55208838a2 Mon Sep 17 00:00:00 2001 From: MonalSD Date: Mon, 11 Mar 2024 10:37:50 +0530 Subject: [PATCH 2/6] Updating test_tf_ScatterND --- .../tensorflow_common/src/op/scatter_nd.cpp | 18 ++++--- .../tensorflow_tests/test_tf_ScatterND.py | 51 +++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index 9f1faab43c50e7..d63074588dae38 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -15,7 +15,7 @@ namespace frontend { namespace tensorflow { namespace op { OutputVector translate_scatter_nd_op(const NodeContext& node) { - default_op_checks(node, 3, {"ScatterNd", "SCATTER_ND"},true); + default_op_checks(node, 3, {"ScatterNd", "SCATTER_ND"}, true); auto input_indices = node.get_input(0); auto updates = node.get_input(1); auto shape = node.get_input(2); @@ -23,9 +23,10 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { auto complex_type_mark_input_indices = as_type_ptr(input_indices.get_node_shared_ptr()); auto complex_type_mark_updates = as_type_ptr(updates.get_node_shared_ptr()); auto complex_type_mark_shape = as_type_ptr(shape.get_node_shared_ptr()); - auto complex_type_inputs = (complex_type_mark_input_indices || complex_type_mark_updates || complex_type_mark_shape) ? true : false; - - if(complex_type_inputs){ + auto complex_type_inputs = + (complex_type_mark_input_indices || complex_type_mark_updates || complex_type_mark_shape) ? true : false; + + if (complex_type_inputs) { input_indices = complex_type_mark_input_indices->input_value(0); updates = complex_type_mark_updates->input_value(0); shape = complex_type_mark_shape->input_value(0); @@ -33,14 +34,15 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); auto broadcast = make_shared(input_data, shape); - + auto scatter_nd = make_shared(broadcast, input_indices, updates); set_node_name(node.get_name(), scatter_nd); - if(complex_type_inputs){ - auto complex_scatter_nd = make_shared(scatter_nd,complex_type_mark_updates->get_complex_part_type()); + if (complex_type_inputs) { + auto complex_scatter_nd = + make_shared(scatter_nd, complex_type_mark_updates->get_complex_part_type()); return {complex_scatter_nd}; } - + return {scatter_nd}; } } // namespace op diff --git a/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py b/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py index 818e09d3f03602..3492e791c2329e 100644 --- a/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py +++ b/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py @@ -73,3 +73,54 @@ def test_tf_scatter_nd(self, params, ie_device, precision, ir_version, temp_dir, use_legacy_frontend=use_legacy_frontend), ie_device, precision, temp_dir=temp_dir, ir_version=ir_version, use_legacy_frontend=use_legacy_frontend, **params) + +class TestComplexScatterND(CommonTFLayerTest): + def create_complex_scatter_nd_net(self, x_shape, indices, updates, ir_version, + use_legacy_frontend): + import tensorflow as tf + tf.compat.v1.reset_default_graph() + + # Create the graph and model + with tf.compat.v1.Session() as sess: + x = tf.compat.v1.placeholder(tf.complex64, x_shape, 'Input') + tf_indices = tf.constant(indices) + tf_updates = tf.constant(updates, dtype=tf.complex64) + scatter_nd = tf.scatter_nd(tf_indices, tf_updates, tf.shape(x), name="Operation") + res = tf.add(x, scatter_nd) + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph_def + ref_net = None + return tf_net, ref_net + + test_data = [ + pytest.param( + dict(x_shape=[8], indices=[[4], [3], [1], [7]], updates=[9j, 10j, 11j, 12j]), + marks=pytest.mark.precommit), + pytest.param(dict(x_shape=[4, 4, 4], indices=[[0], [2]], updates= \ + [[[[5j, 5j, 5j, 5j], [6j, 6j, 6j, 6j], [7j, 7j, 7j, 7j], [8j, 8j, 8j, 8j]], \ + [[1j, 1j, 1j, 1j], [2j, 2j, 2j, 2j], [3j, 3j, 3j, 3j], [4j, 4j, 4j, 4j]]]])), + pytest.param(dict(x_shape=[2, 2], indices=[[0]], updates=[[5j, 3j]])), + pytest.param(dict(x_shape=[2, 2], indices=[[1, 1]], updates=[5j])), + dict(x_shape=[1], indices=[[0]], updates=[3j]), + dict(x_shape=[20], indices=[[0], [6], [9], [19], [13]], + updates=[3j, 7j, -12j, 4j, -99j]), + dict(x_shape=[4, 2], indices=[[1], [2]], updates=[[9j, 14j], [-76j, 0j]]), + dict(x_shape=[4, 4, 4], indices=[[0], [1], [3]], updates=[ + [[5j, 1j, 5j, 13j], [8j, 6j, 6j, 8j], [7j, 0j, 0j, 7j], [8j, 8j, 8j, 8j]], + [[0j, 0j, 0j, 0j], [1j, 2j, 3j, 4j], [5j, 6j, 7j, 8j], [9j, 10j, 11j, 12j]], + [[5j, 5j, 5j, 5j], [6j, 6j, 6j, 6j], [7j, 7j, 7j, 7j], [8j, 8j, 8j, 8j]]]), + dict(x_shape=[2, 2, 2], indices=[[1, 1, 1], [0, 1, 0]], updates=[9j, 6.3j]), + pytest.param(dict(x_shape=[2, 2, 2], indices=[[0, 0], [0, 1]], updates=[[6.7j, 9j], [45j, 8.3j]]), + marks=pytest.mark.precommit_tf_fe), + dict(x_shape=[2, 2, 2], indices=[[1]], updates=[[[6.7j, 9j], [45j, 8.3j]]]), + + ] + + @pytest.mark.parametrize("params", test_data) + @pytest.mark.nightly + def test_tf_scatter_nd(self, params, ie_device, precision, ir_version, temp_dir, + use_legacy_frontend): + self._test(*self.create_complex_scatter_nd_net(**params, ir_version=ir_version, + use_legacy_frontend=use_legacy_frontend), + ie_device, precision, temp_dir=temp_dir, ir_version=ir_version, + use_legacy_frontend=use_legacy_frontend, **params) \ No newline at end of file From b20ca333a5210fefd28cf228f28becfaa39f4e59 Mon Sep 17 00:00:00 2001 From: MonalSD Date: Tue, 12 Mar 2024 10:10:01 +0530 Subject: [PATCH 3/6] Addressing changes in ScatterNd --- .../tensorflow_common/src/op/scatter_nd.cpp | 10 +-- .../tensorflow_tests/test_tf_ScatterND.py | 75 +++++++++++-------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index d63074588dae38..d1ed164623b75e 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -20,16 +20,10 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { auto updates = node.get_input(1); auto shape = node.get_input(2); - auto complex_type_mark_input_indices = as_type_ptr(input_indices.get_node_shared_ptr()); auto complex_type_mark_updates = as_type_ptr(updates.get_node_shared_ptr()); - auto complex_type_mark_shape = as_type_ptr(shape.get_node_shared_ptr()); - auto complex_type_inputs = - (complex_type_mark_input_indices || complex_type_mark_updates || complex_type_mark_shape) ? true : false; - if (complex_type_inputs) { - input_indices = complex_type_mark_input_indices->input_value(0); + if (complex_type_mark_updates) { updates = complex_type_mark_updates->input_value(0); - shape = complex_type_mark_shape->input_value(0); } auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); @@ -42,7 +36,7 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { make_shared(scatter_nd, complex_type_mark_updates->get_complex_part_type()); return {complex_scatter_nd}; } - + return {scatter_nd}; } } // namespace op diff --git a/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py b/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py index 3492e791c2329e..49ee75fd101a1c 100644 --- a/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py +++ b/tests/layer_tests/tensorflow_tests/test_tf_ScatterND.py @@ -5,7 +5,7 @@ import pytest from common.tf_layer_test_class import CommonTFLayerTest - +import numpy as np class TestTFScatterND(CommonTFLayerTest): def create_tf_scatternd_placeholder_const_net(self, x_shape, indices, updates, ir_version, @@ -79,44 +79,55 @@ def create_complex_scatter_nd_net(self, x_shape, indices, updates, ir_version, use_legacy_frontend): import tensorflow as tf tf.compat.v1.reset_default_graph() - # Create the graph and model with tf.compat.v1.Session() as sess: - x = tf.compat.v1.placeholder(tf.complex64, x_shape, 'Input') - tf_indices = tf.constant(indices) - tf_updates = tf.constant(updates, dtype=tf.complex64) - scatter_nd = tf.scatter_nd(tf_indices, tf_updates, tf.shape(x), name="Operation") - res = tf.add(x, scatter_nd) + x = tf.compat.v1.placeholder(tf.float32, x_shape, 'Input') + tf_indices = tf.compat.v1.placeholder(np.int32, [None], 'indices') + updates_real = tf.compat.v1.placeholder(np.float32, [None], 'updates_real') + updates_imag = tf.compat.v1.placeholder(np.float32, [None], 'updates_imag') + updates = tf.raw_ops.Complex(real=updates_real,imag=updates_imag) + + scatter_nd = tf.raw_ops.ScatterNd(indices, updates, tf.shape(x), name="Operation") + res = tf.add(x_shape, scatter_nd, name="Operation") + real = tf.raw_ops.Real(input=res) + img = tf.raw_ops.Imag(input=res) tf.compat.v1.global_variables_initializer() tf_net = sess.graph_def - ref_net = None - return tf_net, ref_net - - test_data = [ - pytest.param( - dict(x_shape=[8], indices=[[4], [3], [1], [7]], updates=[9j, 10j, 11j, 12j]), - marks=pytest.mark.precommit), - pytest.param(dict(x_shape=[4, 4, 4], indices=[[0], [2]], updates= \ - [[[[5j, 5j, 5j, 5j], [6j, 6j, 6j, 6j], [7j, 7j, 7j, 7j], [8j, 8j, 8j, 8j]], \ - [[1j, 1j, 1j, 1j], [2j, 2j, 2j, 2j], [3j, 3j, 3j, 3j], [4j, 4j, 4j, 4j]]]])), - pytest.param(dict(x_shape=[2, 2], indices=[[0]], updates=[[5j, 3j]])), - pytest.param(dict(x_shape=[2, 2], indices=[[1, 1]], updates=[5j])), - dict(x_shape=[1], indices=[[0]], updates=[3j]), - dict(x_shape=[20], indices=[[0], [6], [9], [19], [13]], - updates=[3j, 7j, -12j, 4j, -99j]), - dict(x_shape=[4, 2], indices=[[1], [2]], updates=[[9j, 14j], [-76j, 0j]]), - dict(x_shape=[4, 4, 4], indices=[[0], [1], [3]], updates=[ - [[5j, 1j, 5j, 13j], [8j, 6j, 6j, 8j], [7j, 0j, 0j, 7j], [8j, 8j, 8j, 8j]], - [[0j, 0j, 0j, 0j], [1j, 2j, 3j, 4j], [5j, 6j, 7j, 8j], [9j, 10j, 11j, 12j]], - [[5j, 5j, 5j, 5j], [6j, 6j, 6j, 6j], [7j, 7j, 7j, 7j], [8j, 8j, 8j, 8j]]]), - dict(x_shape=[2, 2, 2], indices=[[1, 1, 1], [0, 1, 0]], updates=[9j, 6.3j]), - pytest.param(dict(x_shape=[2, 2, 2], indices=[[0, 0], [0, 1]], updates=[[6.7j, 9j], [45j, 8.3j]]), - marks=pytest.mark.precommit_tf_fe), - dict(x_shape=[2, 2, 2], indices=[[1]], updates=[[[6.7j, 9j], [45j, 8.3j]]]), + return tf_net, None + + def prepare_input(self, inputs_info): + rng = np.random.default_rng() + + assert 'indices' in inputs_info + assert 'updates_real' in inputs_info + assert 'updates_imag' in inputs_info + assert 'x_shape' in inputs_info + + indices_shape = inputs_info['indices'] + updates_real_shape = inputs_info['updates_real'] + updates_imag_shape = inputs_info['updates_imag'] + x_shape = inputs_info['x_shape'] + + inputs_data = {} + inputs_data['indices'] = rng.integers(0, 10, indices_shape).astype(np.int32) # Example range (0, 10), adjust as needed + inputs_data['updates_real'] = 4 * rng.random(updates_real_shape).astype(np.float32) - 2 + inputs_data['updates_imag'] = 4 * rng.random(updates_imag_shape).astype(np.float32) - 2 + inputs_data['x_shape'] = rng.integers(0, 10, indices_shape).astype(np.int32) + + return inputs_data + + test_data_basic = [ + dict(input_shape=[]), + dict(input_shape=[2]), + dict(input_shape=[1, 3]), + dict(input_shape=[2, 3, 4]), + dict(input_shape=[3, 4, 5, 6]), ] - @pytest.mark.parametrize("params", test_data) + + @pytest.mark.parametrize("params", test_data_basic) + @pytest.mark.precommit_tf_fe @pytest.mark.nightly def test_tf_scatter_nd(self, params, ie_device, precision, ir_version, temp_dir, use_legacy_frontend): From c32412399b6c4c74a52faa22970ca2aa595ab80b Mon Sep 17 00:00:00 2001 From: MonalSD Date: Thu, 14 Mar 2024 13:23:28 +0530 Subject: [PATCH 4/6] Fixing addressed issues --- src/frontends/tensorflow_common/src/op/scatter_nd.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index d1ed164623b75e..a671a33739b84e 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -19,24 +19,29 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { auto input_indices = node.get_input(0); auto updates = node.get_input(1); auto shape = node.get_input(2); - auto complex_type_mark_updates = as_type_ptr(updates.get_node_shared_ptr()); if (complex_type_mark_updates) { updates = complex_type_mark_updates->input_value(0); } + // Add two auxiliary dimensions to the shape tensor + Shape shape_dims = shape->get_shape(); + shape_dims.insert(shape_dims.begin(), 1); + shape_dims.insert(shape_dims.begin(), 1); + auto updated_shape = make_shared(shape_dims, shape->get_data_type()); auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); - auto broadcast = make_shared(input_data, shape); + auto broadcast = make_shared(input_data, updated_shape); auto scatter_nd = make_shared(broadcast, input_indices, updates); set_node_name(node.get_name(), scatter_nd); + if (complex_type_inputs) { auto complex_scatter_nd = make_shared(scatter_nd, complex_type_mark_updates->get_complex_part_type()); return {complex_scatter_nd}; } - + return {scatter_nd}; } } // namespace op From 153c3d59b60f4ebcb03386fe9ce446a66bc1dbbd Mon Sep 17 00:00:00 2001 From: MonalSD Date: Sun, 24 Mar 2024 00:05:15 +0530 Subject: [PATCH 5/6] Addressing changes --- .../tensorflow_common/src/op/scatter_nd.cpp | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index 4a59951931fc5d..5ddee47e293d38 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -3,7 +3,9 @@ // #include "common_op_table.hpp" +#include "helper_ops/complex_type_mark.hpp" #include "openvino/op/broadcast.hpp" +#include "openvino/op/concat.hpp" #include "openvino/op/scatter_nd_update.hpp" #include "utils.hpp" @@ -23,25 +25,27 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { if (complex_type_mark_updates) { updates = complex_type_mark_updates->input_value(0); - } - // Add two auxiliary dimensions to the shape tensor - Shape shape_dims = shape->get_shape(); - shape_dims.insert(shape_dims.begin(), 1); - shape_dims.insert(shape_dims.begin(), 1); - auto updated_shape = make_shared(shape_dims, shape->get_data_type()); + // Add two auxiliary dimensions to the shape tensor + Shape shape_dims = shape.get_shape(); + shape_dims.insert(shape_dims.begin(), 2); + auto aux_shape = create_same_type_const(shape, std::vector{2}, Shape{1}); + auto updated_shape = make_shared(OutputVector{aux_shape, shape}, 0); - auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); - auto broadcast = make_shared(input_data, updated_shape); + auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); + auto broadcast = make_shared(input_data, updated_shape); - auto scatter_nd = make_shared(broadcast, input_indices, updates); - set_node_name(node.get_name(), scatter_nd); + auto scatter_nd = make_shared(broadcast, input_indices, updates); + set_node_name(node.get_name(), scatter_nd); - if (complex_type_inputs) { auto complex_scatter_nd = make_shared(scatter_nd, complex_type_mark_updates->get_complex_part_type()); return {complex_scatter_nd}; } + auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); + auto broadcast = make_shared(input_data, shape); + auto scatter_nd = make_shared(broadcast, input_indices, updates); + set_node_name(node.get_name(), scatter_nd); return {scatter_nd}; } } // namespace op From 28b13e9f372a021034aa976b01c5a3d4120d65ed Mon Sep 17 00:00:00 2001 From: MonalSD Date: Mon, 8 Apr 2024 13:28:20 +0530 Subject: [PATCH 6/6] Update scatter_nd.cpp --- src/frontends/tensorflow_common/src/op/scatter_nd.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp index 5ddee47e293d38..4cbb5982f44691 100644 --- a/src/frontends/tensorflow_common/src/op/scatter_nd.cpp +++ b/src/frontends/tensorflow_common/src/op/scatter_nd.cpp @@ -22,16 +22,17 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { auto updates = node.get_input(1); auto shape = node.get_input(2); auto complex_type_mark_updates = as_type_ptr(updates.get_node_shared_ptr()); + auto zero_scalar = create_same_type_const(updates, 0); if (complex_type_mark_updates) { updates = complex_type_mark_updates->input_value(0); // Add two auxiliary dimensions to the shape tensor - Shape shape_dims = shape.get_shape(); - shape_dims.insert(shape_dims.begin(), 2); + auto shape_of_op = make_shared(updates); + auto shape_dims = make_shared(shape_of_op); auto aux_shape = create_same_type_const(shape, std::vector{2}, Shape{1}); - auto updated_shape = make_shared(OutputVector{aux_shape, shape}, 0); + auto updated_shape = make_shared(OutputVector{aux_shape, shape_dims}, 0); - auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); + auto input_data = zero_scalar; auto broadcast = make_shared(input_data, updated_shape); auto scatter_nd = make_shared(broadcast, input_indices, updates); @@ -42,7 +43,7 @@ OutputVector translate_scatter_nd_op(const NodeContext& node) { return {complex_scatter_nd}; } - auto input_data = create_same_type_const(updates, vector{0}, Shape{1}); + auto input_data = zero_scalar; auto broadcast = make_shared(input_data, shape); auto scatter_nd = make_shared(broadcast, input_indices, updates); set_node_name(node.get_name(), scatter_nd);