diff --git a/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp b/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp index c11078021d6..6791768e4e9 100644 --- a/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp +++ b/inference-engine/src/gna_plugin/frontend/scale_factor_calc.hpp @@ -424,11 +424,10 @@ class ScaleFactorPerLayer { auto quantData = InferenceEngine::getInjectedData(*concatLayer); std::vector inputLayers; for (auto input_idx = 0; input_idx != concatLayer->insData.size(); input_idx++) { - auto prev_layer = InferenceEngine::CNNNetPrevLayer(concatLayer, input_idx); - // FlattenConcat inserts reshape between concat and its inputs, which results in taking wrong layers as inputs for scale factor calulation - if (prev_layer->type == "reshape" && prev_layer->insData.size() == 1 && prev_layer->outData.size() == 1) { - prev_layer = InferenceEngine::CNNNetPrevLayer(prev_layer, 0); - } + auto notChangeScaleFactors = [](InferenceEngine::CNNLayerPtr layer) { + return LayerInfo(layer).isNonFunctional() || LayerInfo(layer).isSplit() || LayerInfo(layer).isCopy(); + }; + auto prev_layer = CNNNetPrevLayerSkipCertain(concatLayer, input_idx, notChangeScaleFactors); inputLayers.push_back(prev_layer); } diff --git a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp index ceb51c1a1f0..1ec79ec26e2 100644 --- a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp +++ b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp @@ -816,13 +816,18 @@ void InsertIdentityLayerPass::run() { void InsertCopyLayerPass::run() { // Copy layer insertion happens in few cases: // Crop output goes to concat layer -> copy layer insertion + // Splitted part of input goes to concat layer -> copy layer insertion // Concat|Split|Crop layer goes to memory layer -> delayed copy layer insertion // One output goes to multiple concat and/or memory layers -> delayed copies before memory layers - // and copies before concay layers (one less copy than outputs) + // and copies before concat layers (one less copy than outputs) for (auto & l : *pLayers) { if (LayerInfo(l).isNonFunctional()) continue; - // Crop -> Concat and Concat -> Memory cases - if ((LayerInfo(l).isCrop() && !LayerInfo(l).isCropAffined()) || LayerInfo(l).isConcat()) { + auto isNonFunctional = [](InferenceEngine::CNNLayerPtr layer) { + return LayerInfo(layer).isNonFunctional(); + }; + // Crop -> Concat, Input -> Split -> Concat and Concat -> Memory cases + if ((LayerInfo(l).isCrop() && !LayerInfo(l).isCropAffined()) || LayerInfo(l).isConcat() || + (LayerInfo(l).isSplit() && LayerInfo(CNNNetPrevLayerSkipCertain(l, 0, isNonFunctional)).isInput())) { std::vector> copy_insertion_tuples; std::vector> delayed_copy_insertion_tuples; @@ -850,7 +855,7 @@ void InsertCopyLayerPass::run() { if ((LayerInfo(l).isConcat() || LayerInfo(l).isCrop() || LayerInfo(l).isSplit()) && LayerInfo(current_layer).isMemory()) { // Concat|Split|Crop -> Memory case delayed_copy_insertion_tuples.push_back(std::make_tuple(original_parent, original_child, input_idx)); - } else if (LayerInfo(l).isCrop() && LayerInfo(current_layer).isConcat()) { + } else if ((LayerInfo(l).isCrop() || LayerInfo(l).isSplit()) && LayerInfo(current_layer).isConcat()) { // Crop -> Concat case copy_insertion_tuples.push_back(std::make_tuple(original_parent, original_child, input_idx)); } diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/input_split_concat.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/input_split_concat.cpp new file mode 100644 index 00000000000..3cf10de3f1f --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/input_split_concat.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "common_test_utils/test_constants.hpp" +#include "subgraph_tests/input_split_concat.hpp" + +using namespace SubgraphTestsDefinitions; + +namespace { +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 +}; + +const std::vector> configs = { + { + {"GNA_DEVICE_MODE", "GNA_SW_EXACT"} + }, + { + {"GNA_DEVICE_MODE", "GNA_SW_FP32"} + } +}; + +const std::vector> inputShapes = { + {1, 128}, + {1, 512}, + {1, 320} +}; + +INSTANTIATE_TEST_CASE_P(smoke_InputSplitConcat, InputSplitConcatTest, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::ValuesIn(configs), + ::testing::ValuesIn(inputShapes)), + InputSplitConcatTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/input_split_concat.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/input_split_concat.hpp new file mode 100644 index 00000000000..e16b6f40ad3 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/input_split_concat.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/subgraph/input_split_concat.hpp" + +namespace SubgraphTestsDefinitions { + +TEST_P(InputSplitConcatTest, CompareWithRefImpl) { + Run(); +}; + +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/input_split_concat.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/input_split_concat.hpp new file mode 100644 index 00000000000..dff93948232 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/input_split_concat.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/layer_test_utils.hpp" +#include "ngraph_functions/builders.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" + +namespace SubgraphTestsDefinitions { + +typedef std::tuple< + InferenceEngine::Precision, // Network Precision + std::string, // Target Device + std::map, // Configuration + std::vector // Input Shapes +> InputSplitConcatParams; + +class InputSplitConcatTest : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; +}; + +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/subgraph/input_split_concat.cpp b/inference-engine/tests/functional/shared_test_classes/src/subgraph/input_split_concat.cpp new file mode 100644 index 00000000000..2b0cb2fbc14 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/src/subgraph/input_split_concat.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/subgraph/input_split_concat.hpp" +#include "ngraph_functions/builders.hpp" + +namespace SubgraphTestsDefinitions { + +std::string InputSplitConcatTest::getTestCaseName(testing::TestParamInfo obj) { + InferenceEngine::Precision netPrecision; + std::string targetDevice; + std::map configuration; + std::vector inputShape; + std::tie(netPrecision, targetDevice, configuration, inputShape) = obj.param; + + std::ostringstream result; + result << "IS=" << CommonTestUtils::vec2str(inputShape) << "_"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "targetDevice=" << targetDevice; + for (auto const& configItem : configuration) { + result << "_configItem=" << configItem.first << "_" << configItem.second; + } + return result.str(); +} + +void InputSplitConcatTest::SetUp() { + InferenceEngine::Precision netPrecision; + std::map tempConfig; + std::vector inputShape; + std::tie(netPrecision, targetDevice, tempConfig, inputShape) = this->GetParam(); + configuration.insert(tempConfig.begin(), tempConfig.end()); + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + auto params = ngraph::builder::makeParams(ngPrc, { inputShape }); + + auto split = ngraph::builder::makeSplit(params[0], ngPrc, 2, 1); + auto relu1 = std::make_shared(split->output(0)); + + auto const_vals = CommonTestUtils::generate_float_numbers(inputShape[1], -5.0f, 5.0f); + auto constant = ngraph::builder::makeConstant(ngPrc, inputShape, const_vals); + auto concat = std::make_shared(ngraph::OutputVector{constant, split->output(1)}, 1); + auto relu2 = std::make_shared(concat); + + ngraph::ResultVector results{ std::make_shared(relu1), std::make_shared(relu2) }; + function = std::make_shared(results, params, "InputSplitConcatTest"); +} +} // namespace SubgraphTestsDefinitions