From f313dde66b6bd8ad42d48e6400217001b7fbf94b Mon Sep 17 00:00:00 2001 From: Evgeny Kotov Date: Wed, 5 Jul 2023 12:34:01 +0200 Subject: [PATCH] EliminatePad and PadFusion support Pad12 positive indexes (#18278) * update opset5::Pad -> PadBase * rewrite unit tests * refactor unit tests * add unit test NegativePadElimination * fix add destructor * clang fixes * fix unit tests * add unit tests * bug fix --------- Co-authored-by: Ivan Tikhonov --- .../common_optimizations/nop_elimination.cpp | 3 +- .../common_optimizations/pad_fusion.cpp | 34 +- .../tests/common_optimizations/pad_fusion.cpp | 1101 ++++++++++------- 3 files changed, 689 insertions(+), 449 deletions(-) diff --git a/src/common/transformations/src/transformations/common_optimizations/nop_elimination.cpp b/src/common/transformations/src/transformations/common_optimizations/nop_elimination.cpp index 68d3cf976ca396..4900eb1a407358 100644 --- a/src/common/transformations/src/transformations/common_optimizations/nop_elimination.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/nop_elimination.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -315,7 +316,7 @@ SIMPLE_MATCHER_PASS_DEFINITION(EliminateGather, simplify_gather, opset3::Gather, pass::EliminatePad::EliminatePad() { MATCHER_SCOPE(EliminatePad); - auto pad_node_pattern = pattern::wrap_type(); + auto pad_node_pattern = pattern::wrap_type(); matcher_pass_callback callback = [=](pattern::Matcher& m) { auto pad = m.get_match_root(); diff --git a/src/common/transformations/src/transformations/common_optimizations/pad_fusion.cpp b/src/common/transformations/src/transformations/common_optimizations/pad_fusion.cpp index 8fc2891747edae..d26c38925a5ee6 100644 --- a/src/common/transformations/src/transformations/common_optimizations/pad_fusion.cpp +++ b/src/common/transformations/src/transformations/common_optimizations/pad_fusion.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -17,7 +18,7 @@ using namespace ov; template -static bool can_be_fused(const std::shared_ptr& pad, +static bool can_be_fused(const std::shared_ptr& pad, const std::shared_ptr& node, const std::shared_ptr& pad_value_node, const std::shared_ptr& pads_begin, @@ -96,14 +97,14 @@ pass::PadFusionAvgPool::PadFusionAvgPool() { auto pads_end_pattern = pattern::wrap_type(); auto pad_value_pattern = pattern::any_input(); auto pad_node_pattern = - pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, - pattern::consumers_count(1)); + pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, + pattern::consumers_count(1)); auto avg_pool_pattern = pattern::wrap_type({pad_node_pattern}); matcher_pass_callback callback = [=](pattern::Matcher& m) { auto pattern_map = m.get_pattern_value_map(); auto data = pattern_map[data_pattern]; - auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); + auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); auto pad_value = pattern_map[pad_value_pattern].get_node_shared_ptr(); auto pads_begin = std::dynamic_pointer_cast(pattern_map[pads_begin_pattern].get_node_shared_ptr()); @@ -196,15 +197,16 @@ pass::PadFusionConvolution::PadFusionConvolution() { auto pads_end_pattern = pattern::wrap_type(); auto pad_value_pattern = pattern::any_input(); auto pad_node_pattern = - pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, - pattern::consumers_count(1)); + pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, + pattern::consumers_count(1)); auto conv_pattern = pattern::wrap_type({pad_node_pattern, filter_pattern}); matcher_pass_callback callback = [=](pattern::Matcher& m) { + std::cout << "[EMUTEX DEBUG] CHECKPOINT PadFusionConvolution" << std::endl; auto pattern_map = m.get_pattern_value_map(); auto data = pattern_map[data_pattern]; auto filter = pattern_map[filter_pattern]; - auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); + auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); auto pad_value = pattern_map[pad_value_pattern].get_node_shared_ptr(); auto pads_begin = std::dynamic_pointer_cast(pattern_map[pads_begin_pattern].get_node_shared_ptr()); @@ -243,15 +245,15 @@ pass::PadFusionConvolutionBackpropData::PadFusionConvolutionBackpropData() { auto pads_end_pattern = pattern::wrap_type(); auto pad_value_pattern = pattern::any_input(); auto pad_node_pattern = - pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, - pattern::consumers_count(1)); + pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, + pattern::consumers_count(1)); auto conv_pattern = pattern::wrap_type({pad_node_pattern, filter_pattern}); matcher_pass_callback callback = [=](pattern::Matcher& m) { auto pattern_map = m.get_pattern_value_map(); auto data = pattern_map[data_pattern]; auto filter = pattern_map[filter_pattern]; - auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); + auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); auto pad_value = pattern_map[pad_value_pattern].get_node_shared_ptr(); auto pads_begin = std::dynamic_pointer_cast(pattern_map[pads_begin_pattern].get_node_shared_ptr()); @@ -301,15 +303,15 @@ pass::PadFusionGroupConvolution::PadFusionGroupConvolution() { auto pads_end_pattern = pattern::wrap_type(); auto pad_value_pattern = pattern::any_input(); auto pad_node_pattern = - pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, - pattern::consumers_count(1)); + pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, + pattern::consumers_count(1)); auto conv_pattern = pattern::wrap_type({pad_node_pattern, filter_pattern}); matcher_pass_callback callback = [=](pattern::Matcher& m) { auto pattern_map = m.get_pattern_value_map(); auto data = pattern_map[data_pattern]; auto filter = pattern_map[filter_pattern]; - auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); + auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); auto pad_value = pattern_map[pad_value_pattern].get_node_shared_ptr(); auto pads_begin = std::dynamic_pointer_cast(pattern_map[pads_begin_pattern].get_node_shared_ptr()); @@ -349,15 +351,15 @@ pass::PadFusionGroupConvolutionBackpropData::PadFusionGroupConvolutionBackpropDa auto pads_end_pattern = pattern::wrap_type(); auto pad_value_pattern = pattern::any_input(); auto pad_node_pattern = - pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, - pattern::consumers_count(1)); + pattern::wrap_type({data_pattern, pads_begin_pattern, pads_end_pattern, pad_value_pattern}, + pattern::consumers_count(1)); auto conv_pattern = pattern::wrap_type({pad_node_pattern, filter_pattern}); matcher_pass_callback callback = [=](pattern::Matcher& m) { auto pattern_map = m.get_pattern_value_map(); auto data = pattern_map[data_pattern]; auto filter = pattern_map[filter_pattern]; - auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); + auto pad = std::dynamic_pointer_cast(pattern_map[pad_node_pattern].get_node_shared_ptr()); auto pad_value = pattern_map[pad_value_pattern].get_node_shared_ptr(); auto pads_begin = std::dynamic_pointer_cast(pattern_map[pads_begin_pattern].get_node_shared_ptr()); diff --git a/src/common/transformations/tests/common_optimizations/pad_fusion.cpp b/src/common/transformations/tests/common_optimizations/pad_fusion.cpp index 0d973466605648..24165f1b13685d 100644 --- a/src/common/transformations/tests/common_optimizations/pad_fusion.cpp +++ b/src/common/transformations/tests/common_optimizations/pad_fusion.cpp @@ -6,9 +6,7 @@ #include #include -#include -#include -#include +#include #include #include #include @@ -17,587 +15,826 @@ #include #include "common_test_utils/ngraph_test_utils.hpp" +#include "openvino/core/model.hpp" +#include "openvino/opsets/opset12.hpp" +#include "openvino/pass/manager.hpp" using namespace testing; -using namespace ngraph; +using namespace ov; +using namespace ov::opset12; + +using NodePtr = std::shared_ptr; + +class IPadFactory { +public: + explicit IPadFactory(const std::string& type_name) : type_name_(type_name) {} + virtual ~IPadFactory() = default; + virtual std::shared_ptr create(const Output& arg, + const Output& pads_begin, + const Output& pads_end, + ov::op::PadMode pad_mode) const = 0; + virtual std::shared_ptr create(const Output& arg, + const Output& pads_begin, + const Output& pads_end, + const Output& arg_pad_value, + ov::op::PadMode pad_mode) const = 0; + + const std::string& getTypeName() const { + return type_name_; + } + +private: + const std::string type_name_; +}; +using PadFactoryPtr = std::shared_ptr; + +template +class PadFactory : public IPadFactory { +public: + explicit PadFactory(const std::string& type_name) : IPadFactory(type_name) {} + NodePtr create(const Output& arg, + const Output& pads_begin, + const Output& pads_end, + ov::op::PadMode pad_mode) const override { + return std::make_shared(arg, pads_begin, pads_end, pad_mode); + } + NodePtr create(const Output& arg, + const Output& pads_begin, + const Output& pads_end, + const Output& arg_pad_value, + ov::op::PadMode pad_mode) const override { + return std::make_shared(arg, pads_begin, pads_end, arg_pad_value, pad_mode); + } +}; + +template +PadFactoryPtr CreatePadFactory(const std::string& type_name) { + return std::make_shared>(type_name); +} + +#undef CREATE_PAD_FACTORY +#define CREATE_PAD_FACTORY(type_name, type_str) CreatePadFactory(type_str) + +std::vector pad_factories = {CREATE_PAD_FACTORY(ov::op::v1::Pad, "op_v1_Pad"), + CREATE_PAD_FACTORY(ov::op::v12::Pad, "op_v12_Pad")}; + +struct ITestModelFactory { + explicit ITestModelFactory(const std::string& a_test_name) : test_name(a_test_name) {} + virtual ~ITestModelFactory() = default; + virtual void setup(PadFactoryPtr pad_factory, ov::pass::Manager& manager) = 0; + std::string test_name; + std::shared_ptr function; + std::shared_ptr function_ref; +}; +using TestModelFactoryPtr = std::shared_ptr; + +using TestParams = std::tuple; + +class PadTestFixture : public ::testing::WithParamInterface, public TransformationTestsF { +public: + static std::string get_test_name(const ::testing::TestParamInfo& obj) { + PadFactoryPtr pad_factory; + TestModelFactoryPtr model_factory; + std::tie(pad_factory, model_factory) = obj.param; + + std::ostringstream test_name; + test_name << "pad_factory=" << pad_factory->getTypeName() << "/"; + test_name << "model_factory=" << model_factory->test_name; + + return test_name.str(); + } +}; + +TEST_P(PadTestFixture, CompareFunctions) { + PadFactoryPtr pad_factory; + TestModelFactoryPtr model_factory; + std::tie(pad_factory, model_factory) = this->GetParam(); + + model_factory->setup(pad_factory, manager); + model = model_factory->function; + model_ref = model_factory->function_ref; + if (!model_ref) + model_ref = model->clone(); +} -TEST_F(TransformationTestsF, PadElimination) { +#define TEST_BODY(TestName) \ + struct TestName : public ITestModelFactory { \ + TestName() : ITestModelFactory(#TestName) {} \ + void setup(PadFactoryPtr pad_factory, ov::pass::Manager& manager) override; \ + }; \ + void TestName::setup(PadFactoryPtr pad_factory, ov::pass::Manager& manager) + +TEST_BODY(PadElimination) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 0, 0}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + } +} + +TEST_BODY(NegativePadElimination) { + Shape data_shape{1, 3, 14, 14}; + { + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + manager.register_pass(); } + // Reference function is equal to function } -TEST_F(TransformationTestsF, PadFusionAvgPoolExcludePad) { +TEST_BODY(PadFusionAvgPoolExcludePad) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto avg_pool = std::make_shared(pad, - Strides{1, 1}, - Shape{0, 0}, - Shape{0, 0}, - Shape{4, 4}, - true, - op::RoundingType::FLOOR); - function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{0, 0}, + Shape{4, 4}, + true, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto avg_pool = std::make_shared(data, - Strides{1, 1}, - Shape{1, 1}, - Shape{2, 2}, - Shape{4, 4}, - false, - op::RoundingType::FLOOR, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto avg_pool = std::make_shared(data, + Strides{1, 1}, + Shape{1, 1}, + Shape{2, 2}, + Shape{4, 4}, + false, + op::RoundingType::FLOOR, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + } +} + +TEST_BODY(NegativePadFusionAvgPoolExcludePad) { + Shape data_shape{1, 3, 14, 14}; + { + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -2, -2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{0, 0}, + Shape{4, 4}, + true, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + manager.register_pass(); } + // Reference function is equal to function } -TEST_F(TransformationTestsF, PadFusionAvgPoolDontExcludePad) { +TEST_BODY(PadFusionAvgPoolDontExcludePad) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto avg_pool = std::make_shared(pad, - Strides{1, 1}, - Shape{0, 0}, - Shape{1, 1}, - Shape{4, 4}, - false, - op::RoundingType::FLOOR); - function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{1, 1}, + Shape{4, 4}, + false, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto avg_pool = std::make_shared(data, - Strides{1, 1}, - Shape{1, 1}, - Shape{3, 3}, - Shape{4, 4}, - false, - op::RoundingType::FLOOR, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto avg_pool = std::make_shared(data, + Strides{1, 1}, + Shape{1, 1}, + Shape{3, 3}, + Shape{4, 4}, + false, + op::RoundingType::FLOOR, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + } +} + +TEST_BODY(NegativePadFusionAvgPoolDontExcludePad) { + Shape data_shape{1, 3, 14, 14}; + { + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -2, -2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{1, 1}, + Shape{4, 4}, + false, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + manager.register_pass(); } + // Reference function is equal to function } -TEST_F(TransformationTestsF, PadFusionConvolution) { +TEST_BODY(PadFusionConvolution) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{3, 3}, - Shape{1, 1}, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{3, 3}, + Shape{1, 1}, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + } +} + +TEST_BODY(NegativePadFusionConvolution) { + Shape data_shape{1, 3, 14, 14}; + { + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -2, -2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + manager.register_pass(); } + // Reference function is equal to function } -TEST_F(TransformationTestsF, PadFusionConvolutionBackpropData) { +TEST_BODY(PadFusionConvolutionBackpropData) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{4, 4}, - CoordinateDiff{3, 3}, - Shape{1, 1}); + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{4, 4}, + CoordinateDiff{3, 3}, + Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{3, 3}, - CoordinateDiff{1, 1}, - Shape{1, 1}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{3, 3}, + CoordinateDiff{1, 1}, + Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, PadFusionGroupConvolution) { +TEST_BODY(PadFusionGroupConvolution) { Shape data_shape{1, 4, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{3, 3}, - Shape{1, 1}, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{3, 3}, + Shape{1, 1}, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + } +} + +TEST_BODY(NegativePadFusionGroupConvolution) { + Shape data_shape{1, 4, 14, 14}; + { + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -2, -2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + manager.register_pass(); } + // Reference function is equal to function } -TEST_F(TransformationTestsF, PadFusionGroupConvolutionBackpropData) { +TEST_BODY(PadFusionGroupConvolutionBackpropData) { Shape data_shape{1, 4, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 3, 1}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{3, 2}, - CoordinateDiff{4, 3}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 3, 1}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{3, 2}, + CoordinateDiff{4, 3}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{2, 1}, - CoordinateDiff{1, 2}, - Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{2, 1}, + CoordinateDiff{1, 2}, + Shape{1, 1}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, PadFusionAvgPoolNonConstPadValue) { +TEST_BODY(PadFusionAvgPoolNonConstPadValue) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - std::shared_ptr pad_value = opset5::Constant::create(element::f16, Shape{}, {0}); - pad_value = std::make_shared(pad_value, element::f32); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto avg_pool = std::make_shared(pad, - Strides{1, 1}, - Shape{0, 0}, - Shape{0, 0}, - Shape{4, 4}, - true, - op::RoundingType::FLOOR); - function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + std::shared_ptr pad_value = Constant::create(element::f16, Shape{}, {0}); + pad_value = std::make_shared(pad_value, element::f32); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{0, 0}, + Shape{4, 4}, + true, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto avg_pool = std::make_shared(data, - Strides{1, 1}, - Shape{1, 1}, - Shape{2, 2}, - Shape{4, 4}, - false, - op::RoundingType::FLOOR, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::f32, data_shape); + auto avg_pool = std::make_shared(data, + Strides{1, 1}, + Shape{1, 1}, + Shape{2, 2}, + Shape{4, 4}, + false, + op::RoundingType::FLOOR, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); } } -TEST_F(TransformationTestsF, PadFusionConvolutionNonConstPadValue) { +TEST_BODY(PadFusionConvolutionNonConstPadValue) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - std::shared_ptr pad_value = opset5::Constant::create(element::f16, Shape{}, {0}); - pad_value = std::make_shared(pad_value, element::f32); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + std::shared_ptr pad_value = Constant::create(element::f16, Shape{}, {0}); + pad_value = std::make_shared(pad_value, element::f32); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{3, 3}, - Shape{1, 1}, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{3, 3}, + Shape{1, 1}, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, PadFusionConvolutionBackpropDataNonConstPadValue) { +TEST_BODY(PadFusionConvolutionBackpropDataNonConstPadValue) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - std::shared_ptr pad_value = opset5::Constant::create(element::f16, Shape{}, {0}); - pad_value = std::make_shared(pad_value, element::f32); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{4, 4}, - CoordinateDiff{3, 3}, - Shape{1, 1}); - - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + std::shared_ptr pad_value = Constant::create(element::f16, Shape{}, {0}); + pad_value = std::make_shared(pad_value, element::f32); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{4, 4}, + CoordinateDiff{3, 3}, + Shape{1, 1}); + + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{3, 3}, - CoordinateDiff{1, 1}, - Shape{1, 1}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{3, 3}, + CoordinateDiff{1, 1}, + Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, PadFusionGroupConvolutionNonConstPadValue) { +TEST_BODY(PadFusionGroupConvolutionNonConstPadValue) { Shape data_shape{1, 4, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - std::shared_ptr pad_value = opset5::Constant::create(element::f16, Shape{}, {0}); - pad_value = std::make_shared(pad_value, element::f32); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + std::shared_ptr pad_value = Constant::create(element::f16, Shape{}, {0}); + pad_value = std::make_shared(pad_value, element::f32); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{3, 3}, - Shape{1, 1}, - op::PadType::EXPLICIT); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{1, 1, 4, 4, 4}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{3, 3}, + Shape{1, 1}, + op::PadType::EXPLICIT); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, PadFusionGroupConvolutionBackpropDataNonConstPadValue) { +TEST_BODY(PadFusionGroupConvolutionBackpropDataNonConstPadValue) { Shape data_shape{1, 4, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 3, 1}); - std::shared_ptr pad_value = opset5::Constant::create(element::f16, Shape{}, {0}); - pad_value = std::make_shared(pad_value, element::f32); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{3, 2}, - CoordinateDiff{4, 3}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 3, 1}); + std::shared_ptr pad_value = Constant::create(element::f16, Shape{}, {0}); + pad_value = std::make_shared(pad_value, element::f32); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{3, 2}, + CoordinateDiff{4, 3}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); - auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); - auto conv = std::make_shared(data, - filters, - Strides{1, 1}, - CoordinateDiff{2, 1}, - CoordinateDiff{1, 2}, - Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::f32, data_shape); + auto filters = std::make_shared(element::f32, Shape{2, 2, 1, 5, 5}); + auto conv = std::make_shared(data, + filters, + Strides{1, 1}, + CoordinateDiff{2, 1}, + CoordinateDiff{1, 2}, + Shape{1, 1}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, NegativePadFusionNonConstantPadMode) { +TEST_BODY(NegativePadFusionNonConstantPadMode) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::REFLECT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::REFLECT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::REFLECT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::REFLECT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, NegativePadFusionNonZeroPadValue) { +TEST_BODY(NegativePadFusionNonZeroPadValue) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad_value = opset5::Constant::create(element::i32, Shape{}, {2}); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad_value = Constant::create(element::i32, Shape{}, {2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad_value = opset5::Constant::create(element::i32, Shape{}, {2}); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad_value = Constant::create(element::i32, Shape{}, {2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, NegativePadFusionPadForBatchSize) { +TEST_BODY(NegativePadFusionPadForBatchSize) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {1, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad_value = opset5::Constant::create(element::i32, Shape{}, {0}); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {1, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad_value = Constant::create(element::i32, Shape{}, {0}); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {1, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad_value = opset5::Constant::create(element::i32, Shape{}, {0}); - auto pad = std::make_shared(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {1, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad_value = Constant::create(element::i32, Shape{}, {0}); + auto pad = pad_factory->create(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, NegativePadFusionAvgPoolExcludePadNonZeroPads) { +TEST_BODY(NegativePadFusionAvgPoolExcludePadNonZeroPads) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto avg_pool = std::make_shared(pad, - Strides{1, 1}, - Shape{0, 0}, - Shape{1, 1}, - Shape{4, 4}, - true, - op::RoundingType::FLOOR); - function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{1, 1}, + Shape{4, 4}, + true, + op::RoundingType::FLOOR); + function = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); manager.register_pass(); } { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto avg_pool = std::make_shared(pad, - Strides{1, 1}, - Shape{0, 0}, - Shape{1, 1}, - Shape{4, 4}, - true, - op::RoundingType::FLOOR); - function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 1, 1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto avg_pool = std::make_shared(pad, + Strides{1, 1}, + Shape{0, 0}, + Shape{1, 1}, + Shape{4, 4}, + true, + op::RoundingType::FLOOR); + function_ref = std::make_shared(NodeVector{avg_pool}, ParameterVector{data}); } } -TEST_F(TransformationTestsF, NegativePadFusionConvolutionBackpropDataTooSmallPad) { +TEST_BODY(NegativePadFusionConvolutionBackpropDataTooSmallPad) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::f32, data_shape); + auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{1, 1}, - Shape{1, 1}); + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{1, 1}, + Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } { - auto data = std::make_shared(element::f32, data_shape); + auto data = std::make_shared(element::f32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, 2, 2}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{1, 1}, - CoordinateDiff{1, 1}, - Shape{1, 1}); + auto filters = std::make_shared(element::f32, Shape{3, 2, 5, 5}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{1, 1}, + CoordinateDiff{1, 1}, + Shape{1, 1}); - function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + function_ref = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); } } -TEST_F(TransformationTestsF, NegativePadPreservation) { +TEST_BODY(NegativePadPreservation) { Shape data_shape{1, 3, 14, 14}; { - auto data = std::make_shared(element::i32, data_shape); - auto pads_begin = opset5::Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); - auto pads_end = opset5::Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); - auto pad = std::make_shared(data, pads_begin, pads_end, op::PadMode::CONSTANT); - auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); - auto conv = std::make_shared(pad, - filters, - Strides{1, 1}, - CoordinateDiff{0, 0}, - CoordinateDiff{1, 1}, - Shape{1, 1}); - function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); + auto data = std::make_shared(element::i32, data_shape); + auto pads_begin = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pads_end = Constant::create(element::i32, Shape{4}, {0, 0, -1, -1}); + auto pad = pad_factory->create(data, pads_begin, pads_end, op::PadMode::CONSTANT); + auto filters = std::make_shared(element::i32, Shape{1, 3, 4, 4}); + auto conv = std::make_shared(pad, + filters, + Strides{1, 1}, + CoordinateDiff{0, 0}, + CoordinateDiff{1, 1}, + Shape{1, 1}); + function = std::make_shared(NodeVector{conv}, ParameterVector{data, filters}); manager.register_pass(); } // Reference function is equal to function } + +#undef CREATE_MODEL_FACTORY +#define CREATE_MODEL_FACTORY(type_name) std::make_shared() + +std::vector model_factories = { + CREATE_MODEL_FACTORY(PadElimination), + CREATE_MODEL_FACTORY(PadFusionAvgPoolExcludePad), + CREATE_MODEL_FACTORY(PadFusionAvgPoolDontExcludePad), + CREATE_MODEL_FACTORY(PadFusionConvolution), + CREATE_MODEL_FACTORY(PadFusionConvolutionBackpropData), + CREATE_MODEL_FACTORY(PadFusionGroupConvolution), + CREATE_MODEL_FACTORY(PadFusionGroupConvolutionBackpropData), + CREATE_MODEL_FACTORY(PadFusionAvgPoolNonConstPadValue), + CREATE_MODEL_FACTORY(PadFusionConvolutionNonConstPadValue), + CREATE_MODEL_FACTORY(PadFusionConvolutionBackpropDataNonConstPadValue), + CREATE_MODEL_FACTORY(PadFusionGroupConvolutionNonConstPadValue), + CREATE_MODEL_FACTORY(PadFusionGroupConvolutionBackpropDataNonConstPadValue), + CREATE_MODEL_FACTORY(NegativePadFusionNonConstantPadMode), + CREATE_MODEL_FACTORY(NegativePadFusionNonZeroPadValue), + CREATE_MODEL_FACTORY(NegativePadFusionPadForBatchSize), + CREATE_MODEL_FACTORY(NegativePadFusionAvgPoolExcludePadNonZeroPads), + CREATE_MODEL_FACTORY(NegativePadFusionConvolutionBackpropDataTooSmallPad), + CREATE_MODEL_FACTORY(NegativePadPreservation), + CREATE_MODEL_FACTORY(NegativePadElimination), + CREATE_MODEL_FACTORY(NegativePadFusionAvgPoolExcludePad), + CREATE_MODEL_FACTORY(NegativePadFusionAvgPoolDontExcludePad), + CREATE_MODEL_FACTORY(NegativePadFusionConvolution), + CREATE_MODEL_FACTORY(NegativePadFusionGroupConvolution)}; + +INSTANTIATE_TEST_SUITE_P(PadTestSuite, + PadTestFixture, + ::testing::Combine(::testing::ValuesIn(pad_factories), ::testing::ValuesIn(model_factories)), + PadTestFixture::get_test_name);