[GNA] Fix issues with compilation and quantization of input-split-concat pattern (#4489)

This commit is contained in:
Elizaveta Lobanova 2021-03-02 14:59:55 +03:00 committed by GitHub
parent 1eb830d083
commit 96b7b9441e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 149 additions and 9 deletions

View File

@ -424,11 +424,10 @@ class ScaleFactorPerLayer<InferenceEngine::ConcatLayer*> {
auto quantData = InferenceEngine::getInjectedData<QuantizedLayerParams>(*concatLayer);
std::vector<InferenceEngine::CNNLayerPtr> 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);
}

View File

@ -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<std::tuple<CNNLayerPtr, CNNLayerPtr, size_t>> copy_insertion_tuples;
std::vector<std::tuple<CNNLayerPtr, CNNLayerPtr, size_t>> 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));
}

View File

@ -0,0 +1,40 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "common_test_utils/test_constants.hpp"
#include "subgraph_tests/input_split_concat.hpp"
using namespace SubgraphTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16
};
const std::vector<std::map<std::string, std::string>> configs = {
{
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}
},
{
{"GNA_DEVICE_MODE", "GNA_SW_FP32"}
}
};
const std::vector<std::vector<size_t>> 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

View File

@ -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

View File

@ -0,0 +1,34 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <memory>
#include <string>
#include <tuple>
#include <vector>
#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<std::string, std::string>, // Configuration
std::vector<size_t> // Input Shapes
> InputSplitConcatParams;
class InputSplitConcatTest : public testing::WithParamInterface<InputSplitConcatParams>,
public LayerTestsUtils::LayerTestsCommon {
public:
static std::string getTestCaseName(testing::TestParamInfo<InputSplitConcatParams> obj);
protected:
void SetUp() override;
};
} // namespace SubgraphTestsDefinitions

View File

@ -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<InputSplitConcatParams> obj) {
InferenceEngine::Precision netPrecision;
std::string targetDevice;
std::map<std::string, std::string> configuration;
std::vector<size_t> 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<std::string, std::string> tempConfig;
std::vector<size_t> 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<ngraph::opset3::Relu>(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::opset1::Concat>(ngraph::OutputVector{constant, split->output(1)}, 1);
auto relu2 = std::make_shared<ngraph::opset3::Relu>(concat);
ngraph::ResultVector results{ std::make_shared<ngraph::op::Result>(relu1), std::make_shared<ngraph::op::Result>(relu2) };
function = std::make_shared<ngraph::Function>(results, params, "InputSplitConcatTest");
}
} // namespace SubgraphTestsDefinitions