Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TF FE] Support Angle operation for TensorFlow models #23028

Merged
merged 46 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
20f6df3
Create angle.cpp
rghvsh Feb 22, 2024
430af66
Merge branch 'openvinotoolkit:master' into tffe-angle
rghvsh Feb 22, 2024
4661cda
Create angle.cpp
rghvsh Feb 22, 2024
2483635
Update angle.cpp
rghvsh Feb 22, 2024
3dc3593
Update common_op_table.hpp
rghvsh Feb 22, 2024
695fb8e
Update op_table.cpp
rghvsh Feb 22, 2024
b88a94a
Create test_angle.py
rghvsh Feb 22, 2024
3293efe
Update and rename test_angle.py to test_tf_angle.py
rghvsh Feb 22, 2024
c33984d
Delete src/frontends/tensorflow/src/op/angle.cpp
rghvsh Feb 22, 2024
e89e1f9
Merge branch 'openvinotoolkit:master' into tffe-angle
rghvsh Feb 22, 2024
44fa398
Update angle.cpp
rghvsh Feb 22, 2024
bf10096
Update supported_ops.md
rghvsh Feb 22, 2024
28fcad9
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Feb 24, 2024
8f9caf1
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Feb 24, 2024
0a062ac
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Feb 24, 2024
42a2aee
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Feb 24, 2024
2063766
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Feb 24, 2024
d01db7c
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Feb 25, 2024
da7621d
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Feb 25, 2024
40f4b32
Update angle.cpp
rghvsh Feb 28, 2024
9fc48fd
Update test_tf_angle.py
rghvsh Feb 29, 2024
34accfe
Update angle.cpp
rghvsh Feb 29, 2024
7dae5d7
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
e21e8f7
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
4d41fcf
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
47f81e0
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
1f53a49
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
baf2e20
Update src/frontends/tensorflow_common/src/op/angle.cpp
rghvsh Mar 4, 2024
5d52e53
Update angle.cpp
rghvsh Mar 4, 2024
cb634ce
Update angle.cpp
rghvsh Mar 4, 2024
f59a789
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Mar 4, 2024
f3cdb25
Merge branch 'master' into tffe-angle
rkazants Mar 4, 2024
197407d
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Mar 4, 2024
6cb6400
Update angle.cpp
rghvsh Mar 5, 2024
2c51435
Update angle.cpp
rghvsh Mar 5, 2024
6d2c581
Update angle.cpp
rghvsh Mar 6, 2024
e864216
Update angle.cpp
rghvsh Mar 6, 2024
d5c4920
Apply suggestions from code review
rkazants Mar 6, 2024
58e5a72
Update angle.cpp
rghvsh Mar 23, 2024
370359b
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Mar 24, 2024
8552bf9
Merge branch 'master' into tffe-angle
rkazants Mar 24, 2024
1c22d7e
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Mar 24, 2024
32d910d
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Mar 24, 2024
8d24ef2
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Mar 24, 2024
a37e905
Update tests/layer_tests/tensorflow_tests/test_tf_angle.py
rkazants Mar 24, 2024
49b9240
Update src/frontends/tensorflow_common/src/op/angle.cpp
rkazants Mar 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/frontends/tensorflow/docs/supported_ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ A "supported operation" is one that TensorFlow Frontend can convert to the OpenV
| All | YES | |
| AllCandidateSampler | NO | |
| AllToAll | NO | |
| Angle | NO | |
| Angle | YES | |
| AnonymousHashTable | NO | |
| AnonymousIterator | NO | |
| AnonymousIteratorV2 | NO | |
Expand Down
1 change: 1 addition & 0 deletions src/frontends/tensorflow/src/op_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ const std::map<std::string, CreatorFunction> get_supported_ops() {
// Separate translators:
{"AddN", CreatorFunction(translate_add_n_op)},
{"AdjustContrastv2", CreatorFunction(translate_adjust_contrast_op)},
{"Angle", CreatorFunction(translate_angle_op)},
{"ArgMax", CreatorFunction(translate_arg_max_op)},
{"ArgMin", CreatorFunction(translate_arg_min_op)},
{"Assert", CreatorFunction(translate_no_op)},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ OP_CONVERTER(translate_addv2_op);
OP_CONVERTER(translate_add_n_op);
OP_CONVERTER(translate_approximate_equal_op);
OP_CONVERTER(translate_adjust_contrast_op);
OP_CONVERTER(translate_angle_op);
OP_CONVERTER(translate_arg_max_op);
OP_CONVERTER(translate_arg_min_op);
OP_CONVERTER(translate_atan2_op);
Expand Down
91 changes: 91 additions & 0 deletions src/frontends/tensorflow_common/src/op/angle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "common_op_table.hpp"
#include "helper_ops/complex_type_mark.hpp"
#include "openvino/op/add.hpp"
#include "openvino/op/atan.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/convert.hpp"
#include "openvino/op/divide.hpp"
#include "openvino/op/equal.hpp"
#include "openvino/op/gather.hpp"
#include "openvino/op/greater.hpp"
#include "openvino/op/greater_eq.hpp"
#include "openvino/op/less.hpp"
#include "openvino/op/logical_and.hpp"
#include "openvino/op/multiply.hpp"
#include "openvino/op/select.hpp"
#include "openvino/op/subtract.hpp"

using namespace std;
using namespace ov::op;

namespace ov {
namespace frontend {
namespace tensorflow {
namespace op {

OutputVector translate_angle_op(const NodeContext& node) {
default_op_checks(node, 2, {"Angle"}, true);
rkazants marked this conversation as resolved.
Show resolved Hide resolved
auto complex = node.get_input(0);
auto result_type = node.get_attribute<ov::element::Type>("Tout");

rkazants marked this conversation as resolved.
Show resolved Hide resolved
auto complex_type_mark = as_type_ptr<ComplexTypeMark>(complex.get_node_shared_ptr());

TENSORFLOW_OP_VALIDATION(
node,
complex_type_mark,
"[TensorFlow Frontend] inconsistent model: Angle operation expects complex type tensor on input");

element::Type complex_part_type = complex_type_mark->get_complex_part_type();
auto complex = complex_type_mark->input_value(0);
rkazants marked this conversation as resolved.
Show resolved Hide resolved
auto real_index = make_shared<v0::Constant>(element::i32, Shape{}, 0);
auto imag_index = make_shared<v0::Constant>(element::i32, Shape{}, 1);
auto gather_axis = make_shared<v0::Constant>(element::i32, Shape{1}, -1);

auto x = make_shared<v8::Gather>(complex, real_index, gather_axis)->output(0);
auto y = make_shared<v8::Gather>(complex, imag_index, gather_axis)->output(0);

rghvsh marked this conversation as resolved.
Show resolved Hide resolved
// handle the first condition : x>0
auto div_y_x = make_shared<v1::Divide>(y, x);
auto atan = make_shared<v0::Atan>(div_y_x);
auto const_zero = create_same_type_const_scalar<int32_t>(x, 0);
auto result = atan->output(0);

// handle the second condition : x<0 && y>=0
auto const_pi = create_same_type_const_scalar<double>(x, std::atan(1.0) * 4);
auto is_x_negative = make_shared<v1::Less>(x, const_zero);
auto y_non_negative = make_shared<v1::GreaterEqual>(y, const_zero);
auto cond1 = make_shared<v1::LogicalAnd>(is_x_negative, y_non_negative);
auto atan_y_x_plus_pi = make_shared<v1::Add>(atan, const_pi);
result = make_shared<v1::Select>(cond1, atan_y_x_plus_pi, result);

// handle the third condition : x<0 && y<0
auto is_y_negative = make_shared<v1::Less>(y, const_zero);
auto cond2 = make_shared<v1::LogicalAnd>(is_x_negative, is_y_negative);
auto atan_y_x_minus_pi = make_shared<v1::Subtract>(atan, const_pi);
result = make_shared<v1::Select>(cond2, atan_y_x_minus_pi, result);

// handle the fourth condition : x=0 && y>0
auto is_x_zero = make_shared<v1::Equal>(x, const_zero);
auto is_y_positive = make_shared<v1::Greater>(y, const_zero);
auto cond3 = make_shared<v1::LogicalAnd>(is_x_zero, is_y_positive);
auto const_two = create_same_type_const_scalar<int32_t>(x, 2);
auto pi_div_two = make_shared<v1::Divide>(const_pi, const_two);
result = make_shared<v1::Select>(cond3, pi_div_two, result);

// handle the fifth condition : x=0 && y<0
auto cond4 = make_shared<v1::LogicalAnd>(is_x_zero, is_y_negative);
auto const_minus_two = create_same_type_const_scalar<int32_t>(x, -2);
auto pi_div_minus_two = make_shared<v1::Divide>(const_pi, const_minus_two);
result = make_shared<v1::Select>(cond4, pi_div_two, result);
auto result_changed_type = make_shared<v0::Convert>(result, result_type);
rkazants marked this conversation as resolved.
Show resolved Hide resolved

set_node_name(node.get_name(), result_changed_type.get_node_shared_ptr());
return {result_changed_type};
}
} // namespace op
} // namespace tensorflow
} // namespace frontend
} // namespace ov
47 changes: 47 additions & 0 deletions tests/layer_tests/tensorflow_tests/test_tf_angle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (C) 2018-2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

import numpy as np
import pytest
import tensorflow as tf
from common.tf_layer_test_class import CommonTFLayerTest


class TestAngle(CommonTFLayerTest):
def _prepare_input(self, inputs_info):
assert 'y:0' in inputs_info
assert 'x:0' in inputs_info
y_shape = inputs_info['y:0']
x_shape = inputs_info['x:0']
inputs_data = {}
inputs_data['y:0'] = np.random.rand(*y_shape).astype(self.input_type) - np.random.rand(*y_shape).astype(self.input_type)
inputs_data['x:0'] = np.random.rand(*x_shape).astype(self.input_type) - np.random.rand(*x_shape).astype(self.input_type)
return inputs_data

def create_angle_net(self, input_shape, input_type):
self.input_type = input_type
tf.compat.v1.reset_default_graph()
# Create the graph and model
with tf.compat.v1.Session() as sess:
y = tf.compat.v1.placeholder(input_type, input_shape, 'y')
x = tf.compat.v1.placeholder(input_type, input_shape, 'x')
complex = tf.raw_ops.complex(real = x,imag =y)
tf.raw_ops.Angle(input = x)
rkazants marked this conversation as resolved.
Show resolved Hide resolved
tf.compat.v1.global_variables_initializer()
tf_net = sess.graph_def

return tf_net, None

test_data_basic = [
dict(input_shape=[1, 2], input_type=np.float32),
dict(input_shape=[2, 3, 4], input_type=np.float32),
]

@pytest.mark.parametrize("params", test_data_basic)
@pytest.mark.precommit_tf_fe
@pytest.mark.nightly
def test_angle(self, params, ie_device, precision, ir_version, temp_dir,
use_new_frontend, use_old_api):
self._test(*self.create_angle_net(**params),
ie_device, precision, ir_version, temp_dir=temp_dir,
use_new_frontend=use_new_frontend, use_old_api=use_old_api)
rkazants marked this conversation as resolved.
Show resolved Hide resolved
Loading