Added RemoveConcatZeroDimInput and RemoveMultiSubGraphOpDanglingParams transformations (#8035)
* fix expand_onnx_functions * refactor + unit test * fixed function in function case * fixed expand_onnx_functions * fixed default value of shape in ValueInfo * enable xpass model * changed MergeFrom to Swap * added xfail with missing test data * added more unit tests * styles applied * used std::rotate, review remarks * removed debug code * after offline discussion remarks * fix checking input/output names on Windows * names comparator refactor * replace regex with custom comparison * review remarks * added RemoveConcatZeroDimInput transformation * added RemoveLoopDanglingParameters transformation * chage place of passes during replace * missing comment * code refactor + unit tests * remove unused headers * used std::any_of in RemoveConcatZeroDimInput * changed headers and namespaces to new ov convention * used std::any_of in RemoveConcatZeroDimInput * RemoveLoopDanglingParameters refactored * changed names to RemoveMultiSubGraphOpDanglingParams * handling multi-body cases * Handling If case during RemoveMultiSubGraphOpDanglingParams * comments and names refactor * More tests for If and TensorIterator * handle removing dagling param from one body and update all descriptors * fixed test * revert if change * moved RemoveConcatZeroDimInput and RemoveMultiSubGraphOpDanglingParams to NopElimantion * return false if node is not replaced * added validate_nodes_and_infer_types * Revert "moved RemoveConcatZeroDimInput and RemoveMultiSubGraphOpDanglingParams to NopElimantion" + remarks * review remarks * review remarks * fixed subgraph rtti * adjust passes to new structure
This commit is contained in:
parent
1b0ff2979c
commit
461d6e8a1d
@ -0,0 +1,140 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <openvino/core/function.hpp>
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
#include <openvino/pass/manager.hpp>
|
||||
#include <transformations/common_optimizations/remove_concat_zero_dim_input.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimInputStaticShape) {
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 2, 3});
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 2, 3});
|
||||
int64_t axis = 1;
|
||||
{
|
||||
auto input2 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 0, 3});
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input2, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input2, input3});
|
||||
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input3}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input3});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimInputSubgraph) {
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 2, 3});
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 2, 3});
|
||||
int64_t axis = 1;
|
||||
{
|
||||
auto in_abs = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 0, 3});
|
||||
auto abs = std::make_shared<ov::opset8::Abs>(in_abs);
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, abs, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input3, in_abs});
|
||||
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input3}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input3});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimInputSubgraph2) {
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, ov::Dimension::dynamic(), 3});
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 2, 3});
|
||||
auto abs = std::make_shared<ov::opset8::Abs>(input1);
|
||||
int64_t axis = 1;
|
||||
{
|
||||
auto in_mul = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape{1, 0, 3});
|
||||
auto mul = std::make_shared<ov::opset8::Multiply>(in_mul, abs);
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{mul, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input3, in_mul});
|
||||
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input3}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input3});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimInputPartiallyKnowShape) {
|
||||
std::shared_ptr<ov::Function> f(nullptr), f_ref(nullptr);
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape::dynamic());
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape::dynamic());
|
||||
int64_t axis = 0;
|
||||
{
|
||||
auto input2 = std::make_shared<ov::opset8::Parameter>(ov::element::f32,
|
||||
ov::PartialShape{0, ov::Dimension::dynamic(), ov::Dimension::dynamic()});
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input2, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input2, input3});
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input3}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input3});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimInputDynamicRank) {
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape::dynamic());
|
||||
auto input2 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape::dynamic());
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32, ov::PartialShape::dynamic());
|
||||
int64_t axis = 0;
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input2, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input2, input3});
|
||||
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input2, input3}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input2, input3});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveConcatZeroDimTwoInputs) {
|
||||
auto input1 = std::make_shared<ov::opset8::Parameter>(ov::element::f32,
|
||||
ov::PartialShape{1, ov::Dimension::dynamic(), ov::Dimension::dynamic()});
|
||||
int64_t axis = 1;
|
||||
{
|
||||
auto input2 = std::make_shared<ov::opset8::Parameter>(ov::element::f32,
|
||||
ov::PartialShape{1, 0, ov::Dimension::dynamic()});
|
||||
auto input3 = std::make_shared<ov::opset8::Parameter>(ov::element::f32,
|
||||
ov::PartialShape{1, ov::Dimension::dynamic(), 0});
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1, input2, input3}, axis);
|
||||
|
||||
function = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1, input2, input3});
|
||||
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
}
|
||||
|
||||
{
|
||||
auto concat = std::make_shared<ov::opset8::Concat>(ov::OutputVector{input1}, axis);
|
||||
function_ref = std::make_shared<ov::Function>(ov::NodeVector{concat}, ov::ParameterVector{input1});
|
||||
}
|
||||
}
|
@ -0,0 +1,423 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include <openvino/core/function.hpp>
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <transformations/common_optimizations/remove_multi_subgraph_op_dangling_params.hpp>
|
||||
#include <transformations/common_optimizations/remove_concat_zero_dim_input.hpp>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ov;
|
||||
using namespace ov::opset8;
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveLoopDanglingParameters) {
|
||||
auto trip_count = std::make_shared<Constant>(element::i64, Shape{}, 10);
|
||||
auto condition = std::make_shared<Constant>(element::boolean, Shape{}, true);
|
||||
|
||||
auto a = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ai = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto b = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto bi = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
|
||||
auto mul = std::make_shared<Multiply>(bi, bi);
|
||||
auto abs = std::make_shared<Abs>(mul);
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{ai, bi});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(ai, a);
|
||||
loop->set_invariant_input(bi, b);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{bi});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(bi, b);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function_ref = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveLoopManyDanglingParameters) {
|
||||
auto trip_count = std::make_shared<Constant>(element::i64, Shape{}, 10);
|
||||
auto condition = std::make_shared<Constant>(element::boolean, Shape{}, true);
|
||||
|
||||
auto a = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ai = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto b = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto bi = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto c = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ci = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
|
||||
auto mul = std::make_shared<Multiply>(bi, bi);
|
||||
auto abs = std::make_shared<Abs>(mul);
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{ai, bi, ci});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(ai, a);
|
||||
loop->set_invariant_input(bi, b);
|
||||
loop->set_invariant_input(ci, c);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b, c});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{bi});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(bi, b);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function_ref = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b, c});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveLoopManyDanglingParameters2) {
|
||||
auto trip_count = std::make_shared<Constant>(element::i64, Shape{}, 10);
|
||||
auto condition = std::make_shared<Constant>(element::boolean, Shape{}, true);
|
||||
|
||||
auto a = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ai = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto b = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto bi = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto c = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ci = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto d = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto di = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
|
||||
auto mul = std::make_shared<Multiply>(bi, bi);
|
||||
auto sub = std::make_shared<Multiply>(mul, di);
|
||||
auto abs = std::make_shared<Abs>(sub);
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{ai, bi, ci, di});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(ai, a);
|
||||
loop->set_invariant_input(bi, b);
|
||||
loop->set_invariant_input(ci, c);
|
||||
loop->set_invariant_input(di, d);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b, c, d});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, abs}, ParameterVector{bi, di});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(bi, b);
|
||||
loop->set_invariant_input(di, d);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(abs));
|
||||
function_ref = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b, c, d});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveLoopDanglingParametersIfConcatEmptyTensor) {
|
||||
auto trip_count = std::make_shared<Constant>(element::i64, Shape{}, 10);
|
||||
auto condition = std::make_shared<Constant>(element::boolean, Shape{}, true);
|
||||
|
||||
auto a = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto ai = std::make_shared<Parameter>(element::f32, Shape{2, 2});
|
||||
auto b = std::make_shared<Parameter>(element::f32, Shape{0, 2}); // empty tensor
|
||||
auto bi = std::make_shared<Parameter>(element::f32, Shape{0, 2});
|
||||
{
|
||||
auto concat = std::make_shared<Concat>(NodeVector{ai, bi}, 0);
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, concat}, ParameterVector{ai, bi});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(ai, a);
|
||||
loop->set_invariant_input(bi, b);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(concat));
|
||||
function = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b});
|
||||
|
||||
manager.register_pass<pass::RemoveConcatZeroDimInput>();
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto concat = std::make_shared<Concat>(NodeVector{ai}, 0);
|
||||
auto body = std::make_shared<Function>(OutputVector{condition, concat}, ParameterVector{ai});
|
||||
auto loop = std::make_shared<Loop>(trip_count, condition);
|
||||
loop->set_special_body_ports({-1, 0});
|
||||
loop->set_function(body);
|
||||
loop->set_invariant_input(ai, a);
|
||||
|
||||
auto loop_res = std::make_shared<Result>(loop->get_iter_value(concat));
|
||||
function_ref = std::make_shared<Function>(OutputVector{loop_res}, ParameterVector{a, b});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveIfDanglingParametersFromBodiesAndInputs) {
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{3, 4, 1});
|
||||
auto cond = std::make_shared<Constant>(element::boolean, Shape{1}, true);
|
||||
|
||||
auto Xte = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Yte = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto then_op = std::make_shared<Add>(Xte, Xte);
|
||||
auto then_op_res = std::make_shared<Result>(then_op);
|
||||
|
||||
auto else_op = std::make_shared<Maximum>(Xte, Xte);
|
||||
auto else_op_res = std::make_shared<Result>(else_op);
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xte, Yte});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xte, Yte});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xte, Xte);
|
||||
if_op->set_input(Y, Yte, Yte);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xte});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xte});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xte, Xte);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveIfDanglingParametersOnlyFromBodies) {
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{3, 4, 1});
|
||||
auto cond = std::make_shared<Constant>(element::boolean, Shape{1}, true);
|
||||
|
||||
auto Xt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Yt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto then_op = std::make_shared<Add>(Xt, Xt);
|
||||
auto then_op_res = std::make_shared<Result>(then_op);
|
||||
|
||||
auto Xe = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Ye = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto else_op = std::make_shared<Maximum>(Ye, Ye);
|
||||
auto else_op_res = std::make_shared<Result>(else_op);
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xt, Yt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xe, Ye});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xt, Xe);
|
||||
if_op->set_input(Y, Yt, Ye);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Ye});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xt, nullptr);
|
||||
if_op->set_input(Y, nullptr, Ye);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveIfManyDanglingParameters) {
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{3, 4, 1});
|
||||
auto Z = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto cond = std::make_shared<Constant>(element::boolean, Shape{1}, true);
|
||||
|
||||
auto Xt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Yt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Zt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto then_op = std::make_shared<Add>(Xt, Zt);
|
||||
auto then_op_res = std::make_shared<Result>(then_op);
|
||||
|
||||
auto Xe = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Ye = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Ze = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto else_op = std::make_shared<Maximum>(Xe, Xe);
|
||||
auto else_op_res = std::make_shared<Result>(else_op);
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xt, Yt, Zt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xe, Ye, Ze});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xt, Xe);
|
||||
if_op->set_input(Y, Yt, Ye);
|
||||
if_op->set_input(Z, Zt, Ze);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xt, Zt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xe});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xt, Xe);
|
||||
if_op->set_input(Z, Zt, nullptr);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveIfDanglingParamFromOneBodyAndUpdateAllDescriptions) {
|
||||
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto Z = std::make_shared<Parameter>(element::f32, Shape{2, 4, 1});
|
||||
auto cond = std::make_shared<Constant>(element::boolean, Shape{1}, true);
|
||||
|
||||
auto Xt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Yt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Zt = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto then_op = std::make_shared<Add>(Zt, Zt);
|
||||
auto then_op_res = std::make_shared<Result>(then_op);
|
||||
|
||||
auto Xe = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto Ze = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
|
||||
|
||||
auto else_op = std::make_shared<Add>(std::make_shared<Maximum>(Xe, Ze), Ze);
|
||||
auto else_op_res = std::make_shared<Result>(else_op);
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Xt, Yt, Zt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xe, Ze});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, Xt, Xe);
|
||||
if_op->set_input(Y, Yt, nullptr);
|
||||
if_op->set_input(Z, Zt, Ze);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto then_body = std::make_shared<Function>(OutputVector{then_op_res}, ParameterVector{Zt});
|
||||
auto else_body = std::make_shared<Function>(OutputVector{else_op_res}, ParameterVector{Xe, Ze});
|
||||
auto if_op = std::make_shared<If>(cond);
|
||||
if_op->set_then_body(then_body);
|
||||
if_op->set_else_body(else_body);
|
||||
if_op->set_input(X, nullptr, Xe);
|
||||
if_op->set_input(Z, Zt, Ze);
|
||||
auto res = if_op->set_output(then_op_res, else_op_res);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveTensorIteratorDanglingParameter) {
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{32, 40, 10});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{32, 40, 10});
|
||||
auto M = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
|
||||
auto Xi = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto Yi = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto M_body = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto Zo = std::make_shared<Abs>(std::make_shared<Add>(Xi, Yi));
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{Zo}, ParameterVector{Xi, Yi, M_body});
|
||||
auto tensor_iterator = std::make_shared<TensorIterator>();
|
||||
tensor_iterator->set_body(body);
|
||||
tensor_iterator->set_sliced_input(Xi, X, 0, 2, 2, 39, 1);
|
||||
tensor_iterator->set_sliced_input(Yi, Y, 0, 2, 2, -1, 1);
|
||||
tensor_iterator->set_invariant_input(M_body, M);
|
||||
|
||||
auto out = tensor_iterator->get_iter_value(Zo, -1);
|
||||
auto res = std::make_shared<Result>(out);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, M});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{Zo}, ParameterVector{Xi, Yi});
|
||||
auto tensor_iterator = std::make_shared<TensorIterator>();
|
||||
tensor_iterator->set_body(body);
|
||||
tensor_iterator->set_sliced_input(Xi, X, 0, 2, 2, 39, 1);
|
||||
tensor_iterator->set_sliced_input(Yi, Y, 0, 2, 2, -1, 1);
|
||||
|
||||
auto out = tensor_iterator->get_iter_value(Zo, -1);
|
||||
auto res = std::make_shared<Result>(out);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, M});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, RemoveTensorIteratorManyDanglingParameters) {
|
||||
auto X = std::make_shared<Parameter>(element::f32, Shape{32, 40, 10});
|
||||
auto Y = std::make_shared<Parameter>(element::f32, Shape{32, 40, 10});
|
||||
auto Z = std::make_shared<Parameter>(element::f32, Shape{32, 40, 10});
|
||||
auto M = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
|
||||
auto Xi = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto Yi = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto Zi = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto M_body = std::make_shared<Parameter>(element::f32, Shape{32, 2, 10});
|
||||
auto Zo = std::make_shared<Abs>(std::make_shared<Add>(Xi, Zi));
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{Zo}, ParameterVector{Xi, Yi, Zi, M_body});
|
||||
auto tensor_iterator = std::make_shared<TensorIterator>();
|
||||
tensor_iterator->set_body(body);
|
||||
tensor_iterator->set_sliced_input(Xi, X, 0, 2, 2, 39, 1);
|
||||
tensor_iterator->set_sliced_input(Yi, Y, 0, 2, 2, -1, 1);
|
||||
tensor_iterator->set_sliced_input(Zi, Z, 0, 2, 2, -1, 1);
|
||||
tensor_iterator->set_invariant_input(M_body, M);
|
||||
|
||||
auto out = tensor_iterator->get_iter_value(Zo, -1);
|
||||
auto res = std::make_shared<Result>(out);
|
||||
function = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z, M});
|
||||
|
||||
manager.register_pass<pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
}
|
||||
{
|
||||
auto body = std::make_shared<Function>(OutputVector{Zo}, ParameterVector{Xi, Zi});
|
||||
auto tensor_iterator = std::make_shared<TensorIterator>();
|
||||
tensor_iterator->set_body(body);
|
||||
tensor_iterator->set_sliced_input(Xi, X, 0, 2, 2, 39, 1);
|
||||
tensor_iterator->set_sliced_input(Zi, Z, 0, 2, 2, -1, 1);
|
||||
|
||||
auto out = tensor_iterator->get_iter_value(Zo, -1);
|
||||
auto res = std::make_shared<Result>(out);
|
||||
function_ref = std::make_shared<Function>(OutputVector{res}, ParameterVector{X, Y, Z, M});
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <transformations_visibility.hpp>
|
||||
#include <openvino/pass/graph_rewrite.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API RemoveConcatZeroDimInput;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ov
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief RemoveConcatZeroDimInput transformation
|
||||
* removes input of Concat if the tensor size is equal to 0
|
||||
*/
|
||||
|
||||
class ov::pass::RemoveConcatZeroDimInput: public ov::pass::MatcherPass {
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
RemoveConcatZeroDimInput();
|
||||
};
|
@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <transformations_visibility.hpp>
|
||||
#include <openvino/pass/graph_rewrite.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API RemoveMultiSubGraphOpDanglingParams;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ov
|
||||
|
||||
/*
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief RemoveMultiSubGraphOpDanglingParams transformation
|
||||
* removed MultiSubGraphOp inputs which are not connected to other nodes
|
||||
* in the bodies of a MultiSubGraphOp
|
||||
*/
|
||||
|
||||
class ov::pass::RemoveMultiSubGraphOpDanglingParams: public ov::pass::MatcherPass {
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
RemoveMultiSubGraphOpDanglingParams();
|
||||
};
|
@ -48,6 +48,8 @@
|
||||
#include <transformations/common_optimizations/transpose_to_reshape.hpp>
|
||||
#include <transformations/common_optimizations/batch_to_space_fusion.hpp>
|
||||
#include <transformations/common_optimizations/mul_conv_fusion.hpp>
|
||||
#include <transformations/common_optimizations/remove_concat_zero_dim_input.hpp>
|
||||
#include <transformations/common_optimizations/remove_multi_subgraph_op_dangling_params.hpp>
|
||||
#include <transformations/common_optimizations/split_concat_pair_to_interpolate_fusion.hpp>
|
||||
#include <transformations/op_conversions/convert_divide.hpp>
|
||||
#include <transformations/common_optimizations/divide_fusion.hpp>
|
||||
@ -79,6 +81,15 @@ bool ngraph::pass::MOCTransformations::run_on_function(std::shared_ptr<ngraph::F
|
||||
if (!m_use_shapes) {
|
||||
manager.register_pass<ngraph::pass::DisableShapeOfConstantFolding>();
|
||||
}
|
||||
// RemoveConcatZeroDimInput and RemoveMultiSubGraphOpDanglingParams
|
||||
// should be performed before first ConstantFolding call.
|
||||
// The passes can deteach graph branches where zero dimesion is calculated.
|
||||
// Zero dimensions in shape causes creation empty tensors, which are incorrect during CF.
|
||||
// In particular, if zero dim tensor is consumed in body of MultiSubGraphOp
|
||||
// RemoveConcatZeroDimInput and RemoveMultiSubGraphOpDanglingParams should be called together.
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
manager.register_pass<ov::pass::Validate>();
|
||||
manager.register_pass<ov::pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
manager.register_pass<ngraph::pass::DisableRandomUniformConstantFolding>();
|
||||
manager.register_pass<ngraph::pass::ConstantFolding>();
|
||||
manager.register_pass<ngraph::pass::Validate>();
|
||||
|
@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/common_optimizations/remove_concat_zero_dim_input.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
#include "openvino/pass/pattern/op/wrap_type.hpp"
|
||||
#include <ngraph/rt_info.hpp>
|
||||
#include "itt.hpp"
|
||||
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ov::pass::RemoveConcatZeroDimInput, "RemoveConcatZeroDimInput", 0);
|
||||
|
||||
ov::pass::RemoveConcatZeroDimInput::RemoveConcatZeroDimInput() {
|
||||
MATCHER_SCOPE(RemoveConcatZeroDimInput);
|
||||
auto concat_pattern = pattern::wrap_type<opset8::Concat>();
|
||||
ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto concat = m.get_match_root();
|
||||
auto concat_inputs = concat->input_values();
|
||||
concat_inputs.erase(std::remove_if(concat_inputs.begin(), concat_inputs.end(),
|
||||
[](const Output<Node>& input) {
|
||||
const auto& in_shape = input.get_partial_shape();
|
||||
if (in_shape.rank().is_static()) {
|
||||
return std::any_of(std::begin(in_shape), std::end(in_shape), [](const ov::Dimension& dim) {
|
||||
if (dim.is_static() && dim.get_length() == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});}
|
||||
return false;
|
||||
}), concat_inputs.end());
|
||||
|
||||
bool inputs_removed = concat->get_input_size() > concat_inputs.size();
|
||||
if (inputs_removed) {
|
||||
concat->set_arguments(concat_inputs);
|
||||
}
|
||||
return inputs_removed;
|
||||
};
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(concat_pattern, matcher_name);
|
||||
this->register_matcher(m, callback);
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/common_optimizations/remove_multi_subgraph_op_dangling_params.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
#include <openvino/op/util/multi_subgraph_base.hpp>
|
||||
#include "openvino/pass/pattern/op/wrap_type.hpp"
|
||||
#include <ngraph/rt_info.hpp>
|
||||
#include "itt.hpp"
|
||||
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ov::pass::RemoveMultiSubGraphOpDanglingParams, "RemoveMultiSubGraphOpDanglingParams", 0);
|
||||
|
||||
ov::pass::RemoveMultiSubGraphOpDanglingParams::RemoveMultiSubGraphOpDanglingParams() {
|
||||
MATCHER_SCOPE(RemoveMultiSubGraphOpDanglingParams);
|
||||
auto multi_subgraph_op_pattern = pattern::wrap_type<op::util::MultiSubGraphOp>();
|
||||
ov::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto multi_subgraph_op = std::dynamic_pointer_cast<op::util::MultiSubGraphOp>(m.get_match_root());
|
||||
if (multi_subgraph_op == nullptr) {
|
||||
return false;
|
||||
}
|
||||
bool pass_required = false;
|
||||
std::set<ov::Output<ov::Node>> required_inputs;
|
||||
auto op_inputs = multi_subgraph_op->input_values();
|
||||
std::vector<std::vector<size_t>> to_remove_descriptors_indexes;
|
||||
const auto subgraphs_size = multi_subgraph_op->get_internal_subgraphs_size();
|
||||
to_remove_descriptors_indexes.resize(subgraphs_size);
|
||||
for (size_t body_idx=0; body_idx < subgraphs_size; ++body_idx) {
|
||||
auto& body_func = multi_subgraph_op->get_function(body_idx);
|
||||
auto& body_params = body_func->get_parameters();
|
||||
auto& body_in_descriptors = multi_subgraph_op->get_input_descriptions(body_idx);
|
||||
// collect all descriptors which should be removed and reqired inputs
|
||||
for (size_t i = 0; i < body_in_descriptors.size(); ++i) {
|
||||
auto& body_param = body_params[body_in_descriptors[i]->m_body_parameter_index];
|
||||
if (body_param->get_output_target_inputs(0).size() == 0) {
|
||||
to_remove_descriptors_indexes[body_idx].push_back(i);
|
||||
pass_required = true;
|
||||
} else {
|
||||
// collecting required inputs is needed to detect cases where the input
|
||||
// is not needed in a one body, but the other one uses it (for example If case)
|
||||
required_inputs.insert(op_inputs[body_in_descriptors[i]->m_input_index]); // only unique
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pass_required) {
|
||||
using DescType = op::util::MultiSubGraphOp::MultiSubgraphInputDescriptionVector;
|
||||
auto update_body_param_desc = [](DescType& descriptors, uint64_t removed_body_idx){
|
||||
for (auto& desc : descriptors) {
|
||||
if (desc->m_body_parameter_index > removed_body_idx) {
|
||||
desc->m_body_parameter_index--;
|
||||
}
|
||||
}};
|
||||
auto update_op_inputs_desc = [&subgraphs_size](const std::shared_ptr<op::util::MultiSubGraphOp>& op, uint64_t removed_loop_idx){
|
||||
for (size_t body_idx=0; body_idx < subgraphs_size; ++body_idx) {
|
||||
auto& descriptors = op->get_input_descriptions(body_idx);
|
||||
for (auto& desc : descriptors) {
|
||||
if (desc->m_input_index > removed_loop_idx) {
|
||||
desc->m_input_index--;
|
||||
}
|
||||
}
|
||||
}};
|
||||
// Remove dangling body params and input and update input descriptors
|
||||
for (size_t body_idx=0; body_idx < subgraphs_size; ++body_idx) {
|
||||
auto& body_in_descriptors = multi_subgraph_op->get_input_descriptions(body_idx);
|
||||
auto& body_func = multi_subgraph_op->get_function(body_idx);
|
||||
auto& body_params = body_func->get_parameters();
|
||||
op::util::MultiSubGraphOp::MultiSubgraphInputDescriptionVector updated_body_in_descriptors;
|
||||
for (size_t desc_idx = 0; desc_idx < body_in_descriptors.size(); ++desc_idx) {
|
||||
if (std::count(std::begin(to_remove_descriptors_indexes[body_idx]), std::end(to_remove_descriptors_indexes[body_idx]), desc_idx) > 0) {
|
||||
auto& body_param = body_params[body_in_descriptors[desc_idx]->m_body_parameter_index];
|
||||
body_func->remove_parameter(body_param);
|
||||
// Move all body indexes which are after these indicated by to_remove_descriptors_indexes
|
||||
update_body_param_desc(body_in_descriptors, body_in_descriptors[desc_idx]->m_body_parameter_index);
|
||||
// remove dangling input of MultiSubGraphOp which was not removed earlier
|
||||
auto& current_input = op_inputs[body_in_descriptors[desc_idx]->m_input_index];
|
||||
if (std::count(std::begin(required_inputs), std::end(required_inputs), current_input) == 0
|
||||
&& std::count(std::begin(op_inputs), std::end(op_inputs), current_input) > 0) {
|
||||
op_inputs.erase(std::next(op_inputs.begin(), body_in_descriptors[desc_idx]->m_input_index));
|
||||
// Move all input indexes (in all bodies) which are after these indicated by to_remove_descriptors_indexes
|
||||
// and are not used in any body
|
||||
update_op_inputs_desc(multi_subgraph_op, body_in_descriptors[desc_idx]->m_input_index);
|
||||
}
|
||||
} else {
|
||||
updated_body_in_descriptors.emplace_back(body_in_descriptors[desc_idx]);
|
||||
}
|
||||
}
|
||||
multi_subgraph_op->set_input_descriptions(body_idx, updated_body_in_descriptors);
|
||||
}
|
||||
multi_subgraph_op->set_arguments(op_inputs);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(multi_subgraph_op_pattern, matcher_name);
|
||||
this->register_matcher(m, callback);
|
||||
}
|
@ -16,7 +16,7 @@ namespace util {
|
||||
///
|
||||
class OPENVINO_API MultiSubGraphOp : public Op {
|
||||
public:
|
||||
OPENVINO_RTTI("MultiSubGraphOp", "util");
|
||||
OPENVINO_OP("MultiSubGraphOp", "util");
|
||||
BWDCMP_RTTI_DECLARATION;
|
||||
/// \brief Abstract class describes a connection between a MultiSubGraphOp input and
|
||||
/// the body.
|
||||
|
@ -15,7 +15,7 @@ namespace util {
|
||||
///
|
||||
class OPENVINO_API SubGraphOp : public MultiSubGraphOp {
|
||||
public:
|
||||
OPENVINO_OP("SubGraphOp", "util");
|
||||
OPENVINO_OP("SubGraphOp", "util", op::util::MultiSubGraphOp);
|
||||
BWDCMP_RTTI_DECLARATION;
|
||||
|
||||
virtual const std::shared_ptr<Function>& get_function() const {
|
||||
|
@ -31,6 +31,8 @@
|
||||
// TODO: remove this pass usage
|
||||
#include <legacy/transformations/convert_opset1_to_legacy/convert_nms_5_to_legacy.hpp>
|
||||
#include <legacy/transformations/convert_opset1_to_legacy/convert_one_hot_to_one_hot_ie.hpp>
|
||||
#include <transformations/common_optimizations/remove_concat_zero_dim_input.hpp>
|
||||
#include <transformations/common_optimizations/remove_multi_subgraph_op_dangling_params.hpp>
|
||||
#include <transformations/low_precision/disable_convert_constant_folding_on_const_path.hpp>
|
||||
#include <transformations/op_conversions/convert_matrix_nms_to_matrix_nms_ie.hpp>
|
||||
#include <transformations/op_conversions/convert_multiclass_nms_to_multiclass_nms_ie.hpp>
|
||||
@ -422,6 +424,8 @@ void CNNNetworkNGraphImpl::reshape(const std::map<std::string, ngraph::PartialSh
|
||||
OV_ITT_SCOPED_TASK(ov::itt::domains::IE, "CNNNetworkNGraphImpl::ConvertToLegacy");
|
||||
::ngraph::pass::Manager manager;
|
||||
// resolves dynamism by replacing dynamic operation with static version
|
||||
manager.register_pass<ov::pass::RemoveConcatZeroDimInput>();
|
||||
manager.register_pass<ov::pass::RemoveMultiSubGraphOpDanglingParams>();
|
||||
manager.register_pass<::ngraph::pass::ConvertNMS5ToLegacyMatcher>(false);
|
||||
// TODO [DS NMS]: remove when nodes from models where nms is not last node in model supports DS
|
||||
manager.register_pass<::ngraph::pass::ConvertMulticlassNmsToMulticlassNmsIE>(false);
|
||||
|
Loading…
Reference in New Issue
Block a user