[dynamism][CPU] Reshape1DOps transformation: dynamic shapes support (#7307)

* [CPUTransformations] Reshape1DOps: dynamic shapes support

* [TESTS] Reshape1DOps tests

* Reshape1D: functions moved to namespace

* postreview fixes

* postreview fixes

* [CPU] Reshape1DOps: reshapes with shapeOf->gather sequences is replaced by unsqueeze/squeeze
This commit is contained in:
Vladislav Golubev 2021-10-21 11:15:23 +03:00 committed by GitHub
parent 1b1e0e7553
commit 55a0e8332b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 567 additions and 40 deletions

View File

@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <numeric>
#include <ngraph/opsets/opset1.hpp> #include <ngraph/opsets/opset1.hpp>
#include <ngraph/rt_info.hpp> #include <ngraph/rt_info.hpp>
@ -27,10 +28,9 @@ std::shared_ptr<ngraph::Node> convert(const ngraph::Output<ngraph::Node> & data,
new_pads_begin.insert(new_pads_begin.begin(), 0); new_pads_begin.insert(new_pads_begin.begin(), 0);
new_pad_end.insert(new_pad_end.begin(), 0); new_pad_end.insert(new_pad_end.begin(), 0);
ngraph::Shape new_weights_shape(node->input_value(1).get_shape()); const size_t weights_rank = node->get_input_partial_shape(1).size();
new_weights_shape.insert(new_weights_shape.begin() + new_weights_shape.size() - 1, 1); const auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { weights_rank - 1 });
auto weights = ngraph::op::util::reshapeTo(node->input_value(1), new_weights_shape); const auto weights = ngraph::op::util::make_try_fold<ngraph::opset1::Unsqueeze>(node->input_value(1), unsqueeze_const);
new_ops.push_back(weights); new_ops.push_back(weights);
if (std::dynamic_pointer_cast<ngraph::op::TypeRelaxedBase>(node)) { if (std::dynamic_pointer_cast<ngraph::op::TypeRelaxedBase>(node)) {
@ -101,20 +101,16 @@ std::shared_ptr<ngraph::Node> convert(const ngraph::Output<ngraph::Node> & data,
ngraph::matcher_pass_callback get_callback() { ngraph::matcher_pass_callback get_callback() {
return [](ngraph::pattern::Matcher& m) { return [](ngraph::pattern::Matcher& m) {
auto node = m.get_match_root(); auto node = m.get_match_root();
if (node->input(0).get_partial_shape().rank().get_length() != 3) { const auto input_rank = node->get_input_partial_shape(0).size();
if (input_rank != 3) {
return false; return false;
} }
// Insert H dimension equal to 1
auto input_shape = node->input(0).get_shape();
auto output_shape = node->output(0).get_shape();
input_shape.insert(input_shape.begin() + 2, 1);
ngraph::NodeVector new_ops; ngraph::NodeVector new_ops;
// Reshape(input_shape)->Op->Reshape(output_shape) // Update pshape from [N, C, W] to [N, C, 1, W]
ngraph::Output<ngraph::Node> last = ngraph::op::util::reshapeTo(node->input_value(0), input_shape); const auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { input_rank - 1 });
ngraph::Output<ngraph::Node> last = std::make_shared<ngraph::opset1::Unsqueeze>(node->input_value(0), unsqueeze_const);
last.get_node_shared_ptr()->set_friendly_name(node->get_friendly_name() + "/reshape_begin"); last.get_node_shared_ptr()->set_friendly_name(node->get_friendly_name() + "/reshape_begin");
new_ops.push_back(last.get_node_shared_ptr()); new_ops.push_back(last.get_node_shared_ptr());
@ -134,38 +130,47 @@ ngraph::matcher_pass_callback get_callback() {
new_ops.push_back(last.get_node_shared_ptr()); new_ops.push_back(last.get_node_shared_ptr());
// if convolution is followed by add we need to replace add before output reshape to fuse conv+bias on plug-in side // if convolution is followed by add we need to replace add before output reshape to fuse conv+bias on plug-in side
std::shared_ptr<ngraph::Node> addToReplace = nullptr; std::shared_ptr<ngraph::Node> add_to_replace = nullptr;
std::shared_ptr<ngraph::Node> reshapedAdd = nullptr; std::shared_ptr<ngraph::Node> reshaped_add = nullptr;
ngraph::NodeVector biasOps; ngraph::NodeVector bias_ops;
if (std::dynamic_pointer_cast<ngraph::opset1::Convolution>(node) || std::dynamic_pointer_cast<ngraph::opset1::GroupConvolution>(node)) { if (std::dynamic_pointer_cast<ngraph::opset1::Convolution>(node) || std::dynamic_pointer_cast<ngraph::opset1::GroupConvolution>(node)) {
ngraph::Shape expectedShape = ngraph::Shape(node->get_output_shape(0).size(), 1); auto out_pshape = node->get_output_partial_shape(0);
expectedShape[1] = node->get_output_shape(0)[1]; const auto dst_nodes = node->get_output_target_inputs(0);
const auto dstNodes = node->get_output_target_inputs(0);
if (dstNodes.size() == 1) { // we can also reshape biases if possible
addToReplace = dstNodes.begin()->get_node()->shared_from_this(); if (dst_nodes.size() == 1 && out_pshape.rank().is_static() && out_pshape.rank().get_length() > 2 && out_pshape[1].is_static()) {
if (std::dynamic_pointer_cast<ngraph::opset1::Add>(addToReplace) && auto channel = node->get_output_partial_shape(0)[1];
std::dynamic_pointer_cast<ngraph::opset1::Constant>(addToReplace->input(1).get_source_output().get_node_shared_ptr()) && ngraph::Shape expected_shape = ngraph::Shape(input_rank, 1);
addToReplace->get_input_shape(1) == expectedShape) { expected_shape[1] = channel.get_length();
ngraph::Shape newBiasShape(addToReplace->get_input_shape(1));
newBiasShape.push_back(1); add_to_replace = dst_nodes.begin()->get_node()->shared_from_this();
auto newBias = ngraph::op::util::reshapeTo(addToReplace->input_value(1), newBiasShape); if (std::dynamic_pointer_cast<ngraph::opset1::Add>(add_to_replace) &&
reshapedAdd = std::make_shared<ngraph::opset1::Add>(last, newBias); std::dynamic_pointer_cast<ngraph::opset1::Constant>(add_to_replace->get_input_node_shared_ptr(1)) &&
reshapedAdd->set_friendly_name(addToReplace->get_friendly_name() + "/new"); add_to_replace->get_input_shape(1) == expected_shape) {
biasOps.push_back(newBias); ngraph::Shape new_shape(add_to_replace->get_input_shape(1));
biasOps.push_back(reshapedAdd); new_shape.push_back(1);
auto new_shape_const = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{ new_shape.size() }, new_shape);
auto new_bias = ngraph::op::util::make_try_fold<ngraph::opset1::Reshape>(add_to_replace->input_value(1), new_shape_const, true);
reshaped_add = std::make_shared<ngraph::opset1::Add>(last, new_bias);
reshaped_add->set_friendly_name(add_to_replace->get_friendly_name() + "/new");
bias_ops.push_back(new_bias);
bias_ops.push_back(reshaped_add);
} }
} }
} }
if (reshapedAdd != nullptr) { if (reshaped_add != nullptr) {
ngraph::replace_node(node, last.get_node_shared_ptr()); ngraph::replace_node(node, last.get_node_shared_ptr());
ngraph::copy_runtime_info(node, new_ops); ngraph::copy_runtime_info(node, new_ops);
last = reshapedAdd; last = reshaped_add;
node = addToReplace; node = add_to_replace;
new_ops = biasOps; new_ops = bias_ops;
} }
last = ngraph::op::util::reshapeTo(last, output_shape); // Update pshape from [N, C, 1, W] to [N, C, W]
const auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { input_rank - 1 });
last = std::make_shared<ngraph::opset1::Squeeze>(last, squeeze_const);
last.get_node_shared_ptr()->set_friendly_name(node->get_friendly_name()); last.get_node_shared_ptr()->set_friendly_name(node->get_friendly_name());
ngraph::replace_node(node, last.get_node_shared_ptr()); ngraph::replace_node(node, last.get_node_shared_ptr());
ngraph::copy_runtime_info(node, new_ops); ngraph::copy_runtime_info(node, new_ops);
@ -177,7 +182,9 @@ ngraph::matcher_pass_callback get_callback() {
NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DConvolution, "Reshape1DConvolution", 0); NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DConvolution, "Reshape1DConvolution", 0);
MKLDNNPlugin::Reshape1DConvolution::Reshape1DConvolution() { MKLDNNPlugin::Reshape1DConvolution::Reshape1DConvolution() {
auto conv = ngraph::pattern::wrap_type<ngraph::opset1::Convolution>(ngraph::pattern::has_static_shape()); auto activations = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto weights = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto conv = ngraph::pattern::wrap_type<ngraph::opset1::Convolution>({ activations, weights });
auto m = std::make_shared<ngraph::pattern::Matcher>(conv, "Reshape1DConvolution"); auto m = std::make_shared<ngraph::pattern::Matcher>(conv, "Reshape1DConvolution");
this->register_matcher(m, Reshape1DOps::get_callback()); this->register_matcher(m, Reshape1DOps::get_callback());
} }
@ -185,7 +192,9 @@ MKLDNNPlugin::Reshape1DConvolution::Reshape1DConvolution() {
NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DGroupConvolution, "Reshape1DGroupConvolution", 0); NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DGroupConvolution, "Reshape1DGroupConvolution", 0);
MKLDNNPlugin::Reshape1DGroupConvolution::Reshape1DGroupConvolution() { MKLDNNPlugin::Reshape1DGroupConvolution::Reshape1DGroupConvolution() {
auto group_conv = ngraph::pattern::wrap_type<ngraph::opset1::GroupConvolution>(ngraph::pattern::has_static_shape()); auto activations = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto weights = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto group_conv = ngraph::pattern::wrap_type<ngraph::opset1::GroupConvolution>({ activations, weights });
auto m = std::make_shared<ngraph::pattern::Matcher>(group_conv, "Reshape1DGroupConvolution"); auto m = std::make_shared<ngraph::pattern::Matcher>(group_conv, "Reshape1DGroupConvolution");
this->register_matcher(m, Reshape1DOps::get_callback()); this->register_matcher(m, Reshape1DOps::get_callback());
} }
@ -193,7 +202,8 @@ MKLDNNPlugin::Reshape1DGroupConvolution::Reshape1DGroupConvolution() {
NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DAvgPool, "Reshape1DAvgPool", 0); NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DAvgPool, "Reshape1DAvgPool", 0);
MKLDNNPlugin::Reshape1DAvgPool::Reshape1DAvgPool() { MKLDNNPlugin::Reshape1DAvgPool::Reshape1DAvgPool() {
auto pool = ngraph::pattern::wrap_type<ngraph::opset1::AvgPool>(ngraph::pattern::has_static_shape()); auto input = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto pool = ngraph::pattern::wrap_type<ngraph::opset1::AvgPool>({ input });
auto m = std::make_shared<ngraph::pattern::Matcher>(pool, "Reshape1DAvgPool"); auto m = std::make_shared<ngraph::pattern::Matcher>(pool, "Reshape1DAvgPool");
this->register_matcher(m, Reshape1DOps::get_callback()); this->register_matcher(m, Reshape1DOps::get_callback());
} }
@ -201,7 +211,8 @@ MKLDNNPlugin::Reshape1DAvgPool::Reshape1DAvgPool() {
NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DMaxPool, "Reshape1DMaxPool", 0); NGRAPH_RTTI_DEFINITION(MKLDNNPlugin::Reshape1DMaxPool, "Reshape1DMaxPool", 0);
MKLDNNPlugin::Reshape1DMaxPool::Reshape1DMaxPool() { MKLDNNPlugin::Reshape1DMaxPool::Reshape1DMaxPool() {
auto pool = ngraph::pattern::wrap_type<ngraph::opset1::MaxPool>(ngraph::pattern::has_static_shape()); auto input = ngraph::pattern::any_input(ngraph::pattern::has_static_rank());
auto pool = ngraph::pattern::wrap_type<ngraph::opset1::MaxPool>({ input });
auto m = std::make_shared<ngraph::pattern::Matcher>(pool, "Reshape1DMaxPool"); auto m = std::make_shared<ngraph::pattern::Matcher>(pool, "Reshape1DMaxPool");
this->register_matcher(m, Reshape1DOps::get_callback()); this->register_matcher(m, Reshape1DOps::get_callback());
} }

View File

@ -0,0 +1,516 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <string>
#include <memory>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset1.hpp>
#include <ngraph_transformations/reshape_1d_ops.hpp>
#include <transformations/init_node_info.hpp>
#include <transformations/utils/utils.hpp>
#include <ngraph_ops/type_relaxed.hpp>
#include <ngraph/pass/manager.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
using namespace testing;
using namespace MKLDNNPlugin;
TEST(TransformationTests, Reshape1DAvgPoolTest1) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 });
auto avgPool = std::make_shared<ngraph::opset1::AvgPool>(
input,
ngraph::Strides{ 1 },
ngraph::Shape{ 1 },
ngraph::Shape{ 0 },
ngraph::Shape{ 2 },
true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DAvgPool>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(input, unsqueeze_const);
auto avg_pool = std::make_shared<ngraph::opset1::AvgPool>(
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<ngraph::opset1::Squeeze>(avg_pool, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto avgPool = std::make_shared<ngraph::opset1::AvgPool>(
input,
ngraph::Strides{ 1 },
ngraph::Shape{ 1 },
ngraph::Shape{ 0 },
ngraph::Shape{ 2 },
true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DAvgPool>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto unsqueeze = std::make_shared<ngraph::opset1::Unsqueeze>(input, unsqueeze_const);
auto avg_pool = std::make_shared<ngraph::opset1::AvgPool>(
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<ngraph::opset1::Squeeze>(avg_pool, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{ 1, 3, 16, 16 });
auto avgPool = std::make_shared<ngraph::opset1::AvgPool>(
input,
ngraph::Strides{ 1, 1 },
ngraph::Shape{ 1, 1 },
ngraph::Shape{ 0, 0 },
ngraph::Shape{ 2, 2 },
true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ avgPool }, ngraph::ParameterVector{ input });
f_ref = f;
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DAvgPool>();
m.run_passes(f);
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, Reshape1DMaxPoolTest1) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{ 1, 3, 16 });
auto max_pool = std::make_shared<ngraph::opset1::MaxPool>(
input,
ngraph::Strides{ 1 },
ngraph::Shape{ 1 },
ngraph::Shape{ 0 },
ngraph::Shape{ 2 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DMaxPool>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(input, unsqueeze_const);
auto max_pool = std::make_shared<ngraph::opset1::MaxPool>(
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<ngraph::opset1::Squeeze>(max_pool, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto max_pool = std::make_shared<ngraph::opset1::MaxPool>(
input,
ngraph::Strides{ 1 },
ngraph::Shape{ 1 },
ngraph::Shape{ 0 },
ngraph::Shape{ 2 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DMaxPool>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto unsqueeze = std::make_shared<ngraph::opset1::Unsqueeze>(input, unsqueeze_const);
auto max_pool = std::make_shared<ngraph::opset1::MaxPool>(
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<ngraph::opset1::Squeeze>(max_pool, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic());
auto max_pool = std::make_shared<ngraph::opset1::MaxPool>(
input,
ngraph::Strides{ 1 },
ngraph::Shape{ 1 },
ngraph::Shape{ 0 },
ngraph::Shape{ 2 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ max_pool }, ngraph::ParameterVector{ input });
f_ref = f;
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DMaxPool>();
m.run_passes(f);
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}
TEST(TransformationTests, Reshape1DConvolutionTest1) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Convolution>(
input,
weights,
ngraph::Strides{ 1 },
ngraph::CoordinateDiff{ 0 },
ngraph::CoordinateDiff{ 0 },
ngraph::Strides{ 1 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ convolution }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(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<ngraph::opset1::Convolution>(
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<ngraph::opset1::Squeeze>(convolution, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Convolution>(
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<ngraph::opset1::Add>(convolution, bias_const);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ bias }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(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<ngraph::opset1::Convolution>(
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<ngraph::opset1::Add>(convolution, bias_const);
auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto squeeze = std::make_shared<ngraph::opset1::Squeeze>(bias, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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::op::TypeRelaxed<ngraph::opset1::Convolution>>(
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::Function>(ngraph::NodeVector{ relaxed_convolution }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(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::op::TypeRelaxed<ngraph::opset1::Convolution>>(
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<ngraph::opset1::Squeeze>(relaxed_convolution, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Convolution>(
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<ngraph::opset1::Add>(convolution, bias_const);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ bias }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto unsqueeze = std::make_shared<ngraph::opset1::Unsqueeze>(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<ngraph::opset1::Convolution>(
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<ngraph::opset1::Add>(convolution, bias_const);
auto squeeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto squeeze = std::make_shared<ngraph::opset1::Squeeze>(bias, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::GroupConvolution>(
input,
weights,
ngraph::Strides{ 1 },
ngraph::CoordinateDiff{ 0 },
ngraph::CoordinateDiff{ 0 },
ngraph::Strides{ 1 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ group_convolution }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DGroupConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::Unsqueeze>(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<ngraph::opset1::GroupConvolution>(
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<ngraph::opset1::Squeeze>(group_convolution, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(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<ngraph::Function> f(nullptr), f_ref(nullptr);
{
auto input = std::make_shared<ngraph::opset1::Parameter>(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<ngraph::opset1::GroupConvolution>(
input,
weights,
ngraph::Strides{ 1 },
ngraph::CoordinateDiff{ 0 },
ngraph::CoordinateDiff{ 0 },
ngraph::Strides{ 1 });
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ group_convolution }, ngraph::ParameterVector{ input });
ngraph::pass::Manager m;
m.register_pass<ngraph::pass::InitNodeInfo>();
m.register_pass<Reshape1DGroupConvolution>();
m.run_passes(f);
}
{
auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic(3));
auto unsqueeze_const = ngraph::opset1::Constant::create(ngraph::element::i32, { 1 }, { 2 });
auto unsqueeze = std::make_shared<ngraph::opset1::Unsqueeze>(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<ngraph::opset1::GroupConvolution>(
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<ngraph::opset1::Squeeze>(group_convolution, squeeze_const);
f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ squeeze }, ngraph::ParameterVector{ input });
}
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}