[GNA] Support for cascade concat with non functional layers between concats (#598)
[GNA] Support for cascade concat with non functional layers between concats
This commit is contained in:
parent
cf4dedbb92
commit
861bcc2949
@ -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<int32_t>(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<int>(inputLayer.offset), idx);
|
||||
|
||||
concatLayerInfo.input_allocated = true;
|
||||
|
@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <vector>
|
||||
#include <ie_precision.hpp>
|
||||
#include <subgraph_tests/cascade_concat.hpp>
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
std::vector<std::vector<std::vector<size_t>>> shape1{
|
||||
{{1, 64}},
|
||||
{{1, 128}},
|
||||
{{1, 32}},
|
||||
{{1, 16}},
|
||||
{{1, 8}}
|
||||
};
|
||||
|
||||
std::vector<std::vector<std::vector<size_t>>> shape2{
|
||||
{{1, 72}},
|
||||
{{1, 128}},
|
||||
{{1, 32}},
|
||||
{{1, 16}},
|
||||
{{1, 8}}
|
||||
};
|
||||
|
||||
std::vector<std::vector<std::vector<size_t>>> shape3{
|
||||
{{1, 80}},
|
||||
{{1, 128}},
|
||||
{{1, 32}},
|
||||
{{1, 16}},
|
||||
{{1, 8}}
|
||||
};
|
||||
|
||||
std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
|
||||
};
|
||||
|
||||
std::map<std::string, std::string> 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
|
@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "functional_test_utils/layer_test_utils.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
typedef std::tuple<
|
||||
std::vector<std::vector<size_t>>, //input shapes 1
|
||||
std::vector<std::vector<size_t>>, //input shapes 2
|
||||
std::vector<std::vector<size_t>>, //input shapes 3
|
||||
InferenceEngine::Precision, //Network precision
|
||||
bool, //Multioutput -> True, Single out ->false
|
||||
std::string, //Device name
|
||||
std::map<std::string, std::string>//config
|
||||
> CascadeConcatTuple;
|
||||
|
||||
class CascadeConcat
|
||||
: public testing::WithParamInterface<CascadeConcatTuple>,
|
||||
public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<CascadeConcatTuple> &obj);
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#include <debug.h>
|
||||
#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<CascadeConcatTuple> &obj) {
|
||||
std::vector<std::vector<size_t>> input1, input2, input3;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetName;
|
||||
bool multioutput;
|
||||
std::map<std::string, std::string> 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<std::vector<size_t>> input1, input2, input3;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::map<std::string, std::string> 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<ngraph::opset1::Relu>(input[0]);
|
||||
auto relu2 = std::make_shared<ngraph::opset1::Relu>(input[1]);
|
||||
auto relu3 = std::make_shared<ngraph::opset1::Relu>(input[2]);
|
||||
auto concat = std::make_shared<ngraph::opset1::Concat>(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::opset1::Concat>(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<float>{1.01f});
|
||||
auto mult = std::make_shared<ngraph::op::v0::Multiply>(concat, const_mult);
|
||||
results = ngraph::ResultVector{std::make_shared<ngraph::opset1::Result>(concat2),
|
||||
std::make_shared<ngraph::opset1::Result>(mult)};
|
||||
} else {
|
||||
results = ngraph::ResultVector{std::make_shared<ngraph::opset1::Result>(concat2)};
|
||||
}
|
||||
function = std::make_shared<ngraph::Function>(results, input, "concat_reshape_reshape_concat_mul");
|
||||
}
|
||||
|
||||
TEST_P(CascadeConcat, CompareWithRefs) {
|
||||
Run();
|
||||
}
|
||||
} // namespace LayerTestsDefinitions
|
Loading…
Reference in New Issue
Block a user