[TF FE] Support ToBool operation (#20511)

* [TF FE][TF Hub] Support ToBool operations

* [TF FE][TF Hub] Support ToBool operations

* fixing select operation Support ToBool operations for TF Hub models

* added false and true const for tobool operations

* added reduction axes

* Apply suggestions from code review

* Update tests/layer_tests/tensorflow_tests/test_tf_ToBool.py

* Update tests/layer_tests/tensorflow_tests/test_tf_ToBool.py

* Update tests/layer_tests/tensorflow_tests/test_tf_ToBool.py

* Update src/frontends/tensorflow_common/src/op/tobool.cpp

* added second zero constant

* added correct types  src\frontends\tensorflow_common\src\op\tobool.cpp

* added includes src\frontends\tensorflow_common\src\op\tobool.cpp

* Update src/frontends/tensorflow_common/src/op/tobool.cpp

* remove select and not_equal src/frontends/tensorflow_common/src/op/tobool.cpp

* Apply suggestions from code review

* Update src/frontends/tensorflow_common/src/op/tobool.cpp

* Apply suggestions from code review

* Update src/frontends/tensorflow_common/src/op/tobool.cpp

---------

Co-authored-by: Roman Kazantsev <roman.kazantsev@intel.com>
This commit is contained in:
rsato10 2023-10-20 03:22:30 -07:00 committed by GitHub
parent 2b8827abd0
commit 9edbcb1d4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 0 deletions

View File

@ -278,6 +278,7 @@ const std::map<std::string, CreatorFunction> get_supported_ops() {
{"TensorListReserve", CreatorFunction(translate_tensor_list_reserve_op)},
{"TensorListResize", CreatorFunction(translate_tensor_list_resize_op)},
{"Tile", CreatorFunction(translate_tile_op)},
{"ToBool", CreatorFunction(translate_tobool_op)},
{"TopK", CreatorFunction(translate_top_k_op)},
{"TopKV2", CreatorFunction(translate_top_k_v2_op)},
{"Transpose", CreatorFunction(translate_transpose_op)},

View File

@ -142,6 +142,7 @@ OP_CONVERTER(translate_tensor_list_set_item_op);
OP_CONVERTER(translate_tensor_list_stack_op);
OP_CONVERTER(translate_tensor_list_resize_op);
OP_CONVERTER(translate_tile_op);
OP_CONVERTER(translate_tobool_op);
OP_CONVERTER_NAMED(translate_top_k_op);
OP_CONVERTER_NAMED(translate_top_k_v2_op);
OP_CONVERTER(translate_transpose_op);

View File

@ -0,0 +1,68 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "common_op_table.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/equal.hpp"
#include "openvino/op/greater.hpp"
#include "openvino/op/logical_and.hpp"
#include "openvino/op/logical_or.hpp"
#include "openvino/op/not_equal.hpp"
#include "openvino/op/reduce_prod.hpp"
#include "openvino/op/select.hpp"
#include "openvino/op/shape_of.hpp"
using namespace std;
using namespace ov::op;
namespace ov {
namespace frontend {
namespace tensorflow {
namespace op {
OutputVector translate_tobool_op(const NodeContext& node) {
// (rank(x) == 0 && x != 0) || (rank > 0 && ReduceProd(ShapeOf(x))) > 0
default_op_checks(node, 1, {"ToBool"});
auto x = node.get_input(0);
// prepare auxiliary zero and zero constants of the same type as the inputs
auto zero = create_same_type_const_scalar<int32_t>(x, 0);
auto zero_2 = make_shared<v0::Constant>(element::i32, Shape{}, 0);
auto true_const = make_shared<v0::Constant>(element::boolean, Shape{}, true);
auto false_const = make_shared<v0::Constant>(element::boolean, Shape{}, false);
// compute a mask to get rank(x) == 0
auto x_rank = compute_subgraph_scalar_rank(x, element::i32);
// compute rank(x) == 0
auto is_zero = make_shared<v1::Equal>(x_rank, zero_2);
// compute mask to get x != 0
auto is_not_zero = make_shared<v1::NotEqual>(x, zero);
// compute (rank(x) == 0 && x != 0)
auto logical_and = make_shared<v1::LogicalAnd>(is_zero, is_not_zero);
// compute rank(x) > 0
auto greater_than_zero = make_shared<v1::Greater>(x_rank, zero_2);
// compute ShapeOf(x)
auto cond_shape = make_shared<v3::ShapeOf>(x, element::i32);
// compute ReduceProd(ShapeOf(x))) and axis
auto axis = make_shared<v0::Constant>(element::i32, Shape{}, 0);
auto reduce_prod = make_shared<v1::ReduceProd>(cond_shape, axis);
// compute ReduceProd(ShapeOf(x))) > 0
auto greater_than__zero_2 = make_shared<v1::Greater>(reduce_prod, zero_2);
// compute (rank > 0 && ReduceProd(ShapeOf(x))) > 0
auto logical_and_2 = make_shared<v1::LogicalAnd>(greater_than_zero, greater_than__zero_2);
auto logical_or = make_shared<v1::LogicalOr>(logical_and, logical_and_2);
auto tobool = make_shared<v1::Select>(logical_or, true_const, false_const);
set_node_name(node.get_name(), tobool);
return tobool->outputs();
}
} // namespace op
} // namespace tensorflow
} // namespace frontend
} // namespace ov

View File

@ -0,0 +1,43 @@
# Copyright (C) 2018-2023 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 TestToBool(CommonTFLayerTest):
def _prepare_input(self, inputs_info):
assert 'x' in inputs_info
x_shape = inputs_info['x']
inputs_data = {}
inputs_data['x'] = np.random.randint(-10, 10, x_shape).astype(np.float32)
return inputs_data
def create_tobool_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:
x = tf.compat.v1.placeholder(input_type, input_shape, 'x')
tf.raw_ops.ToBool(input=x)
tf.compat.v1.global_variables_initializer()
tf_net = sess.graph_def
return tf_net, None
test_data_basic = [
dict(input_shape=[10, 20], 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_to_bool_basic(self, params, ie_device, precision, ir_version, temp_dir,
use_new_frontend, use_old_api):
self._test(*self.create_tobool_net(**params),
ie_device, precision, ir_version, temp_dir=temp_dir,
use_new_frontend=use_new_frontend, use_old_api=use_old_api)