[TF FE] Avoid usage of NGraph routines (#17709)

* [TF FE] Avoid usage of NGraph routines

Also, it introduces separate test fixture with graph comparison
for FEs

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>

* Specify tickets for TODOs

---------

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>
This commit is contained in:
Roman Kazantsev 2023-05-24 20:42:41 +03:00 committed by GitHub
parent 5edc5e7010
commit 3925abfb19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 106 additions and 47 deletions

View File

@ -5,7 +5,6 @@
#include "helper_ops/block_lstm.hpp"
#include "common_op_table.hpp"
#include "ngraph/validation_util.hpp"
#include "openvino/core/validation_util.hpp"
#include "openvino/frontend/tensorflow/node_context.hpp"

View File

@ -5,14 +5,12 @@
#include "common_op_table.hpp"
#include "helper_ops/sparse_fill_empty_rows.hpp"
#include "helper_ops/sparse_segment_ops.hpp"
#include "ngraph/validation_util.hpp"
#include "openvino/core/validation_util.hpp"
#include "openvino/frontend/tensorflow/node_context.hpp"
#include "openvino/opsets/opset8.hpp"
using namespace std;
using namespace ov::opset8;
using namespace ngraph;
namespace ov {
namespace frontend {

View File

@ -6,7 +6,6 @@
#include "tf_utils.hpp"
using namespace ngraph;
using namespace ov::frontend;
using namespace ov::frontend::tensorflow::tests;

View File

@ -6,7 +6,6 @@
#include "tf_utils.hpp"
using namespace ngraph;
using namespace ov::frontend;
using namespace ov::frontend::tensorflow::tests;

View File

@ -4,7 +4,7 @@
#include <openvino/opsets/opset10.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
#include "conversion_with_reference.hpp"
#include "gtest/gtest.h"
#include "test_common.hpp"
#include "tf_utils.hpp"
@ -14,7 +14,7 @@ using namespace ov;
using namespace ov::opset10;
using namespace ov::frontend::tensorflow::tests;
TEST_F(TransformationTestsF, SavedModelProgramOnly) {
TEST_F(FrontEndConversionWithReferenceTestsF, SavedModelProgramOnly) {
{
model = convert_model("saved_model_program-only");
@ -40,7 +40,7 @@ TEST_F(TransformationTestsF, SavedModelProgramOnly) {
}
}
TEST_F(TransformationTestsF, SavedModelVariables) {
TEST_F(FrontEndConversionWithReferenceTestsF, SavedModelVariables) {
{ model = convert_model("saved_model_variables"); }
{
// create a reference graph
@ -52,7 +52,7 @@ TEST_F(TransformationTestsF, SavedModelVariables) {
}
}
TEST_F(TransformationTestsF, SavedModelWithInputIntegerType) {
TEST_F(FrontEndConversionWithReferenceTestsF, SavedModelWithInputIntegerType) {
{
model = convert_model("saved_model_with_gather",
nullptr,
@ -89,7 +89,7 @@ TEST_F(TransformationTestsF, SavedModelWithInputIntegerType) {
}
}
TEST_F(TransformationTestsF, SavedModelMultipleTensorNames) {
TEST_F(FrontEndConversionWithReferenceTestsF, SavedModelMultipleTensorNames) {
// The test aims to check tensor names of input and output tensors
// it checks that TF FE preserved user specific names for input and output tensor
// and exclude internal names

View File

@ -8,7 +8,7 @@
#include <openvino/opsets/opset10.hpp>
#include <transformations/common_optimizations/moc_transformations.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
#include "conversion_with_reference.hpp"
#include "gtest/gtest.h"
#include "test_common.hpp"
#include "tf_utils.hpp"
@ -107,7 +107,7 @@ TEST(FrontEndConvertTrickyModels, model_with_output_shapes) {
}
}
TEST_F(TransformationTestsF, AssertAndStringTensors) {
TEST_F(FrontEndConversionWithReferenceTestsF, AssertAndStringTensors) {
{
model = convert_model("string_tensors_model/string_tensors_model.pbtxt");
// TODO: investigate - why we have redundant nodes after the conversion
@ -123,12 +123,12 @@ TEST_F(TransformationTestsF, AssertAndStringTensors) {
}
}
TEST_F(TransformationTestsF, UnsortedNodes) {
TEST_F(FrontEndConversionWithReferenceTestsF, UnsortedNodes) {
{ model = convert_model("forward_edge_model_unsorted/forward_edge_model_unsorted.pbtxt"); }
{ model_ref = convert_model("forward_edge_model/forward_edge_model.pbtxt"); }
}
TEST_F(TransformationTestsF, ModelWithSwishF32BodyGraph) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithSwishF32BodyGraph) {
{
model = convert_model("swish_f32/swish_f32.pbtxt");
// need to call shape inference since body graphs can be injected with undefined shapes
@ -146,7 +146,7 @@ TEST_F(TransformationTestsF, ModelWithSwishF32BodyGraph) {
}
}
TEST_F(TransformationTestsF, PartitionedCall) {
TEST_F(FrontEndConversionWithReferenceTestsF, PartitionedCall) {
{
model = convert_model("partitioned_call/partitioned_call.pbtxt");
// need to call shape inference since body graphs can be injected with undefined shapes
@ -163,7 +163,7 @@ TEST_F(TransformationTestsF, PartitionedCall) {
}
}
TEST_F(TransformationTestsF, ModelWithIf) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithIf) {
{ model = convert_model("model_with_if/model_with_if.pbtxt"); }
{
// create then branch body graph
@ -196,7 +196,7 @@ TEST_F(TransformationTestsF, ModelWithIf) {
}
}
TEST_F(TransformationTestsF, InjectedBodyAndIf) {
TEST_F(FrontEndConversionWithReferenceTestsF, InjectedBodyAndIf) {
{
model = convert_model("injected_body_and_if/injected_body_and_if.pbtxt");
// need to call shape inference since body graphs can be injected with undefined shapes
@ -235,11 +235,15 @@ TEST_F(TransformationTestsF, InjectedBodyAndIf) {
}
}
TEST_F(TransformationTestsF, ModelWithDilatedGroupConvolution) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithDilatedGroupConvolution) {
{
model = convert_model("dilated_gconv_model/dilated_gconv_model.pbtxt");
// need to call MOC to fuse BatchToSpace/SpaceToBatch with GroupConvolution
manager.register_pass<pass::MOCTransformations>(false);
// TODO: enable ATTRIBUTES, CONST_VALUES and ACCURACY checks, CVS-111900
comparator.disable(FunctionsComparator::CmpValues::ATTRIBUTES);
comparator.disable(FunctionsComparator::CmpValues::CONST_VALUES);
comparator.disable(FunctionsComparator::CmpValues::ACCURACY);
}
{
auto x = make_shared<Parameter>(f32, Shape{1, 129, 257, 384});
@ -259,7 +263,7 @@ TEST_F(TransformationTestsF, ModelWithDilatedGroupConvolution) {
}
}
TEST_F(TransformationTestsF, ModelWithSaveV2) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithSaveV2) {
{
model = convert_model("model_savev2/model_savev2.pbtxt");
// need to call shape inference since body graphs can be injected with undefined shapes
@ -275,7 +279,7 @@ TEST_F(TransformationTestsF, ModelWithSaveV2) {
}
}
TEST_F(TransformationTestsF, ModelWithConstResultSubgraphs) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithConstResultSubgraphs) {
{ model = convert_model("model_with_const_result/model_with_const_result.pbtxt"); }
{
// create a reference graph
@ -298,7 +302,7 @@ TEST_F(TransformationTestsF, ModelWithConstResultSubgraphs) {
}
}
TEST_F(TransformationTestsF, ModelWithIteratorGetNext) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithIteratorGetNext) {
{ model = convert_model("model_with_iterator_get_next/model_with_iterator_get_next.pbtxt"); }
{
// create a reference graph
@ -310,7 +314,7 @@ TEST_F(TransformationTestsF, ModelWithIteratorGetNext) {
}
}
TEST_F(TransformationTestsF, ModelWithQueueOperations) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithQueueOperations) {
{ model = convert_model("model_with_queue_ops/model_with_queue_ops.pbtxt"); }
{
// create a reference graph
@ -322,7 +326,7 @@ TEST_F(TransformationTestsF, ModelWithQueueOperations) {
}
}
TEST_F(TransformationTestsF, ModelWithQueueOperations2) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithQueueOperations2) {
{ model = convert_model("model_with_queue_ops2/model_with_queue_ops2.pbtxt"); }
{
// create a reference graph
@ -336,7 +340,7 @@ TEST_F(TransformationTestsF, ModelWithQueueOperations2) {
}
}
TEST_F(TransformationTestsF, ModelWithLookupTableOperations) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithLookupTableOperations) {
{ model = convert_model("model_with_lookup_table/model_with_lookup_table.pbtxt"); }
{
// create a reference graph
@ -348,7 +352,7 @@ TEST_F(TransformationTestsF, ModelWithLookupTableOperations) {
}
}
TEST_F(TransformationTestsF, ModelWithIteratorGetNextAndUnsupportedOp) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithIteratorGetNextAndUnsupportedOp) {
{ model = convert_model("unsupported_op_itergetnext/unsupported_op_itergetnext.pb"); }
{
// create then branch body graph
@ -360,8 +364,12 @@ TEST_F(TransformationTestsF, ModelWithIteratorGetNextAndUnsupportedOp) {
}
}
TEST_F(TransformationTestsF, ModelWithMultioutputBodyGraphNode) {
{ model = convert_model("partitioned_call2/partitioned_call2.pbtxt"); }
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithMultioutputBodyGraphNode) {
{
model = convert_model("partitioned_call2/partitioned_call2.pbtxt");
// TODO: enable ATTRIBUTES check, CVS-111901
comparator.disable(FunctionsComparator::CmpValues::ATTRIBUTES);
}
{
auto x = make_shared<Parameter>(i32, Shape{5});
auto y = make_shared<Parameter>(i32, Shape{5});
@ -375,7 +383,7 @@ TEST_F(TransformationTestsF, ModelWithMultioutputBodyGraphNode) {
}
}
TEST_F(TransformationTestsF, ModelWithEmptyTensorListAndPushBack) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithEmptyTensorListAndPushBack) {
{ model = convert_model("empty_tensor_list/empty_tensor_list.pb"); }
{
auto x = make_shared<Parameter>(f32, Shape{2, 3, 5});
@ -397,7 +405,7 @@ TEST_F(TransformationTestsF, ModelWithEmptyTensorListAndPushBack) {
}
}
TEST_F(TransformationTestsF, ModelWithAssertNode) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithAssertNode) {
{ model = convert_model("model_with_assert/model_with_assert.pb"); }
{
auto x = make_shared<Parameter>(i32, PartialShape{Dimension::dynamic()});
@ -407,7 +415,7 @@ TEST_F(TransformationTestsF, ModelWithAssertNode) {
}
}
TEST_F(TransformationTestsF, PartitionedCallWithUnique) {
TEST_F(FrontEndConversionWithReferenceTestsF, PartitionedCallWithUnique) {
// This test aims to test named output ports for Unique operation
{ model = convert_model("partitioned_call_with_unique/partitioned_call_with_unique.pb"); }
{
@ -421,7 +429,7 @@ TEST_F(TransformationTestsF, PartitionedCallWithUnique) {
}
}
TEST_F(TransformationTestsF, RaggedTensorToSparse) {
TEST_F(FrontEndConversionWithReferenceTestsF, RaggedTensorToSparse) {
// This test aims to test named output ports for RaggedTensorToSparse operation
// also, it tests propagation of custom type (specified in the extension) to Parameter node in the parent graph
{
@ -451,7 +459,7 @@ TEST_F(TransformationTestsF, RaggedTensorToSparse) {
}
}
TEST_F(TransformationTestsF, MetaGraphVariables) {
TEST_F(FrontEndConversionWithReferenceTestsF, MetaGraphVariables) {
{
model = convert_model("metagraph_variables/graph.meta");
model->validate_nodes_and_infer_types();
@ -468,7 +476,7 @@ TEST_F(TransformationTestsF, MetaGraphVariables) {
}
}
TEST_F(TransformationTestsF, MetaGraphCut) {
TEST_F(FrontEndConversionWithReferenceTestsF, MetaGraphCut) {
{
model = convert_model("metagraph_variables/graph.meta", nullptr, {"y"});
model->validate_nodes_and_infer_types();
@ -485,7 +493,7 @@ TEST_F(TransformationTestsF, MetaGraphCut) {
}
}
TEST_F(TransformationTestsF, MetaGraphCutInputTensor) {
TEST_F(FrontEndConversionWithReferenceTestsF, MetaGraphCutInputTensor) {
{
model = convert_model("metagraph_variables/graph.meta",
nullptr,
@ -504,7 +512,7 @@ TEST_F(TransformationTestsF, MetaGraphCutInputTensor) {
}
}
TEST_F(TransformationTestsF, MetaGraphCutOutputTensor) {
TEST_F(FrontEndConversionWithReferenceTestsF, MetaGraphCutOutputTensor) {
{
model = convert_model("metagraph_variables/graph.meta",
nullptr,
@ -523,7 +531,7 @@ TEST_F(TransformationTestsF, MetaGraphCutOutputTensor) {
}
}
TEST_F(TransformationTestsF, MetaGraphCutIdentity) {
TEST_F(FrontEndConversionWithReferenceTestsF, MetaGraphCutIdentity) {
{
model = convert_model("metagraph_variables/graph.meta",
nullptr,
@ -542,7 +550,7 @@ TEST_F(TransformationTestsF, MetaGraphCutIdentity) {
}
}
TEST_F(TransformationTestsF, SplitInFunction) {
TEST_F(FrontEndConversionWithReferenceTestsF, SplitInFunction) {
{
// create FAKE conversion extension for Split using named ports, this is not required for Split, but it tests
// how named ports will work if there is one name and many outputs associated with it
@ -572,7 +580,7 @@ TEST_F(TransformationTestsF, SplitInFunction) {
}
}
TEST_F(TransformationTestsF, ResourceGatherModel) {
TEST_F(FrontEndConversionWithReferenceTestsF, ResourceGatherModel) {
// This test aims to check basic support of ResourceGather operation
// and cutting an input model with specified shapes and types
{
@ -600,7 +608,7 @@ TEST_F(TransformationTestsF, ResourceGatherModel) {
}
}
TEST_F(TransformationTestsF, NonMaxSuppressionWithNamedOutputs) {
TEST_F(FrontEndConversionWithReferenceTestsF, NonMaxSuppressionWithNamedOutputs) {
// The purpose of this test is to check that named output ports of TensorFlow NMS operation are connected correctly
// to its consumers
{ model = convert_model("nms_named_outputs/nms_named_outputs.pb"); }
@ -668,7 +676,7 @@ TEST_F(TransformationTestsF, NonMaxSuppressionWithNamedOutputs) {
}
}
TEST_F(TransformationTestsF, PartitionedCallsWithConvInBodyGraphs) {
TEST_F(FrontEndConversionWithReferenceTestsF, PartitionedCallsWithConvInBodyGraphs) {
// The test aims to check that the conversion for the body graphs is performed with set input shapes
// that allows to get more optimized ov::Model for the body graphs.
// In particular, we check that the resulted graph contains Convolution operations instead of GroupConvolution

View File

@ -11,7 +11,7 @@
#include <openvino/op/util/framework_node.hpp>
#include <openvino/opsets/opset10.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
#include "conversion_with_reference.hpp"
#include "tf_framework_node.hpp"
#include "tf_utils.hpp"
#include "utils.hpp"
@ -142,7 +142,7 @@ TEST(FrontEndConvertModelTest, test_unsupported_tf1_while) {
}
}
TEST_F(TransformationTestsF, ModelWithDynamicType) {
TEST_F(FrontEndConversionWithReferenceTestsF, ModelWithDynamicType) {
{ model = convert_model_partially("dynamic_type_model/dynamic_type_model.pb"); }
{
auto x = make_shared<Parameter>(f32, Shape{2, 3});

View File

@ -79,16 +79,16 @@ TEST(TFTelemetryTest, test_nonexistent_add) {
string("nonexistent_add/nonexistent_add.pb"));
ASSERT_NO_THROW(inputModel = frontEnd->load(model_filename));
ASSERT_NE(inputModel, nullptr);
shared_ptr<ngraph::Function> function;
shared_ptr<ov::Model> model;
try {
function = frontEnd->convert(inputModel);
model = frontEnd->convert(inputModel);
FAIL() << "Non-existent operation Adddd must not be supported by TF FE.";
} catch (const OpConversionFailure& error) {
string error_message = error.what();
string ref_message = "Internal error, no translator found for operation(s): Adddd";
ASSERT_TRUE(error_message.find(ref_message) != string::npos);
ASSERT_EQ(function, nullptr);
ASSERT_EQ(model, nullptr);
// check telemetry data
EXPECT_EQ(m_test_telemetry.m_error_cnt, 0);

View File

@ -8,7 +8,6 @@
#include <vector>
#include "helper_ops/block_lstm.hpp"
#include "ngraph/rt_info.hpp"
#include "openvino/opsets/opset9.hpp"
#include "openvino/pass/pattern/matcher.hpp"
#include "openvino/pass/pattern/op/or.hpp"

View File

@ -8,7 +8,6 @@
#include <vector>
#include "helper_ops/gru_block_cell.hpp"
#include "ngraph/rt_info.hpp"
#include "openvino/opsets/opset9.hpp"
#include "openvino/pass/pattern/matcher.hpp"
#include "openvino/pass/pattern/op/or.hpp"

View File

@ -0,0 +1,25 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <gtest/gtest.h>
#include "common_test_utils/graph_comparator.hpp"
#include "openvino/core/model.hpp"
#include "openvino/pass/manager.hpp"
// test fixture to check that the resulted graph generated by the frontend matches the reference
class FrontEndConversionWithReferenceTestsF : virtual public ::testing::Test {
public:
FrontEndConversionWithReferenceTestsF();
void SetUp() override;
void TearDown() override;
std::shared_ptr<ov::Model> model, model_ref;
ov::pass::Manager manager;
FunctionsComparator comparator;
};

View File

@ -0,0 +1,33 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "conversion_with_reference.hpp"
#include "transformations/init_node_info.hpp"
FrontEndConversionWithReferenceTestsF::FrontEndConversionWithReferenceTestsF()
: comparator(FunctionsComparator::no_default()) {
comparator.enable(FunctionsComparator::CmpValues::NODES);
comparator.enable(FunctionsComparator::CmpValues::PRECISIONS);
comparator.enable(FunctionsComparator::CmpValues::RUNTIME_KEYS);
comparator.enable(FunctionsComparator::CmpValues::SUBGRAPH_DESCRIPTORS);
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
comparator.enable(FunctionsComparator::CmpValues::ACCURACY);
}
void FrontEndConversionWithReferenceTestsF::SetUp() {
manager.register_pass<ov::pass::InitNodeInfo>();
}
void FrontEndConversionWithReferenceTestsF::TearDown() {
OPENVINO_ASSERT(model != nullptr, "Test Model is not initialized.");
OPENVINO_ASSERT(model_ref != nullptr, "Reference Test Model is not initialized.");
manager.run_passes(model);
ASSERT_NO_THROW(check_rt_info(model));
auto res = comparator.compare(model, model_ref);
ASSERT_TRUE(res.valid) << res.message;
}