From 075ae0343ad734ef07173422b3f436a32e9076d1 Mon Sep 17 00:00:00 2001 From: Andrey Dmitriev Date: Tue, 26 May 2020 14:30:51 +0300 Subject: [PATCH] [GNA] Support for cascade concat with non functional layers between concats [GNA] Support for cascade concat with non functional layers between concats [GNA] Support for cascade concat with non functional layers between concats fix discussion medn test delete commet Rework test minor fix last fix Test Align filter fix discussion --- .../src/gna_plugin/gna_graph_compiler.cpp | 24 +++++-- .../subgraph_tests/cascade_concat.cpp | 65 ++++++++++++++++++ .../include/subgraph_tests/cascade_concat.hpp | 31 +++++++++ .../src/subgraph_tests/cascade_concat.cpp | 66 +++++++++++++++++++ 4 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/cascade_concat.cpp create mode 100644 inference-engine/tests/functional/plugin/shared/include/subgraph_tests/cascade_concat.hpp create mode 100644 inference-engine/tests/functional/plugin/shared/src/subgraph_tests/cascade_concat.cpp diff --git a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp index a49d94044476c3..c4dee7f60c7483 100644 --- a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp +++ b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp @@ -602,9 +602,22 @@ void GNAGraphCompiler::ConcatPrimitive(InferenceEngine::CNNLayerPtr layer) { auto& concatLayerInfo = concat_connection.find(concatLayer->name)->second; for (auto &&outLayer : getInputTo(concatLayer->outData.front())) { - if ( LayerInfo(outLayer.second).isConcat() ) { - connectOutput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size); + auto concatCandidate = outLayer.second; + if (LayerInfo(concatCandidate).isNonFunctional()) { + // searching for next concat + auto isNonFunctional = [](CNNLayerPtr l) { + return LayerInfo(l).isNonFunctional(); + }; + if (!CNNNetHasNextLayerSkipCertain(concatCandidate, 0, 0, isNonFunctional)) { + continue; + } + concatCandidate = CNNNetGetNextLayerSkipCertain(concatCandidate, 0, 0, isNonFunctional).first; + } + if (!LayerInfo(concatCandidate).isConcat()) { + continue; } + gnalog() << "Cascaded concat connection found from: " << layer->name << ", to: " << concatCandidate->name << std::endl; + connectOutput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size); } size_t idx = 0; @@ -625,21 +638,22 @@ void GNAGraphCompiler::ConcatPrimitive(InferenceEngine::CNNLayerPtr layer) { auto layerInfo = LayerInfo(concatParent); // auto layerInfo = LayerInfo(getCreatorLayer(concatLayerInput->insData[it].lock()).lock()); if (layerInfo.isInput()) { + auto & bytesAllocated = inputDesc->bytes_allocated_for_input[((InferenceEngine::CNNLayerPtr)layerInfo)->name]; if (concatLayerInfo.input_allocated) { // for concat input allocated only once, so lets mark this specific input layer also as allocated // we will bind it to offset further in connectInput // size need to be equal to full layer in order to pass checks - inputDesc->bytes_allocated_for_input[((InferenceEngine::CNNLayerPtr)layerInfo)->name] = concatLayerInfo.reserved_size; + bytesAllocated = concatLayerInfo.reserved_size; } connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, -static_cast(inputLayer.offset), idx); // TODO: currently connectInput api accept only total size, for concat we need extension for allocated, and actual sizes - inputDesc->bytes_allocated_for_input[((InferenceEngine::CNNLayerPtr) layerInfo)->name] = inputLayer.tensorSize; + bytesAllocated = inputLayer.tensorSize; concatLayerInfo.input_allocated = true; - } else if (layerInfo.isMemory()) { + } else if (layerInfo.isMemory()) { connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, -static_cast(inputLayer.offset), idx); concatLayerInfo.input_allocated = true; diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/cascade_concat.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/cascade_concat.cpp new file mode 100644 index 00000000000000..16d275539b53e0 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/cascade_concat.cpp @@ -0,0 +1,65 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +#include +#include +#include +#include "common_test_utils/test_constants.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + std::vector>> shape1{ + {{1, 64}}, + {{1, 128}}, + {{1, 32}}, + {{1, 16}}, + {{1, 8}} + }; + + std::vector>> shape2{ + {{1, 72}}, + {{1, 128}}, + {{1, 32}}, + {{1, 16}}, + {{1, 8}} + }; + + std::vector>> shape3{ + {{1, 80}}, + {{1, 128}}, + {{1, 32}}, + {{1, 16}}, + {{1, 8}} + }; + + std::vector netPrecisions = {InferenceEngine::Precision::FP32, + }; + + std::map additional_config = { + {"GNA_SCALE_FACTOR_0", "1"}, + {"GNA_SCALE_FACTOR_1", "1"}, + {"GNA_SCALE_FACTOR_2", "1"} + }; + + INSTANTIATE_TEST_CASE_P(cascade_concat, CascadeConcat, + ::testing::Combine( + ::testing::ValuesIn(shape1), + ::testing::ValuesIn(shape2), + ::testing::ValuesIn(shape3), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(false), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::Values(additional_config)), + CascadeConcat::getTestCaseName); + + INSTANTIATE_TEST_CASE_P(cascade_concat_multioutput, CascadeConcat, + ::testing::Combine( + ::testing::ValuesIn(shape1), + ::testing::ValuesIn(shape2), + ::testing::ValuesIn(shape3), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(true), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::Values(additional_config)), + CascadeConcat::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/cascade_concat.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/cascade_concat.hpp new file mode 100644 index 00000000000000..03cd47d4b30864 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/cascade_concat.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include +#include +#include +#include "functional_test_utils/layer_test_utils.hpp" +#include "ngraph_functions/builders.hpp" + +namespace LayerTestsDefinitions { + +typedef std::tuple< + std::vector>, //input shapes 1 + std::vector>, //input shapes 2 + std::vector>, //input shapes 3 + InferenceEngine::Precision, //Network precision + bool, //Multioutput -> True, Single out ->false + std::string, //Device name + std::map//config + > CascadeConcatTuple; + +class CascadeConcat + : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); +protected: + void SetUp() override; +}; +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/cascade_concat.cpp b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/cascade_concat.cpp new file mode 100644 index 00000000000000..5e2d54b7de4849 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/cascade_concat.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// +#include +#include "common_test_utils/common_utils.hpp" +#include "functional_test_utils/precision_utils.hpp" +#include "functional_test_utils/skip_tests_config.hpp" +#include "subgraph_tests/cascade_concat.hpp" + +namespace LayerTestsDefinitions { + +std::string CascadeConcat::getTestCaseName(const testing::TestParamInfo &obj) { + std::vector> input1, input2, input3; + InferenceEngine::Precision netPrecision; + std::string targetName; + bool multioutput; + std::map additional_config; + std::tie(input1, input2, input3, netPrecision, multioutput, targetName, additional_config) = obj.param; + std::ostringstream results; + + results << "IS=" << CommonTestUtils::vec2str(input1[0]) << "_"; + results << CommonTestUtils::vec2str(input2[0]) << "_"; + results << CommonTestUtils::vec2str(input3[0]) << "_"; + results << "netPRC=" << netPrecision.name() << "_"; + results << "Multioutput=" << multioutput << "_"; + results << "targetDevice=" << targetName << "_"; + return results.str(); +} + +void CascadeConcat::SetUp() { + std::vector> input1, input2, input3; + InferenceEngine::Precision netPrecision; + std::map additional_config; + bool multioutput; + std::tie(input1, input2, input3, netPrecision, multioutput, targetDevice, additional_config) = this->GetParam(); + configuration.insert(additional_config.begin(), additional_config.end()); + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + auto input = ngraph::builder::makeParams(ngPrc, {input1[0], input2[0], input2[0]}); + auto relu1 = std::make_shared(input[0]); + auto relu2 = std::make_shared(input[1]); + auto relu3 = std::make_shared(input[2]); + auto concat = std::make_shared(ngraph::OutputVector{relu1->output(0), + relu2->output(0)}, + 1); + auto reshape = ngraph::builder::makeSqueezeUnsqueeze(concat, ngPrc, {0}, ngraph::helpers::SqueezeOpType::UNSQUEEZE); + auto reshape2 = ngraph::builder::makeSqueezeUnsqueeze(reshape, ngPrc, {0}, ngraph::helpers::SqueezeOpType::SQUEEZE); + auto concat2 = std::make_shared(ngraph::OutputVector{reshape2->output(0), + relu3->output(0)}, + 1); + ngraph::ResultVector results; + if (multioutput) { + auto const_mult = ngraph::builder::makeConstant(ngPrc, ngraph::Shape{1, input1[0][1]+input2[0][1]}, + std::vector{1.01f}); + auto mult = std::make_shared(concat, const_mult); + results = ngraph::ResultVector{std::make_shared(concat2), + std::make_shared(mult)}; + } else { + results = ngraph::ResultVector{std::make_shared(concat2)}; + } + function = std::make_shared(results, input, "concat_reshape_reshape_concat_mul"); +} + +TEST_P(CascadeConcat, CompareWithRefs) { + Run(); +} +} // namespace LayerTestsDefinitions