[SSR] Transformation mimicking oldSetBatchSize logic (#2597)

* [SSR] Transformation mimicking oldSetBatchSize logic

* Self-review

* gkazanta comments adressed

* support for opset1::Proposal and  opset4::Proposal. Use of pattern predicates

* Constant Folding during setBatchSize

* StridedSlice->Squeeze resolver

* SR tests added

* Squeeze->StridedSlice

* Comments

* getting rid of folding

* comment

* sq->ss transformation

* Revert "sq->ss transformation"

This reverts commit 9731b1cf52.

* Revert "comment"

This reverts commit a57b4f863e.

* Revert "getting rid of folding"

This reverts commit 85405dab0a.
This commit is contained in:
Evgenya Stepyreva
2020-10-26 20:51:59 +03:00
committed by GitHub
parent 8884791362
commit 40a4ae3cfa
24 changed files with 1142 additions and 59 deletions

View File

@@ -160,9 +160,9 @@ TEST(CNNNGraphImplTests, TestSetBatch) {
InferenceEngine::details::CNNNetworkNGraphImpl cnnNet(ngraph);
ASSERT_EQ(1, cnnNet.getBatchSize());
ASSERT_EQ(OK, cnnNet.setBatchSize(2, nullptr)); // triggers conversion
ASSERT_EQ(OK, cnnNet.setBatchSize(2, nullptr)); // must not trigger conversion
ASSERT_EQ(2, cnnNet.getBatchSize());
ASSERT_EQ(nullptr, cnnNet.getFunction());
ASSERT_NE(nullptr, cnnNet.getFunction());
}
TEST(CNNNGraphImplTests, TestGetBatchScalar) {
@@ -201,7 +201,35 @@ TEST(CNNNGraphImplTests, TestSetBatchScalar) {
InferenceEngine::details::CNNNetworkNGraphImpl cnnNet(ngraph);
ASSERT_EQ(1, cnnNet.getBatchSize());
ASSERT_EQ(PARAMETER_MISMATCH, cnnNet.setBatchSize(2, nullptr)); // triggers conversion
ASSERT_EQ(PARAMETER_MISMATCH, cnnNet.setBatchSize(2, nullptr)); // must not trigger conversion
}
TEST(CNNNGraphImplTests, TestGetBatchDynamic) {
std::shared_ptr<ngraph::Function> ngraph;
{
auto param = std::make_shared<ngraph::op::Parameter>(ngraph::element::Type_t::f32, ngraph::PartialShape{5, ngraph::Dimension::dynamic()});
auto relu = std::make_shared<ngraph::op::Relu>(param);
auto result = std::make_shared<ngraph::op::Result>(relu);
ngraph = std::make_shared<ngraph::Function>(ngraph::ResultVector{result}, ngraph::ParameterVector{param});
}
InferenceEngine::details::CNNNetworkNGraphImpl cnnNet(ngraph);
ASSERT_TRUE(cnnNet.getFunction()->get_parameters()[0]->get_partial_shape().is_dynamic());
ASSERT_EQ(5, cnnNet.getBatchSize());
}
TEST(CNNNGraphImplTests, TestSetBatchDynamic) {
std::shared_ptr<ngraph::Function> ngraph;
{
auto param = std::make_shared<ngraph::op::Parameter>(ngraph::element::Type_t::f32, ngraph::PartialShape::dynamic());
auto relu = std::make_shared<ngraph::op::Relu>(param);
auto result = std::make_shared<ngraph::op::Result>(relu);
ngraph = std::make_shared<ngraph::Function>(ngraph::ResultVector{result}, ngraph::ParameterVector{param});
}
InferenceEngine::details::CNNNetworkNGraphImpl cnnNet(ngraph);
ASSERT_EQ(1, cnnNet.getBatchSize());
ASSERT_EQ(PARAMETER_MISMATCH, cnnNet.setBatchSize(2, nullptr)); // must not trigger conversion
}
TEST(CNNNGraphImplTests, TestSaveAffinity) {

View File

@@ -0,0 +1,55 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <cpp/ie_cnn_network.h>
TEST(SmartReshapeTests, MimickingSBS) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 3, 4});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {6, -1}), true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{reshape}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({12, 4}));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 2, 3, 4}));
}
TEST(SmartReshapeTests, MimickingSBS_1) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 2, 3, 4});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, -1}), true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{reshape}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({2, 24}));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 2, 3, 4}));
}
TEST(SmartReshapeTests, MimickingSBS_2) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{2, 2, 3, 4});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {12, -1}), true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{reshape}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_NO_THROW(network.setBatchSize(1));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({6, 4}));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 2, 3, 4}));
}

View File

@@ -0,0 +1,73 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset1.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <cpp/ie_cnn_network.h>
TEST(SmartReshapeTests, Proposal1Scales) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input_0 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 24, 75, 128});
auto input_1 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 48, 75, 128});
auto input_2 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input_2, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {3}), true);
ngraph::op::ProposalAttrs attrs;
attrs.base_size = 256;
attrs.box_coordinate_scale = 10.0;
attrs.box_size_scale = 5.0;
attrs.clip_after_nms = false;
attrs.clip_before_nms = true;
attrs.feat_stride = 8;
attrs.framework = "tensorflow";
attrs.min_size = 1;
attrs.nms_thresh = 0.699999988079;
attrs.normalize = true;
attrs.post_nms_topn = 300;
attrs.pre_nms_topn = 2147483647;
attrs.ratio = {0.5, 1.0, 2.0};
attrs.scale = {0.25, 0.5, 1.0, 2.0};
auto proposal = std::make_shared<ngraph::opset1::Proposal>(input_0, input_1, reshape, attrs);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{proposal}, ngraph::ParameterVector{input_0, input_1, input_2});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({600, 5}));
}
TEST(SmartReshapeTests, Proposal4Scales) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input_0 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 24, 75, 128});
auto input_1 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 48, 75, 128});
auto input_2 = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 4});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input_2, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {-1}), true);
ngraph::op::ProposalAttrs attrs;
attrs.base_size = 256;
attrs.box_coordinate_scale = 10.0;
attrs.box_size_scale = 5.0;
attrs.clip_after_nms = false;
attrs.clip_before_nms = true;
attrs.feat_stride = 8;
attrs.framework = "tensorflow";
attrs.min_size = 1;
attrs.nms_thresh = 0.699999988079;
attrs.normalize = true;
attrs.post_nms_topn = 300;
attrs.pre_nms_topn = 2147483647;
attrs.ratio = {0.5, 1.0, 2.0};
attrs.scale = {0.25, 0.5, 1.0, 2.0};
auto proposal = std::make_shared<ngraph::opset5::Proposal>(input_0, input_1, reshape, attrs);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{proposal}, ngraph::ParameterVector{input_0, input_1, input_2});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({600, 5}));
}

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <cpp/ie_cnn_network.h>
TEST(SmartReshapeTests, Reshape1d) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic());
input->set_friendly_name("input");
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {5}), true);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{reshape}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible(ngraph::PartialShape::dynamic()));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({5}));
ASSERT_NO_THROW(network.reshape({{"input", {1, 3, 300, 300}}}));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({270000}));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3, 300, 300}));
}
TEST(SmartReshapeTests, Reshape1d_negative) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::PartialShape::dynamic());
auto pattern = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::i64, ngraph::Shape{1});
input->set_friendly_name("input");
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, pattern, false);
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{reshape}, ngraph::ParameterVector{input, pattern});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible(ngraph::PartialShape::dynamic()));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().is_dynamic());
ASSERT_NO_THROW(network.reshape({{"input", {1, 3, 300, 300}}}));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({270000}));
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3, 300, 300}));
ASSERT_FALSE(network.getFunction()->get_parameters()[1]->get_output_target_inputs(0).empty());
}

View File

@@ -0,0 +1,176 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <cpp/ie_cnn_network.h>
TEST(SmartReshapeTests, SS_Squeeze) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3});
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
input,
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, 1}),
std::vector<int64_t>{1, 1}, std::vector<int64_t>{1, 1});
auto squeeze = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {0}));
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{squeeze}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3}));
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 3}));
}
TEST(SmartReshapeTests, SS_Squeeze_mask_use_negative) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3});
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
input,
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, 1}),
std::vector<int64_t>{1, 1}, std::vector<int64_t>{1, 1}, std::vector<int64_t>{0, 1});
auto squeeze = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {0}));
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{squeeze}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({1, 3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3}));
ASSERT_ANY_THROW(network.setBatchSize(2));
}
TEST(SmartReshapeTests, SS_Squeeze_negative_stride_negative) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3});
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
input,
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {-1, -1}),
std::vector<int64_t>{1, 1}, std::vector<int64_t>{1, 1});
auto squeeze = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {0}));
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{squeeze}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3}));
ASSERT_ANY_THROW(network.setBatchSize(2));
}
TEST(SmartReshapeTests, SS_SharedSqueezes) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3});
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
input,
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, 1}),
std::vector<int64_t>{1, 1}, std::vector<int64_t>{1, 1});
auto squeeze_1 = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {0}));
auto squeeze_2 = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {1}, {0}));
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{squeeze_1, squeeze_2}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3}));
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 3}));
}
TEST(SmartReshapeTests, SS_SqueezeNegativeAxes) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3, 1, 8, 1, 2});
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
input,
ngraph::opset5::Constant::create(ngraph::element::i64, {6}, {0, 0, 0, 0, 0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {6}, {0, 0, 0, 0, 0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {6}, {1, 1, 1, 1, 1, 1}),
std::vector<int64_t>{1, 1, 1, 1, 1, 1}, std::vector<int64_t>{1, 1, 1, 1, 1, 1});
auto squeeze = std::make_shared<ngraph::opset5::Squeeze>(ss, ngraph::opset5::Constant::create(ngraph::element::i64, {3}, {-2, 0, -4}));
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{squeeze}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3, 8, 2})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3, 1, 8, 1, 2}));
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3, 8, 2})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 3, 1, 8, 1, 2}));
}
TEST(SmartReshapeTests, Squeeze_SSNegativeAxes) {
std::shared_ptr<ngraph::Function> f(nullptr);
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3, 1, 8, 1, 2});
auto squeeze = std::make_shared<ngraph::opset5::Squeeze>(input, ngraph::opset5::Constant::create(ngraph::element::i64, {3}, {-2, 0, -4}));
auto ss = std::make_shared<ngraph::opset5::StridedSlice>(
squeeze,
ngraph::opset5::Constant::create(ngraph::element::i64, {3}, {0, 0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {3}, {0, 0, 0}),
ngraph::opset5::Constant::create(ngraph::element::i64, {3}, {1, 1, 1}),
std::vector<int64_t>{1, 1, 1}, std::vector<int64_t>{1, 1, 1});
f = std::make_shared<ngraph::Function>(ngraph::NodeVector{ss}, ngraph::ParameterVector{input});
}
InferenceEngine::CNNNetwork network(f);
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3, 8, 2})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({1, 3, 1, 8, 1, 2}));
ASSERT_NO_THROW(network.setBatchSize(2));
ASSERT_TRUE(network.getFunction()->get_results()[0]->get_output_partial_shape(0).compatible({3, 8, 2})) <<
network.getFunction()->get_results()[0]->get_output_partial_shape(0);
ASSERT_TRUE(network.getFunction()->get_parameters()[0]->get_partial_shape().compatible({2, 3, 1, 8, 1, 2}));
}