From 13f3f351b78d1f16f26a2dda2cfb564b469170e5 Mon Sep 17 00:00:00 2001 From: Aleksandr Pertovsky Date: Tue, 30 Nov 2021 19:41:14 +0300 Subject: [PATCH] [CPU] Add MoveEltwiseUpThroughDataMov (#7488) --- .../src/mkldnn_plugin/mkldnn_plugin.cpp | 9 + .../move_eltwise_up_data_movement.cpp | 113 ++++ .../move_eltwise_up_data_movement.hpp | 17 + .../convert_matmul_test.cpp | 0 .../convert_to_leaky_relu_test.cpp | 0 .../move_eltwise_up_data_movement_test.cpp | 331 +++++++++++ .../reshape_1d_ops_test.cpp | 516 ++++++++++++++++++ .../reshape_prelu_test.cpp | 0 8 files changed, 986 insertions(+) create mode 100644 inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.cpp create mode 100644 inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.hpp rename inference-engine/tests/unit/cpu/{ => ngraph_transformations}/convert_matmul_test.cpp (100%) rename inference-engine/tests/unit/cpu/{ => ngraph_transformations}/convert_to_leaky_relu_test.cpp (100%) create mode 100644 inference-engine/tests/unit/cpu/ngraph_transformations/move_eltwise_up_data_movement_test.cpp create mode 100644 inference-engine/tests/unit/cpu/ngraph_transformations/reshape_1d_ops_test.cpp rename inference-engine/tests/unit/cpu/{ => ngraph_transformations}/reshape_prelu_test.cpp (100%) diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp index 308ecfe3000..d2dc0f0c79e 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp @@ -108,6 +108,7 @@ #include "nodes/mkldnn_fake_quantize_node.h" #include "nodes/mkldnn_normalize_node.h" #include "ngraph_transformations/convert_to_cpu_specific_opset.hpp" +#include "ngraph_transformations/move_eltwise_up_data_movement.hpp" #include "transformations/smart_reshape/smart_reshape.hpp" #if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__) && !defined(_M_ARM64) @@ -477,6 +478,14 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr return node->get_rt_info().count("UNROLL_TI") == 0; }); + postLPTPassManager.register_pass(); + postLPTPassManager.get_pass_config()->set_callback([](const std::shared_ptr& node) -> bool { + if (node->get_input_size() >= 2) { + return node->get_input_element_type(1) == ngraph::element::i8 || node->get_input_element_type(1) == ngraph::element::u8; + } + return false; + }); + postLPTPassManager.run_passes(nGraphFunc); } diff --git a/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.cpp b/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.cpp new file mode 100644 index 00000000000..948a33d3951 --- /dev/null +++ b/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.cpp @@ -0,0 +1,113 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "move_eltwise_up_data_movement.hpp" + +#include +#include +#include + +#include +#include +#include + + +NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::MoveEltwiseUpThroughDataMov, "MoveEltwiseUpThroughDataMov", 0); + +namespace { + bool is_data_movement_operation(const std::shared_ptr& node) { + return ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node) || + ov::is_type(node); + } + + bool is_scalar_like(const std::shared_ptr& node) { + auto constantNode = std::dynamic_pointer_cast(node); + return constantNode != nullptr && shape_size(constantNode->get_shape()) == 1; + } +} // namespace + +MKLDNNPlugin::MoveEltwiseUpThroughDataMov::MoveEltwiseUpThroughDataMov() { + auto eltwise_pattern = ngraph::pattern::wrap_type(ngraph::pattern::has_static_rank()); + + ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) { + const auto& pattern_map = m.get_pattern_value_map(); + + auto eltwise = pattern_map.at(eltwise_pattern).get_node_shared_ptr(); + if (transformation_callback(eltwise)) { + return false; + } + + if (eltwise->get_output_size() == 0 || + eltwise->get_input_size() == 0 || + eltwise->get_output_element_type(0) != eltwise->get_input_element_type(0) || + eltwise->get_output_target_inputs(0).size() != 1) { + return false; + } + + bool is_binary_op = std::dynamic_pointer_cast(eltwise) != nullptr; + if (is_binary_op && !is_scalar_like(eltwise->get_input_node_shared_ptr(1))) { + return false; + } + + + + auto current = eltwise->get_input_node_shared_ptr(0); + auto child = eltwise; + + while (is_data_movement_operation(current)) { + if (current->get_output_size() != 1 || + current->get_output_target_inputs(0).size() != 1 || + current->get_output_element_type(0) != current->get_input_element_type(0)) { + return false; + } + + child = current; + current = current->get_input_node_shared_ptr(0); + } + + // now current is the first not data movement op + if (child == eltwise) { + return false; + } + + // eltwise constant shape should match new input shape + if (is_binary_op && current->get_output_shape(0).size() != eltwise->get_input_shape(1).size()) { + auto old_eltwise_const = std::dynamic_pointer_cast(eltwise->get_input_node_shared_ptr(1)); + auto new_constant = std::make_shared(*old_eltwise_const.get(), ngraph::Shape{}); + ngraph::replace_node(old_eltwise_const, new_constant); + } + ngraph::replace_output_update_name(eltwise->output(0), eltwise->input_value(0)); + + ngraph::OutputVector eltwiseInputs = eltwise->input_values(); + eltwiseInputs[0] = child->input_value(0); + auto newEltwise = eltwise->clone_with_new_inputs(eltwiseInputs); + ngraph::copy_runtime_info(eltwise, newEltwise); + newEltwise->set_friendly_name(eltwise->get_friendly_name()); + + ngraph::OutputVector childInputs = child->input_values(); + childInputs[0] = newEltwise; + auto newChild = child->clone_with_new_inputs(childInputs); + ngraph::copy_runtime_info(child, newChild); + newChild->set_friendly_name(child->get_friendly_name()); + + ngraph::replace_node(child, newChild); + return true; + }; + + auto m = std::make_shared(eltwise_pattern, "MoveEltwiseUpThroughDataMov"); + register_matcher(m, callback); +} diff --git a/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.hpp b/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.hpp new file mode 100644 index 00000000000..af145e1d7ee --- /dev/null +++ b/inference-engine/src/mkldnn_plugin/ngraph_transformations/move_eltwise_up_data_movement.hpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace MKLDNNPlugin { + +class MoveEltwiseUpThroughDataMov : public ngraph::pass::MatcherPass { +public: + NGRAPH_RTTI_DECLARATION; + MoveEltwiseUpThroughDataMov(); +}; + +} // namespace MKLDNNPlugin diff --git a/inference-engine/tests/unit/cpu/convert_matmul_test.cpp b/inference-engine/tests/unit/cpu/ngraph_transformations/convert_matmul_test.cpp similarity index 100% rename from inference-engine/tests/unit/cpu/convert_matmul_test.cpp rename to inference-engine/tests/unit/cpu/ngraph_transformations/convert_matmul_test.cpp diff --git a/inference-engine/tests/unit/cpu/convert_to_leaky_relu_test.cpp b/inference-engine/tests/unit/cpu/ngraph_transformations/convert_to_leaky_relu_test.cpp similarity index 100% rename from inference-engine/tests/unit/cpu/convert_to_leaky_relu_test.cpp rename to inference-engine/tests/unit/cpu/ngraph_transformations/convert_to_leaky_relu_test.cpp diff --git a/inference-engine/tests/unit/cpu/ngraph_transformations/move_eltwise_up_data_movement_test.cpp b/inference-engine/tests/unit/cpu/ngraph_transformations/move_eltwise_up_data_movement_test.cpp new file mode 100644 index 00000000000..daa09802d50 --- /dev/null +++ b/inference-engine/tests/unit/cpu/ngraph_transformations/move_eltwise_up_data_movement_test.cpp @@ -0,0 +1,331 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include + +using namespace testing; + +TEST(MoveEltwiseUpThroughDataMov, SingleUnaryEltwise) { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + std::shared_ptr f(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(input, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + auto sigmoid = std::make_shared(unsqueeze); + + f = std::make_shared(ngraph::NodeVector{sigmoid}, ngraph::ParameterVector{input}); + } + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + std::shared_ptr f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto sigmoid = std::make_shared(input); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(sigmoid, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{unsqueeze}, ngraph::ParameterVector{input}); + } + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, EltwiseSequence) { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {1, 2, 0, 3}; + const int64_t unsqueeze_axis = 1; + std::shared_ptr f(nullptr); + { + auto input_left = std::make_shared(ngraph::element::f32, shape); + auto input_right = std::make_shared(ngraph::element::f32, shape); + + auto matmul = std::make_shared(input_left, input_right); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(matmul, transpose_const); + + auto relu = std::make_shared(transpose); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(relu, unsqueeze_const); + + auto sigmoid = std::make_shared(unsqueeze); + + f = std::make_shared(ngraph::NodeVector{sigmoid}, ngraph::ParameterVector{input_left, input_right}); + } + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + + std::shared_ptr f_ref(nullptr); + { + auto input_left = std::make_shared(ngraph::element::f32, shape); + auto input_right = std::make_shared(ngraph::element::f32, shape); + + auto matmul = std::make_shared(input_left, input_right); + + auto relu = std::make_shared(matmul); + + auto sigmoid = std::make_shared(relu); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(sigmoid, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{unsqueeze}, ngraph::ParameterVector{input_left, input_right}); + } + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, DataMovementTwoConsumers) { + /* In this case transformation shouldn't apply */ + auto create_graph = [] () -> std::shared_ptr { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {1, 2, 0, 3}; + const int64_t unsqueeze_axis = 1; + + auto input_left = std::make_shared(ngraph::element::f32, shape); + auto input_right = std::make_shared(ngraph::element::f32, shape); + + auto matmul = std::make_shared(input_left, input_right); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(matmul, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + auto sigmoid = std::make_shared(unsqueeze); + + auto relu = std::make_shared(transpose); + + return std::make_shared(ngraph::NodeVector{sigmoid, relu}, ngraph::ParameterVector{input_left, input_right}); + }; + + std::shared_ptr f = create_graph(); + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + + std::shared_ptr f_ref = create_graph(); + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, SingleBinaryEltwiseWithScalarOnSecondBranch) { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + const float scalar_value = 0.5f; + std::shared_ptr f(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(input, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + auto add = std::make_shared(unsqueeze, ngraph::opset8::Constant::create(ngraph::element::f32, {}, {scalar_value})); + + f = std::make_shared(ngraph::NodeVector{add}, ngraph::ParameterVector{input}); + } + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + std::shared_ptr f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto add = std::make_shared(input, ngraph::opset8::Constant::create(ngraph::element::f32, {}, {scalar_value})); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(add, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{unsqueeze}, ngraph::ParameterVector{input}); + } + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, SingleEltwiseWith5ScalarOnSecondBranch) { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + const float scalar_value = 0.5f; + std::shared_ptr f(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto add = std::make_shared(unsqueeze, ngraph::opset8::Constant::create(ngraph::element::f32, {1, 1, 1, 1, 1}, {scalar_value})); + + f = std::make_shared(ngraph::NodeVector{add}, ngraph::ParameterVector{input}); + } + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + std::shared_ptr f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, shape); + + auto add = std::make_shared(input, ngraph::opset8::Constant::create(ngraph::element::f32, {}, {scalar_value})); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(add, unsqueeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{unsqueeze}, ngraph::ParameterVector{input}); + } + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, SingleBinaryEltwiseWithNotScalarOnSecondBranch) { + auto create_graph = [] () -> std::shared_ptr { + const ngraph::Shape shape{1, 3, 224, 224}; + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + std::shared_ptr f(nullptr); + auto input = std::make_shared(ngraph::element::f32, shape); + + auto transpose_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{input_order.size()}, input_order); + auto transpose = std::make_shared(input, transpose_const); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(transpose, unsqueeze_const); + + auto add_scalar = ngraph::opset8::Constant::create(ngraph::element::f32, {1, 1, 1, 3}, {0.5, 0.2, 0.3}); + auto add = std::make_shared(unsqueeze, add_scalar); + + return std::make_shared(ngraph::NodeVector{add}, ngraph::ParameterVector{input}); + }; + std::shared_ptr f = create_graph(); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + + std::shared_ptr f_ref = create_graph(); + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, SingleUnaryEltwiseDynamicShape) { + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + std::shared_ptr f(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto sigmoid = std::make_shared(unsqueeze); + + f = std::make_shared(ngraph::NodeVector{sigmoid}, ngraph::ParameterVector{input}); + } + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + std::shared_ptr f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + + auto sigmoid = std::make_shared(input); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(sigmoid, unsqueeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{unsqueeze}, ngraph::ParameterVector{input}); + } + + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} + +TEST(MoveEltwiseUpThroughDataMov, SingleUnaryEltwiseDynamicRank) { + auto create_graph = [] () -> std::shared_ptr { + const std::vector input_order = {3, 2, 1, 0}; + const int64_t unsqueeze_axis = 2; + std::shared_ptr f(nullptr); + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(ngraph::Rank::dynamic())); + + auto unsqueeze_const = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, {unsqueeze_axis}); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + auto sigmoid = std::make_shared(unsqueeze); + return std::make_shared(ngraph::NodeVector{sigmoid}, ngraph::ParameterVector{input}); + }; + std::shared_ptr f = create_graph(); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + + m.run_passes(f); + ASSERT_NO_THROW(check_rt_info(f)); + + std::shared_ptr f_ref = create_graph(); + auto res = compare_functions(f, f_ref); + + ASSERT_TRUE(res.first) << res.second; +} diff --git a/inference-engine/tests/unit/cpu/ngraph_transformations/reshape_1d_ops_test.cpp b/inference-engine/tests/unit/cpu/ngraph_transformations/reshape_1d_ops_test.cpp new file mode 100644 index 00000000000..99b42dbfebb --- /dev/null +++ b/inference-engine/tests/unit/cpu/ngraph_transformations/reshape_1d_ops_test.cpp @@ -0,0 +1,516 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "common_test_utils/ngraph_test_utils.hpp" + +using namespace testing; +using namespace MKLDNNPlugin; + +TEST(TransformationTests, Reshape1DAvgPoolTest1) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto avgPool = std::make_shared( + input, + ngraph::Strides{ 1 }, + ngraph::Shape{ 1 }, + ngraph::Shape{ 0 }, + ngraph::Shape{ 2 }, + true); + + f = std::make_shared(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto avg_pool = std::make_shared( + unsqueeze, + ngraph::Strides{ 1, 1 }, + ngraph::Shape{ 0, 1 }, + ngraph::Shape{ 0, 0 }, + ngraph::Shape{ 1, 2 }, + true); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(avg_pool, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DAvgPoolTest2) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto avgPool = std::make_shared( + input, + ngraph::Strides{ 1 }, + ngraph::Shape{ 1 }, + ngraph::Shape{ 0 }, + ngraph::Shape{ 2 }, + true); + + f = std::make_shared(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto avg_pool = std::make_shared( + unsqueeze, + ngraph::Strides{ 1, 1 }, + ngraph::Shape{ 0, 1 }, + ngraph::Shape{ 0, 0 }, + ngraph::Shape{ 1, 2 }, + true); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(avg_pool, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DAvgPoolTest3) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16, 16 }); + auto avgPool = std::make_shared( + input, + ngraph::Strides{ 1, 1 }, + ngraph::Shape{ 1, 1 }, + ngraph::Shape{ 0, 0 }, + ngraph::Shape{ 2, 2 }, + true); + + f = std::make_shared(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input }); + f_ref = f; + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DMaxPoolTest1) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto max_pool = std::make_shared( + input, + ngraph::Strides{ 1 }, + ngraph::Shape{ 1 }, + ngraph::Shape{ 0 }, + ngraph::Shape{ 2 }); + + f = std::make_shared(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto max_pool = std::make_shared( + unsqueeze, + ngraph::Strides{ 1, 1 }, + ngraph::Shape{ 0, 1 }, + ngraph::Shape{ 0, 0 }, + ngraph::Shape{ 1, 2 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(max_pool, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DMaxPoolTest2) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto max_pool = std::make_shared( + input, + ngraph::Strides{ 1 }, + ngraph::Shape{ 1 }, + ngraph::Shape{ 0 }, + ngraph::Shape{ 2 }); + + f = std::make_shared(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto max_pool = std::make_shared( + unsqueeze, + ngraph::Strides{ 1, 1 }, + ngraph::Shape{ 0, 1 }, + ngraph::Shape{ 0, 0 }, + ngraph::Shape{ 1, 2 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(max_pool, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DMaxPoolTest3) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic()); + auto max_pool = std::make_shared( + input, + ngraph::Strides{ 1 }, + ngraph::Shape{ 1 }, + ngraph::Shape{ 0 }, + ngraph::Shape{ 2 }); + + f = std::make_shared(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input }); + f_ref = f; + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DConvolutionTest1) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 3 }, { 2.f }); + auto convolution = std::make_shared( + input, + weights, + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + f = std::make_shared(ngraph::NodeVector{ convolution }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 1, 3 }, { 2.f }); + auto convolution = std::make_shared( + unsqueeze, + weights, + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(convolution, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DConvolutionTest2) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 3 }, { 2.f }); + auto convolution = std::make_shared( + input, + weights, + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + auto bias_const = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 1, 6, 1 }, { 24.f }); + auto bias = std::make_shared(convolution, bias_const); + + f = std::make_shared(ngraph::NodeVector{ bias }, ngraph::ParameterVector{ input }); + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 1, 3 }, { 2.f }); + auto convolution = std::make_shared( + unsqueeze, + weights, + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto bias_const = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 1, 6, 1, 1 }, { 24.f }); + auto bias = std::make_shared(convolution, bias_const); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(bias, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DConvolutionTest3) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::u8, ngraph::Shape{ 1, 3, 16 }); + auto weights = ngraph::opset1::Constant::create(ngraph::element::i8, ngraph::Shape{ 6, 3, 3 }, { 2.f }); + + auto relaxed_convolution = std::make_shared>( + ngraph::element::TypeVector{ngraph::element::f32, ngraph::element::f32}, + ngraph::element::TypeVector{ngraph::element::f32}, + ngraph::op::TemporaryReplaceOutputType(input, ngraph::element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(weights, ngraph::element::f32).get(), + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + f = std::make_shared(ngraph::NodeVector{ relaxed_convolution }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::u8, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::i8, ngraph::Shape{ 6, 3, 1, 3 }, { 2.f }); + auto relaxed_convolution = std::make_shared>( + ngraph::element::TypeVector{ ngraph::element::f32, ngraph::element::f32 }, + ngraph::element::TypeVector{ ngraph::element::f32 }, + ngraph::op::TemporaryReplaceOutputType(unsqueeze, ngraph::element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(weights, ngraph::element::f32).get(), + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(relaxed_convolution, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DConvolutionTest4) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 3 }, { 2.f }); + auto convolution = std::make_shared( + input, + weights, + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + auto bias_const = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 1, 6, 1 }, { 24.f }); + auto bias = std::make_shared(convolution, bias_const); + + f = std::make_shared(ngraph::NodeVector{ bias }, ngraph::ParameterVector{ input }); + + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 6, 3, 1, 3 }, { 2.f }); + auto convolution = std::make_shared( + unsqueeze, + weights, + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto bias_const = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 1, 6, 1, 1 }, { 24.f }); + auto bias = std::make_shared(convolution, bias_const); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(bias, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DGroupConvolutionTest1) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 3, 1, 1, 3 }, { 2.f }); + auto group_convolution = std::make_shared( + input, + weights, + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + f = std::make_shared(ngraph::NodeVector{ group_convolution }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 }); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 3, 1, 1, 1, 3 }, { 2.f }); + auto group_convolution = std::make_shared( + unsqueeze, + weights, + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(group_convolution, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} + +TEST(TransformationTests, Reshape1DGroupConvolutionTest2) { + std::shared_ptr f(nullptr), f_ref(nullptr); + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 3, 1, 1, 3 }, { 2.f }); + auto group_convolution = std::make_shared( + input, + weights, + ngraph::Strides{ 1 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::CoordinateDiff{ 0 }, + ngraph::Strides{ 1 }); + + f = std::make_shared(ngraph::NodeVector{ group_convolution }, ngraph::ParameterVector{ input }); + ngraph::pass::Manager m; + m.register_pass(); + m.register_pass(); + m.run_passes(f); + } + + { + auto input = std::make_shared(ngraph::element::f32, ngraph::PartialShape::dynamic(3)); + auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto unsqueeze = std::make_shared(input, unsqueeze_const); + + auto weights = ngraph::opset1::Constant::create(ngraph::element::f32, ngraph::Shape{ 3, 1, 1, 1, 3 }, { 2.f }); + auto group_convolution = std::make_shared( + unsqueeze, + weights, + ngraph::Strides{ 1, 1 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::CoordinateDiff{ 0, 0 }, + ngraph::Strides{ 1, 1 }); + + auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 }); + auto squeeze = std::make_shared(group_convolution, squeeze_const); + + f_ref = std::make_shared(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input }); + } + + auto res = compare_functions(f, f_ref); + ASSERT_TRUE(res.first) << res.second; +} diff --git a/inference-engine/tests/unit/cpu/reshape_prelu_test.cpp b/inference-engine/tests/unit/cpu/ngraph_transformations/reshape_prelu_test.cpp similarity index 100% rename from inference-engine/tests/unit/cpu/reshape_prelu_test.cpp rename to inference-engine/tests/unit/cpu/ngraph_transformations/reshape_prelu_test.cpp