Files
openvino/inference-engine/tests/functional/inference_engine/transformations/pad_fusion.cpp
Gleb Kazantaev 2a970a56d3 Enable common optimizations on MO (#6245)
* Enable common optimizations on MO

* Added tensor name tracking; updated tests

* Disable DilatedConvolution transform

* Fix TopK3 transformation

* Codestyle fix

* Update tensor name logic

* Fix scatter nd shape inference for dynamic shape

* Update FrameworkNode to propagate dynamic output shape

* Enable HSwish in MO that is missing in nGrpah

* Cleanup MO and IE code

* Fix review comments

* Fix unit test
2021-07-09 00:38:07 +03:00

467 lines
24 KiB
C++

// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <string>
#include <memory>
#include <queue>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <transformations/common_optimizations/pad_fusion.hpp>
#include <transformations/init_node_info.hpp>
#include <transformations/utils/utils.hpp>
#include <ngraph/pass/manager.hpp>
#include <common_test_utils/ngraph_test_utils.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
using namespace testing;
using namespace ngraph;
TEST(TransformationTests, PadElimination) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
set_tensor_name(data, "param");
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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
set_tensor_name(pad, "pad");
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
set_tensor_name(conv, "conv");
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
set_tensor_names(data, {"param", "pad"});
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(data, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1},
op::PadType::EXPLICIT);
set_tensor_name(conv, "conv");
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionAvgPoolExcludePad) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto avg_pool = std::make_shared<opset5::AvgPool>(pad, Strides{1, 1},
Shape{0, 0}, Shape{0, 0},
Shape{4, 4}, true, op::RoundingType::FLOOR);
f = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
auto avg_pool = std::make_shared<opset5::AvgPool>(data, Strides{1, 1},
Shape{1, 1}, Shape{2, 2}, Shape{4, 4},
false, op::RoundingType::FLOOR, op::PadType::EXPLICIT);
f_ref = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionAvgPoolDontExcludePad) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto avg_pool = std::make_shared<opset5::AvgPool>(pad, Strides{1, 1},
Shape{0, 0}, Shape{1, 1},
Shape{4, 4}, false, op::RoundingType::FLOOR);
f = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
auto avg_pool = std::make_shared<opset5::AvgPool>(data, Strides{1, 1},
Shape{1, 1}, Shape{3, 3}, Shape{4, 4},
false, op::RoundingType::FLOOR, op::PadType::EXPLICIT);
f_ref = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionMaxPool) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto max_pool = std::make_shared<opset5::MaxPool>(pad, Strides{1, 1},
Shape{0, 0}, Shape{1, 1}, Shape{4, 4});
f = std::make_shared<Function>(NodeVector{max_pool}, ParameterVector{data});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
auto max_pool = std::make_shared<opset5::MaxPool>(data, Strides{1, 1},
Shape{1, 1}, Shape{3, 3}, Shape{4, 4},
op::RoundingType::FLOOR, op::PadType::EXPLICIT);
f_ref = std::make_shared<Function>(NodeVector{max_pool}, ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionConvolution) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::i32, data_shape);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(data, filters, Strides{1, 1},
CoordinateDiff{1, 1}, CoordinateDiff{3, 3}, Shape{1, 1},
op::PadType::EXPLICIT);
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionConvolutionBackpropData) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
set_tensor_name(pad, "pad");
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
CoordinateDiff{4, 4}, CoordinateDiff{3, 3}, Shape{1, 1});
set_tensor_name(conv, "conv");
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(data, filters, Strides{1, 1},
CoordinateDiff{3, 3}, CoordinateDiff{1, 1}, Shape{1, 1});
set_tensor_name(conv, "conv");
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionGroupConvolution) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 4, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{1, 1, 4, 4, 4});
auto conv = std::make_shared<opset5::GroupConvolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{1, 1, 4, 4, 4});
auto conv = std::make_shared<opset5::GroupConvolution>(data, filters, Strides{1, 1},
CoordinateDiff{1, 1}, CoordinateDiff{3, 3}, Shape{1, 1},
op::PadType::EXPLICIT);
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, PadFusionGroupConvolutionBackpropData) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 4, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{2, 2, 1, 5, 5});
auto conv = std::make_shared<opset5::GroupConvolutionBackpropData>(pad, filters, Strides{1, 1},
CoordinateDiff{3, 2}, CoordinateDiff{4, 3}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{2, 2, 1, 5, 5});
auto conv = std::make_shared<opset5::GroupConvolutionBackpropData>(data, filters, Strides{1, 1},
CoordinateDiff{2, 1}, CoordinateDiff{1, 2}, Shape{1, 1});
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, NegativePadFusionNonConstantPadMode) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::REFLECT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::REFLECT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, NegativePadFusionNonZeroPadValue) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, NegativePadFusionPadForBatchSize) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, pad_value, op::PadMode::CONSTANT);
auto filters = std::make_shared<opset5::Parameter>(element::i32, Shape{1, 3, 4, 4});
auto conv = std::make_shared<opset5::Convolution>(pad, filters, Strides{1, 1},
CoordinateDiff{0, 0}, CoordinateDiff{1, 1}, Shape{1, 1});
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, NegativePadFusionAvgPoolExcludePadNonZeroPads) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto avg_pool = std::make_shared<opset5::AvgPool>(pad, Strides{1, 1},
Shape{0, 0}, Shape{1, 1},
Shape{4, 4}, true, op::RoundingType::FLOOR);
f = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
auto avg_pool = std::make_shared<opset5::AvgPool>(pad, Strides{1, 1},
Shape{0, 0}, Shape{1, 1},
Shape{4, 4}, true, op::RoundingType::FLOOR);
f_ref = std::make_shared<Function>(NodeVector{avg_pool}, ParameterVector{data});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, NegativePadFusionConvolutionBackpropDataTooSmallPad) {
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
Shape data_shape{1, 3, 14, 14};
{
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
set_tensor_name(data, "data");
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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
set_tensor_name(pad, "pad");
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1});
set_tensor_name(conv, "conv");
f = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
pass::Manager m;
m.register_pass<pass::InitNodeInfo>();
m.register_pass<pass::PadFusion>();
m.run_passes(f);
ASSERT_NO_THROW(check_rt_info(f));
}
{
auto data = std::make_shared<opset5::Parameter>(element::f32, data_shape);
set_tensor_name(data, "data");
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<opset5::Pad>(data, pads_begin, pads_end, op::PadMode::CONSTANT);
set_tensor_name(pad, "pad");
auto filters = std::make_shared<opset5::Parameter>(element::f32, Shape{3, 2, 5, 5});
auto conv = std::make_shared<opset5::ConvolutionBackpropData>(pad, filters, Strides{1, 1},
CoordinateDiff{1, 1}, CoordinateDiff{1, 1}, Shape{1, 1});
set_tensor_name(conv, "conv");
f_ref = std::make_shared<Function>(NodeVector{conv}, ParameterVector{data, filters});
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}