From 790f02c0b191bc758ff15166f86e142fc2e144bb Mon Sep 17 00:00:00 2001 From: Anton Pankratov Date: Fri, 14 Jan 2022 12:26:39 +0300 Subject: [PATCH] Hetero creates single result node (#9572) --- .../hetero/synthetic.cpp | 7 +++ src/plugins/hetero/executable_network.cpp | 45 ++++++++------ .../ngraph_functions/subgraph_builders.hpp | 61 +++++++++++++++++++ 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/docs/template_plugin/tests/functional/shared_tests_instances/hetero/synthetic.cpp b/docs/template_plugin/tests/functional/shared_tests_instances/hetero/synthetic.cpp index 5a0adbf4fc4..4bca7c4a851 100644 --- a/docs/template_plugin/tests/functional/shared_tests_instances/hetero/synthetic.cpp +++ b/docs/template_plugin/tests/functional/shared_tests_instances/hetero/synthetic.cpp @@ -14,6 +14,13 @@ using namespace HeteroTests; // this tests load plugin by library name: this is not available during static linkage #ifndef OPENVINO_STATIC_LIBRARY +INSTANTIATE_TEST_SUITE_P(smoke_manyTargetInputs, HeteroSyntheticTest, + ::testing::Combine( + ::testing::Values(std::vector{{"TEMPLATE0", "ov_template_plugin"}, {"TEMPLATE1", "ov_template_plugin"}}), + ::testing::ValuesIn(HeteroTests::HeteroSyntheticTest::withMajorNodesFunctions( + [] {return ngraph::builder::subgraph::makeConvPool2Relu2();}, {"Conv_1"}, true))), + HeteroSyntheticTest::getTestCaseName); + INSTANTIATE_TEST_SUITE_P(smoke_SingleMajorNode, HeteroSyntheticTest, ::testing::Combine( ::testing::Values(std::vector{{"TEMPLATE0", "ov_template_plugin"}, {"TEMPLATE1", "ov_template_plugin"}}), diff --git a/src/plugins/hetero/executable_network.cpp b/src/plugins/hetero/executable_network.cpp index 53b5d54cec6..97496a9986e 100644 --- a/src/plugins/hetero/executable_network.cpp +++ b/src/plugins/hetero/executable_network.cpp @@ -303,29 +303,37 @@ HeteroExecutableNetwork::HeteroExecutableNetwork(const InferenceEngine::CNNNetwo // Break graph using insertion of result parameter split NodeMap subgraphParameterToPrevResult; std::vector> results; - for (auto&& input : subgraphInputs) { - if (!ngraph::op::is_parameter(input.get_node()) && !ngraph::op::is_constant(input.get_node())) { - auto output = input.get_source_output(); - output.remove_target_input(input); + { + std::set> subgraphOutputs; + for (auto&& input : subgraphInputs) { + if (!ngraph::op::is_parameter(input.get_node()) && !ngraph::op::is_constant(input.get_node())) { + subgraphOutputs.insert(input.get_source_output()); + } + } + for (auto&& output : subgraphOutputs) { + auto inputs = output.get_target_inputs(); auto result = std::make_shared(output); result->set_friendly_name(output.get_node()->get_friendly_name() + "_" + std::to_string(output.get_index()) + "_result"); ngraph::copy_runtime_info(output.get_node_shared_ptr(), result); - auto parameter = - std::make_shared(output.get_element_type(), output.get_partial_shape()); - parameter->set_friendly_name(input.get_node()->get_friendly_name() + "_" + - std::to_string(input.get_index()) + "_parameter"); - ngraph::copy_runtime_info(input.get_node()->shared_from_this(), parameter); - input.replace_source_output(parameter->output(0)); - results.push_back(result); subgraphIds.emplace(result.get(), subgraphIds[output.get_node()]); - subgraphIds.emplace(parameter.get(), subgraphIds[input.get_node()]); - subgraphParameterToPrevResult.emplace(parameter.get(), result.get()); - _blobNameMap.emplace( - parameter->get_friendly_name(), - output.get_node()->get_friendly_name() + ((output.get_node()->get_output_size() != 1) - ? ("." + std::to_string(output.get_index())) - : std::string{})); + results.push_back(result); + for (auto&& input : inputs) { + output.remove_target_input(input); + auto parameter = + std::make_shared(output.get_element_type(), output.get_partial_shape()); + parameter->set_friendly_name(input.get_node()->get_friendly_name() + "_" + + std::to_string(input.get_index()) + "_parameter"); + ngraph::copy_runtime_info(input.get_node()->shared_from_this(), parameter); + input.replace_source_output(parameter->output(0)); + subgraphIds.emplace(parameter.get(), subgraphIds[input.get_node()]); + subgraphParameterToPrevResult.emplace(parameter.get(), result.get()); + _blobNameMap.emplace( + parameter->get_friendly_name(), + output.get_node()->get_friendly_name() + ((output.get_node()->get_output_size() != 1) + ? ("." + std::to_string(output.get_index())) + : std::string{})); + } } } @@ -353,6 +361,7 @@ HeteroExecutableNetwork::HeteroExecutableNetwork(const InferenceEngine::CNNNetwo subgraph._affinity = itAffinity->second; } } + results = {}; // Subgraph topological sort std::vector allSubgraphs; diff --git a/src/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/subgraph_builders.hpp b/src/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/subgraph_builders.hpp index 3609d54bab4..53707514a1c 100644 --- a/src/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/subgraph_builders.hpp +++ b/src/tests/ngraph_helpers/ngraph_functions/include/ngraph_functions/subgraph_builders.hpp @@ -47,6 +47,67 @@ inline std::shared_ptr makeConvPoolRelu(std::vector in return fnPtr; } +inline std::shared_ptr makeConvPool2Relu2(std::vector inputShape = {1, 1, 32, 32}, + ngraph::element::Type_t ngPrc = ngraph::element::Type_t::f32) { + auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); + params.front()->set_friendly_name("Param_1"); + params.front()->output(0).get_tensor().set_names({"data"}); + std::vector constShape = {inputShape[0], inputShape[2], inputShape[1], inputShape[3]}; + auto const1 = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{4}, constShape); + const1->set_friendly_name("Const_1"); + const1->output(0).get_tensor().set_names({"const1"}); + auto reshape1 = std::make_shared(params.front(), const1, false); + reshape1->set_friendly_name("Reshape_1"); + reshape1->output(0).get_tensor().set_names({"reshape1"}); + auto conv1 = ngraph::builder::makeConvolution(reshape1, ngPrc, {1, 3}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, + ngraph::op::PadType::EXPLICIT, 4); + conv1->set_friendly_name("Conv_1"); + conv1->output(0).get_tensor().set_names({"conv"}); + std::vector stride{1, 1}, padB{0, 0}, padE = padB, kernel{1, 2}; + + ngraph::ResultVector results; + { + auto pool1 = std::make_shared(conv1, stride, padB, padE, kernel, + ngraph::op::RoundingType::FLOOR, + ngraph::op::PadType::EXPLICIT); + pool1->output(0).get_tensor().set_names({"pool_0"}); + pool1->set_friendly_name("Pool_1_0"); + auto relu1 = std::make_shared(pool1); + relu1->set_friendly_name("Relu_1_0"); + relu1->output(0).get_tensor().set_names({"relu_0"}); + ngraph::Shape reluShape = relu1->outputs()[0].get_tensor().get_shape(); + std::vector constShape2 = {1, ngraph::shape_size(reluShape)}; + auto const2 = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{2}, constShape2); + const2->output(0).get_tensor().set_names({"const2_0"}); + const2->set_friendly_name("Const_2_0"); + auto reshape2 = std::make_shared(relu1, const2, false); + reshape2->output(0).get_tensor().set_names({"reshape2_0"}); + reshape2->set_friendly_name("Reshape_2_0"); + results.push_back(std::make_shared(reshape2)); + } + { + auto pool1 = std::make_shared(conv1, stride, padB, padE, kernel, + ngraph::op::RoundingType::FLOOR, + ngraph::op::PadType::EXPLICIT); + pool1->output(0).get_tensor().set_names({"pool_1"}); + pool1->set_friendly_name("Pool_1_1"); + auto relu1 = std::make_shared(pool1); + relu1->set_friendly_name("Relu_1_1"); + relu1->output(0).get_tensor().set_names({"relu_1"}); + ngraph::Shape reluShape = relu1->outputs()[0].get_tensor().get_shape(); + std::vector constShape2 = {1, ngraph::shape_size(reluShape)}; + auto const2 = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{2}, constShape2); + const2->output(0).get_tensor().set_names({"const2_1"}); + const2->set_friendly_name("Const_2_1"); + auto reshape2 = std::make_shared(relu1, const2, false); + reshape2->output(0).get_tensor().set_names({"reshape2_1"}); + reshape2->set_friendly_name("Reshape_2_1"); + results.push_back(std::make_shared(reshape2)); + } + std::shared_ptr fnPtr = std::make_shared(results, params); + return fnPtr; +} + inline std::shared_ptr makeConvPoolReluNonZero(std::vector inputShape = {1, 1, 32, 32}, ngraph::element::Type_t ngPrc = ngraph::element::Type_t::f32) { auto params = ngraph::builder::makeParams(ngPrc, {inputShape});