[Transformation] transform ConvertLike into Convert when applicable (#7543)

* [Transformation] transform ConvertLike into Convert when applicable

Signed-off-by: Li, Tingqian <tingqian.li@intel.com>

* Remove xfail markup for onnx castlike cpu tests

Signed-off-by: Li, Tingqian <tingqian.li@intel.com>

* remove un-used xfail

Signed-off-by: Li, Tingqian <tingqian.li@intel.com>

* Enable ConvertLike cpu functional test

Signed-off-by: Li, Tingqian <tingqian.li@intel.com>

* remove unnecessary headers

* move to common transformation

Signed-off-by: Li, Tingqian <tingqian.li@intel.com>

* remove test

* fix pytest CI issue

* minor fix after rebase

* fix clang format check

* fix failed tests
This commit is contained in:
Tingqian Li 2022-07-05 15:50:35 +08:00 committed by GitHub
parent 8c152405ad
commit 3e97d12fe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 173 additions and 135 deletions

View File

@ -120,7 +120,6 @@ xfail_issue_63043 = xfail_test(reason="Recurrent node expects constants as W, R,
xfail_issue_63044 = xfail_test(reason="ONNX opset 14 operation: Trilu")
skip_rng_tests = pytest.mark.skip(reason="Tests use random number generator with no seed.")
xfail_issue_63136 = xfail_test(reason="Unsupported operation: CastLike")
xfail_issue_63137 = xfail_test(reason="Unsupported operations: OptionalHasElement, OptionalGetElement")
xfail_issue_63138 = xfail_test(reason="Missing ONNX Shape-15 support")
xfail_issue_68212 = xfail_test(reason="Unsupported reading model with bytes streams")

View File

@ -41,7 +41,6 @@ from tests import (
xfail_issue_63039,
xfail_issue_63043,
xfail_issue_63044,
xfail_issue_63136,
xfail_issue_63137,
xfail_issue_63138,
xfail_issue_69444,
@ -327,17 +326,6 @@ tests_expected_to_fail = [
"OnnxBackendNodeModelTest.test_bernoulli_seed_cpu",
"OnnxBackendNodeModelTest.test_bernoulli_seed_expanded_cpu",
),
(
xfail_issue_63136,
"OnnxBackendNodeModelTest.test_castlike_BFLOAT16_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_DOUBLE_to_FLOAT16_cpu",
"OnnxBackendNodeModelTest.test_castlike_DOUBLE_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT16_to_DOUBLE_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT16_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_BFLOAT16_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_DOUBLE_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_FLOAT16_cpu",
),
(
xfail_issue_63137,
"OnnxBackendNodeModelTest.test_optional_get_element_cpu",

View File

@ -130,7 +130,6 @@ xfail_issue_63043 = xfail_test(reason="Recurrent node expects constants as W, R,
xfail_issue_63044 = xfail_test(reason="ONNX opset 14 operation: Trilu")
skip_rng_tests = pytest.mark.skip(reason="Tests use random number generator with no seed.")
xfail_issue_63136 = xfail_test(reason="Unsupported operation: CastLike")
xfail_issue_63137 = xfail_test(reason="Unsupported operations: OptionalHasElement, OptionalGetElement")
xfail_issue_63138 = xfail_test(reason="Missing ONNX Shape-15 support")

View File

@ -40,7 +40,6 @@ from tests_compatibility import (
xfail_issue_63039,
xfail_issue_63043,
xfail_issue_63044,
xfail_issue_63136,
xfail_issue_63137,
xfail_issue_63138,
xfail_issue_69444,
@ -326,17 +325,6 @@ tests_expected_to_fail = [
"OnnxBackendNodeModelTest.test_bernoulli_seed_cpu",
"OnnxBackendNodeModelTest.test_bernoulli_seed_expanded_cpu",
),
(
xfail_issue_63136,
"OnnxBackendNodeModelTest.test_castlike_BFLOAT16_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_DOUBLE_to_FLOAT16_cpu",
"OnnxBackendNodeModelTest.test_castlike_DOUBLE_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT16_to_DOUBLE_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT16_to_FLOAT_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_BFLOAT16_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_DOUBLE_cpu",
"OnnxBackendNodeModelTest.test_castlike_FLOAT_to_FLOAT16_cpu",
),
(
xfail_issue_63137,
"OnnxBackendNodeModelTest.test_optional_get_element_cpu",

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <ngraph/pass/graph_rewrite.hpp>
#include <transformations_visibility.hpp>
namespace ngraph {
namespace pass {
class TRANSFORMATIONS_API ConvertConvertLike;
} // namespace pass
} // namespace ngraph
class ngraph::pass::ConvertConvertLike : public ngraph::pass::MatcherPass {
public:
NGRAPH_RTTI_DECLARATION;
ConvertConvertLike();
};

View File

@ -69,6 +69,7 @@
#include "transformations/op_conversions/batch_norm_decomposition.hpp"
#include "transformations/op_conversions/bidirectional_sequences_decomposition.hpp"
#include "transformations/op_conversions/convert_broadcast_to_tiles.hpp"
#include "transformations/op_conversions/convert_convertlike.hpp"
#include "transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp"
#include "transformations/op_conversions/convert_depth_to_space.hpp"
#include "transformations/op_conversions/convert_divide.hpp"
@ -154,6 +155,7 @@ bool ngraph::pass::CommonOptimizations::run_on_model(const std::shared_ptr<ngrap
decomp->add_matcher<ngraph::pass::ConvertDivide>();
decomp->add_matcher<ngraph::pass::ConvertDepthToSpace>();
decomp->add_matcher<ngraph::pass::ConvertSpaceToDepth>();
decomp->add_matcher<ngraph::pass::ConvertConvertLike>();
decomp->add_matcher<ngraph::pass::BatchNormDecomposition>();
decomp->add_matcher<ngraph::pass::MVN6Decomposition>();
decomp->add_matcher<ngraph::pass::NormalizeL2Decomposition, false>();

View File

@ -0,0 +1,45 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "transformations/op_conversions/convert_convertlike.hpp"
#include <memory>
#include <ngraph/opsets/opset8.hpp>
#include <ngraph/pattern/op/wrap_type.hpp>
#include <ngraph/rt_info.hpp>
#include <vector>
#include "itt.hpp"
NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertConvertLike, "ConvertConvertLike", 0);
using namespace ngraph;
ngraph::pass::ConvertConvertLike::ConvertConvertLike() {
MATCHER_SCOPE(ConvertConvertLike);
auto convertlike = pattern::wrap_type<opset8::ConvertLike>();
matcher_pass_callback callback = [](pattern::Matcher& m) {
auto cvtlike = std::dynamic_pointer_cast<opset8::ConvertLike>(m.get_match_root());
if (!cvtlike) {
return false;
}
auto like = cvtlike->input_value(1);
const element::Type& dest_type = like.get_element_type();
if (dest_type == element::dynamic || dest_type == element::undefined)
return false;
auto cvt = std::make_shared<opset8::Convert>(cvtlike->input_value(0), dest_type);
cvt->set_friendly_name(cvtlike->get_friendly_name());
copy_runtime_info(cvtlike, cvt);
replace_node(cvtlike, cvt);
return true;
};
auto m = std::make_shared<pattern::Matcher>(convertlike, matcher_name);
this->register_matcher(m, callback);
}

View File

@ -1,109 +0,0 @@
// Copyright (C) 2018-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <string>
#include "ngraph_reader_tests.hpp"
TEST_F(NGraphReaderTests, ReadConvertLikeNetwork) {
std::string model = R"V0G0N(
<net name="ConvertLike" version="10">
<layers>
<layer id="0" name="input_a" type="Parameter" version="opset1">
<data shape="256,56" element_type="i32"/>
<output>
<port id="0" precision="I32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
<layer id="1" name="input_b" type="Parameter" version="opset1">
<data shape="256,56" element_type="f32"/>
<output>
<port id="0" precision="FP32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
<layer id="2" name="ConvertLike" type="ConvertLike" version="opset1">
<input>
<port id="0">
<dim>256</dim>
<dim>56</dim>
</port>
<port id="1">
<dim>256</dim>
<dim>56</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
<layer id="3" name="Identity/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>256</dim>
<dim>56</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
<edge from-layer="2" from-port="2" to-layer="3" to-port="0"/>
</edges>
</net>
)V0G0N";
std::string modelV7 = R"V0G0N(
<net name="ConvertLike" version="7">
<layers>
<layer id="0" name="input_a" type="Input" version="opset1">
<output>
<port id="0" precision="I32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
<layer id="1" name="input_b" type="Input" version="opset1">
<output>
<port id="0" precision="FP32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
<layer id="2" name="ConvertLike" type="ConvertLike" version="opset1">
<input>
<port id="0">
<dim>256</dim>
<dim>56</dim>
</port>
<port id="1">
<dim>256</dim>
<dim>56</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>256</dim>
<dim>56</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
</edges>
</net>
)V0G0N";
compareIRs(model, modelV7);
}

View File

@ -0,0 +1,104 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <string>
#include <memory>
#include <queue>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset8.hpp>
#include <transformations/op_conversions/convert_convertlike.hpp>
#include <transformations/init_node_info.hpp>
#include <transformations/utils/utils.hpp>
#include <ngraph/pass/manager.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
using namespace testing;
TEST(TransformationTests, ConvertConvertLike) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto like = ngraph::opset8::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1});
auto cvtlike = std::make_shared<ngraph::opset8::ConvertLike>(data, like);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvtlike}, ngraph::ParameterVector{data});
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<ngraph::pass::ConvertConvertLike>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto cvt = std::make_shared<ngraph::opset8::Convert>(data, ngraph::element::i32);
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvt}, ngraph::ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, ConvertConvertLike2) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto data2 = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::i8, ngraph::Shape{1});
auto constant = ngraph::opset8::Constant::create(ngraph::element::i8, ngraph::Shape{}, {1});
auto like = std::make_shared<ngraph::opset8::Add>(data2, constant);
auto cvtlike = std::make_shared<ngraph::opset8::ConvertLike>(data, like);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvtlike}, ngraph::ParameterVector{data, data2});
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<ngraph::pass::ConvertConvertLike>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto cvt = std::make_shared<ngraph::opset8::Convert>(data, ngraph::element::i8);
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvt}, ngraph::ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, ConvertConvertLike_Negative) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto like = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::dynamic, ngraph::Shape{1});
auto cvtlike = std::make_shared<ngraph::opset8::ConvertLike>(data, like);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvtlike}, ngraph::ParameterVector{data, like});
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<ngraph::pass::ConvertConvertLike>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, ngraph::Shape{3, 1, 2});
auto like = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::dynamic, ngraph::Shape{1});
auto cvtlike = std::make_shared<ngraph::opset8::ConvertLike>(data, like);
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{cvtlike}, ngraph::ParameterVector{data, like});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}