From 5dafc03efef2804f6480ad100359a54fc9b035c2 Mon Sep 17 00:00:00 2001 From: Rinne Date: Tue, 27 Feb 2024 08:36:11 +0800 Subject: [PATCH 1/5] feat: add complex support for rank op. --- .../tensorflow_common/src/op/rank.cpp | 44 ++++++++++--- .../tensorflow_tests/test_tf_Rank.py | 64 ++++++++++++++++--- 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/rank.cpp b/src/frontends/tensorflow_common/src/op/rank.cpp index 1c37dfa5a0e878..85092d7ad0ba42 100644 --- a/src/frontends/tensorflow_common/src/op/rank.cpp +++ b/src/frontends/tensorflow_common/src/op/rank.cpp @@ -3,8 +3,11 @@ // #include "common_op_table.hpp" +#include "helper_ops/complex_type_mark.hpp" +#include "openvino/op/constant.hpp" #include "openvino/op/shape_of.hpp" #include "openvino/op/squeeze.hpp" +#include "openvino/util/log.hpp" using namespace std; using namespace ov::op; @@ -14,17 +17,38 @@ namespace frontend { namespace tensorflow { namespace op { -ov::OutputVector translate_rank_op(const NodeContext& node) { - default_op_checks(node, 1, {"Rank"}); - auto input = node.get_input(0); - auto input_shape = make_shared(input, ov::element::i32); - auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); +ov::OutputVector translate_rank_op(const NodeContext &node) { + OPENVINO_DEBUG << "Translating Rank..............."; + default_op_checks(node, 1, {"Rank"}, true); + auto input = node.get_input(0); + auto complex_type_mark = + as_type_ptr(input.get_node_shared_ptr()); + auto input_shape = make_shared(input, ov::element::i32); + if (complex_type_mark) { + element::Type complex_part_type = + complex_type_mark->get_complex_part_type(); + input = complex_type_mark->input_value(0); + + auto unsqueeze_input_rank = + make_shared(input_shape, ov::element::i32); auto input_rank = make_shared(unsqueeze_input_rank); + input_rank = make_shared( + input_rank, + make_shared(ov::element::i32, Shape{1}, + input_shape->get_input_size() - 1)); set_node_name(node.get_name(), input_rank); - return {input_rank}; + auto complex_rank = + make_shared(input_rank, complex_part_type); + return {complex_rank->output(0)}; + } + auto unsqueeze_input_rank = + make_shared(input_shape, ov::element::i32); + auto input_rank = make_shared(unsqueeze_input_rank); + set_node_name(node.get_name(), input_rank); + return {input_rank}; } -} // namespace op -} // namespace tensorflow -} // namespace frontend -} // namespace ov +} // namespace op +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/tests/layer_tests/tensorflow_tests/test_tf_Rank.py b/tests/layer_tests/tensorflow_tests/test_tf_Rank.py index e047b8ecb4ed8b..0d15b81c3d3e33 100644 --- a/tests/layer_tests/tensorflow_tests/test_tf_Rank.py +++ b/tests/layer_tests/tensorflow_tests/test_tf_Rank.py @@ -2,33 +2,79 @@ # SPDX-License-Identifier: Apache-2.0 import pytest +import numpy as np import tensorflow as tf from common.tf_layer_test_class import CommonTFLayerTest -class TestRank(CommonTFLayerTest): - def create_rank_net(self, input_shape, input_type): +# class TestRank(CommonTFLayerTest): +# def create_rank_net(self, input_shape, input_type): +# tf.compat.v1.reset_default_graph() +# # Create the graph and model +# with tf.compat.v1.Session() as sess: +# input = tf.compat.v1.placeholder(input_type, input_shape, 'input') +# tf.raw_ops.Rank(input=input) +# tf.compat.v1.global_variables_initializer() +# tf_net = sess.graph_def + +# return tf_net, None + +# test_data_basic = [ +# dict(input_shape=[], input_type=tf.float32), +# dict(input_shape=[1], input_type=tf.float32), +# dict(input_shape=[2, 6], input_type=tf.int32), +# dict(input_shape=[3, 4, 5, 6], input_type=tf.float32) +# ] + +# @pytest.mark.parametrize("params", test_data_basic) +# @pytest.mark.precommit_tf_fe +# @pytest.mark.nightly +# def test_rank_basic(self, params, ie_device, precision, ir_version, temp_dir, +# use_legacy_frontend): +# self._test(*self.create_rank_net(**params), +# ie_device, precision, ir_version, temp_dir=temp_dir, +# use_legacy_frontend=use_legacy_frontend) + +class TestComplexRank(CommonTFLayerTest): + def _prepare_input(self, inputs_info): + print(inputs_info) + raise NotImplementedError + rng = np.random.default_rng() + assert 'param_real:0' in inputs_info + assert 'param_imag:0' in inputs_info + param_real_shape_1 = inputs_info['param_real:0'] + param_imag_shape_1 = inputs_info['param_imag:0'] + inputs_data = {} + inputs_data['param_real:0'] = 4 * rng.random(param_real_shape_1).astype(np.float32) - 2 + inputs_data['param_imag:0'] = 4 * rng.random(param_imag_shape_1).astype(np.float32) - 2 + return inputs_data + + def create_rank_net(self, input_shape): tf.compat.v1.reset_default_graph() # Create the graph and model with tf.compat.v1.Session() as sess: - input = tf.compat.v1.placeholder(input_type, input_shape, 'input') - tf.raw_ops.Rank(input=input) + input_real = tf.compat.v1.placeholder(np.float32, input_shape, 'param_real') + input_imag = tf.compat.v1.placeholder(np.float32, input_shape, 'param_imag') + input = tf.raw_ops.Complex(real=input_real, imag=input_imag) + rank = tf.raw_ops.Rank(input=input) + # real = tf.raw_ops.Real(input=rank) + # imag = tf.raw_ops.Imag(input=rank) tf.compat.v1.global_variables_initializer() tf_net = sess.graph_def return tf_net, None test_data_basic = [ - dict(input_shape=[], input_type=tf.float32), - dict(input_shape=[1], input_type=tf.float32), - dict(input_shape=[2, 6], input_type=tf.int32), - dict(input_shape=[3, 4, 5, 6], input_type=tf.float32) + # dict(input_shape=[]), + # dict(input_shape=[1]), + dict(input_shape=[2, 6]), + # dict(input_shape=[3, 4, 5, 6]) ] @pytest.mark.parametrize("params", test_data_basic) @pytest.mark.precommit_tf_fe @pytest.mark.nightly - def test_rank_basic(self, params, ie_device, precision, ir_version, temp_dir, + def test_complex_rank(self, params, ie_device, precision, ir_version, temp_dir, use_legacy_frontend): self._test(*self.create_rank_net(**params), ie_device, precision, ir_version, temp_dir=temp_dir, From 90208e0125bf7e9108a090c4acc9d6b1a9f6f09f Mon Sep 17 00:00:00 2001 From: Rinne Date: Wed, 28 Feb 2024 01:46:34 +0800 Subject: [PATCH 2/5] feat: support complex type for rank op. --- .../tensorflow_common/src/op/rank.cpp | 16 ++--- .../tensorflow_tests/test_tf_Rank.py | 64 +++++++++---------- 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/rank.cpp b/src/frontends/tensorflow_common/src/op/rank.cpp index 85092d7ad0ba42..5919f54228c301 100644 --- a/src/frontends/tensorflow_common/src/op/rank.cpp +++ b/src/frontends/tensorflow_common/src/op/rank.cpp @@ -8,6 +8,7 @@ #include "openvino/op/shape_of.hpp" #include "openvino/op/squeeze.hpp" #include "openvino/util/log.hpp" +#include "utils.hpp" using namespace std; using namespace ov::op; @@ -18,28 +19,25 @@ namespace tensorflow { namespace op { ov::OutputVector translate_rank_op(const NodeContext &node) { - OPENVINO_DEBUG << "Translating Rank..............."; default_op_checks(node, 1, {"Rank"}, true); auto input = node.get_input(0); auto complex_type_mark = as_type_ptr(input.get_node_shared_ptr()); auto input_shape = make_shared(input, ov::element::i32); if (complex_type_mark) { - element::Type complex_part_type = - complex_type_mark->get_complex_part_type(); input = complex_type_mark->input_value(0); auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); - auto input_rank = make_shared(unsqueeze_input_rank); - input_rank = make_shared( - input_rank, + auto input_rank_with_complex = + make_shared(unsqueeze_input_rank); + // Squeeze again to eliminate the extra dimension + auto input_rank = make_shared( + input_rank_with_complex, make_shared(ov::element::i32, Shape{1}, input_shape->get_input_size() - 1)); set_node_name(node.get_name(), input_rank); - auto complex_rank = - make_shared(input_rank, complex_part_type); - return {complex_rank->output(0)}; + return {input_rank}; } auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); diff --git a/tests/layer_tests/tensorflow_tests/test_tf_Rank.py b/tests/layer_tests/tensorflow_tests/test_tf_Rank.py index 0d15b81c3d3e33..0a6ef2b08f6f57 100644 --- a/tests/layer_tests/tensorflow_tests/test_tf_Rank.py +++ b/tests/layer_tests/tensorflow_tests/test_tf_Rank.py @@ -7,38 +7,36 @@ from common.tf_layer_test_class import CommonTFLayerTest -# class TestRank(CommonTFLayerTest): -# def create_rank_net(self, input_shape, input_type): -# tf.compat.v1.reset_default_graph() -# # Create the graph and model -# with tf.compat.v1.Session() as sess: -# input = tf.compat.v1.placeholder(input_type, input_shape, 'input') -# tf.raw_ops.Rank(input=input) -# tf.compat.v1.global_variables_initializer() -# tf_net = sess.graph_def +class TestRank(CommonTFLayerTest): + def create_rank_net(self, input_shape, input_type): + tf.compat.v1.reset_default_graph() + # Create the graph and model + with tf.compat.v1.Session() as sess: + input = tf.compat.v1.placeholder(input_type, input_shape, 'input') + tf.raw_ops.Rank(input=input) + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph_def -# return tf_net, None + return tf_net, None -# test_data_basic = [ -# dict(input_shape=[], input_type=tf.float32), -# dict(input_shape=[1], input_type=tf.float32), -# dict(input_shape=[2, 6], input_type=tf.int32), -# dict(input_shape=[3, 4, 5, 6], input_type=tf.float32) -# ] + test_data_basic = [ + dict(input_shape=[], input_type=tf.float32), + dict(input_shape=[1], input_type=tf.float32), + dict(input_shape=[2, 6], input_type=tf.int32), + dict(input_shape=[3, 4, 5, 6], input_type=tf.float32) + ] -# @pytest.mark.parametrize("params", test_data_basic) -# @pytest.mark.precommit_tf_fe -# @pytest.mark.nightly -# def test_rank_basic(self, params, ie_device, precision, ir_version, temp_dir, -# use_legacy_frontend): -# self._test(*self.create_rank_net(**params), -# ie_device, precision, ir_version, temp_dir=temp_dir, -# use_legacy_frontend=use_legacy_frontend) + @pytest.mark.parametrize("params", test_data_basic) + @pytest.mark.precommit_tf_fe + @pytest.mark.nightly + def test_rank_basic(self, params, ie_device, precision, ir_version, temp_dir, + use_legacy_frontend): + self._test(*self.create_rank_net(**params), + ie_device, precision, ir_version, temp_dir=temp_dir, + use_legacy_frontend=use_legacy_frontend) class TestComplexRank(CommonTFLayerTest): def _prepare_input(self, inputs_info): - print(inputs_info) - raise NotImplementedError rng = np.random.default_rng() assert 'param_real:0' in inputs_info assert 'param_imag:0' in inputs_info @@ -53,22 +51,20 @@ def create_rank_net(self, input_shape): tf.compat.v1.reset_default_graph() # Create the graph and model with tf.compat.v1.Session() as sess: - input_real = tf.compat.v1.placeholder(np.float32, input_shape, 'param_real') - input_imag = tf.compat.v1.placeholder(np.float32, input_shape, 'param_imag') + input_real = tf.compat.v1.placeholder(tf.float32, input_shape, 'param_real') + input_imag = tf.compat.v1.placeholder(tf.float32, input_shape, 'param_imag') input = tf.raw_ops.Complex(real=input_real, imag=input_imag) - rank = tf.raw_ops.Rank(input=input) - # real = tf.raw_ops.Real(input=rank) - # imag = tf.raw_ops.Imag(input=rank) + tf.raw_ops.Rank(input=input) tf.compat.v1.global_variables_initializer() tf_net = sess.graph_def return tf_net, None test_data_basic = [ - # dict(input_shape=[]), - # dict(input_shape=[1]), + dict(input_shape=[]), + dict(input_shape=[1]), dict(input_shape=[2, 6]), - # dict(input_shape=[3, 4, 5, 6]) + dict(input_shape=[3, 4, 5, 6]) ] @pytest.mark.parametrize("params", test_data_basic) From b4750d944cfb95a073e67904bfae92bf954c00b3 Mon Sep 17 00:00:00 2001 From: Rinne Date: Fri, 1 Mar 2024 02:19:17 +0800 Subject: [PATCH 3/5] fix bug and resolve comments. --- .../tensorflow_common/src/op/rank.cpp | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/rank.cpp b/src/frontends/tensorflow_common/src/op/rank.cpp index 5919f54228c301..9bd94d130e140a 100644 --- a/src/frontends/tensorflow_common/src/op/rank.cpp +++ b/src/frontends/tensorflow_common/src/op/rank.cpp @@ -7,8 +7,7 @@ #include "openvino/op/constant.hpp" #include "openvino/op/shape_of.hpp" #include "openvino/op/squeeze.hpp" -#include "openvino/util/log.hpp" -#include "utils.hpp" +#include "openvino/op/subtract.hpp" using namespace std; using namespace ov::op; @@ -18,35 +17,30 @@ namespace frontend { namespace tensorflow { namespace op { -ov::OutputVector translate_rank_op(const NodeContext &node) { - default_op_checks(node, 1, {"Rank"}, true); - auto input = node.get_input(0); - auto complex_type_mark = - as_type_ptr(input.get_node_shared_ptr()); - auto input_shape = make_shared(input, ov::element::i32); - if (complex_type_mark) { - input = complex_type_mark->input_value(0); +ov::OutputVector translate_rank_op(const NodeContext& node) { + default_op_checks(node, 1, {"Rank"}, true); + auto input = node.get_input(0); + auto complex_type_mark = as_type_ptr(input.get_node_shared_ptr()); + if (complex_type_mark) { + input = complex_type_mark->input_value(0); + auto input_shape = make_shared(input, ov::element::i32); - auto unsqueeze_input_rank = - make_shared(input_shape, ov::element::i32); - auto input_rank_with_complex = - make_shared(unsqueeze_input_rank); - // Squeeze again to eliminate the extra dimension - auto input_rank = make_shared( - input_rank_with_complex, - make_shared(ov::element::i32, Shape{1}, - input_shape->get_input_size() - 1)); + auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); + auto input_rank_with_complex = make_shared(unsqueeze_input_rank); + // eliminate the extra dimension + auto input_rank = make_shared(input_rank_with_complex, + make_shared(ov::element::i32, Shape{1}, 1)); + set_node_name(node.get_name(), input_rank); + return {input_rank->output(0)}; + } + auto input_shape = make_shared(input, ov::element::i32); + auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); + auto input_rank = make_shared(unsqueeze_input_rank); set_node_name(node.get_name(), input_rank); return {input_rank}; - } - auto unsqueeze_input_rank = - make_shared(input_shape, ov::element::i32); - auto input_rank = make_shared(unsqueeze_input_rank); - set_node_name(node.get_name(), input_rank); - return {input_rank}; } -} // namespace op -} // namespace tensorflow -} // namespace frontend -} // namespace ov +} // namespace op +} // namespace tensorflow +} // namespace frontend +} // namespace ov From 3e8b93c75683d4f05a353aa11bc163802d94db7a Mon Sep 17 00:00:00 2001 From: Roman Kazantsev Date: Thu, 29 Feb 2024 23:39:45 +0400 Subject: [PATCH 4/5] Update src/frontends/tensorflow_common/src/op/rank.cpp --- src/frontends/tensorflow_common/src/op/rank.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/tensorflow_common/src/op/rank.cpp b/src/frontends/tensorflow_common/src/op/rank.cpp index 9bd94d130e140a..6f7b9860d132d4 100644 --- a/src/frontends/tensorflow_common/src/op/rank.cpp +++ b/src/frontends/tensorflow_common/src/op/rank.cpp @@ -29,7 +29,7 @@ ov::OutputVector translate_rank_op(const NodeContext& node) { auto input_rank_with_complex = make_shared(unsqueeze_input_rank); // eliminate the extra dimension auto input_rank = make_shared(input_rank_with_complex, - make_shared(ov::element::i32, Shape{1}, 1)); + make_shared(ov::element::i32, Shape{}, 1)); set_node_name(node.get_name(), input_rank); return {input_rank->output(0)}; } From a0e976e3b2a9d7d053152e94725e060d276f9dd8 Mon Sep 17 00:00:00 2001 From: Rinne Date: Fri, 1 Mar 2024 03:53:35 +0800 Subject: [PATCH 5/5] format the code. --- src/frontends/tensorflow_common/src/op/rank.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontends/tensorflow_common/src/op/rank.cpp b/src/frontends/tensorflow_common/src/op/rank.cpp index 6f7b9860d132d4..1adbcd43d2fc04 100644 --- a/src/frontends/tensorflow_common/src/op/rank.cpp +++ b/src/frontends/tensorflow_common/src/op/rank.cpp @@ -28,8 +28,8 @@ ov::OutputVector translate_rank_op(const NodeContext& node) { auto unsqueeze_input_rank = make_shared(input_shape, ov::element::i32); auto input_rank_with_complex = make_shared(unsqueeze_input_rank); // eliminate the extra dimension - auto input_rank = make_shared(input_rank_with_complex, - make_shared(ov::element::i32, Shape{}, 1)); + auto input_rank = + make_shared(input_rank_with_complex, make_shared(ov::element::i32, Shape{}, 1)); set_node_name(node.get_name(), input_rank); return {input_rank->output(0)}; }