[GNA] fixed case when input connected to concat from left and const from right (#2874)

* Added test

* Added fix

* Fix comment

* Fix conflict
This commit is contained in:
Andrey Dmitriev
2020-11-10 16:37:03 +03:00
committed by GitHub
parent 12bb8abe5c
commit 4a0170dcb0
5 changed files with 147 additions and 21 deletions

View File

@@ -797,22 +797,16 @@ void GNAGraphCompiler::ConcatPrimitive(InferenceEngine::CNNLayerPtr layer) {
// 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
bytesAllocated = concatLayerInfo.reserved_size;
}
connectInput(layer, &concatLayerInfo.gna_ptr,
concatLayerInfo.reserved_size, -static_cast<int32_t>(inputLayer.offset), idx);
concatLayerInfo.reserved_size, inputLayer.offset, idx, false);
// TODO: currently connectInput api accept only total size, for concat we need extension for allocated, and actual sizes
bytesAllocated = inputLayer.tensorSize;
concatLayerInfo.input_allocated = true;
} else if (layerInfo.isMemory()) {
connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, -static_cast<int>(inputLayer.offset), idx);
connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, inputLayer.offset, idx, false);
concatLayerInfo.input_allocated = true;
}
@@ -2021,7 +2015,7 @@ void GNAGraphCompiler::connectOutput(InferenceEngine::CNNLayerPtr layer, void *p
}
}
GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, void *ptr, size_t num_data_bytes_in, int32_t offset, int idx) {
GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, void *ptr, size_t num_data_bytes_in, int32_t offset, int idx, bool connectTo) {
// selecting particular input layers
// auto prevLayer = CNNNetPrevLayer(layer, idx);
auto prevLayer = CNNNetPrevLayerSkipCertain(layer, idx, [](CNNLayerPtr l) {
@@ -2041,7 +2035,7 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
}
// real allocation pointer will be kept in ptr not in ptr_inputs_global
if (offset < 0) {
if (!connectTo) {
gnamem->push_value(ptr,
static_cast<uint8_t>(0),
num_data_bytes_in,
@@ -2062,20 +2056,20 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
<< ", and size_requested=" << num_data_bytes_in;
}
if (offset >= 0) {
gnamem->bind_ptr(ptr, &inputDesc->getPtrInputsGlobal(prevLayer->name).front(), offset);
if (connectTo) {
gnamem->bind_ptr(ptr, &inputDesc->getPtrInputsGlobal(prevLayer->name).front(), offset, ALIGN(num_data_bytes_in, 64));
} else {
gnamem->bind_ptr(&inputDesc->getPtrInputsGlobal(prevLayer->name).front(), ptr, -offset);
gnamem->bind_ptr(&inputDesc->getPtrInputsGlobal(prevLayer->name).front(), ptr, offset, ALIGN(num_data_bytes_in, 64));
}
return prevLayer;
}
// const input
if (LayerInfo(prevLayer).isConst()) {
if (offset >= 0) {
if (connectTo) {
gnamem->bind_ptr(ptr, const_connections[prevLayer->name], offset);
} else {
gnamem->bind_ptr(const_connections[prevLayer->name], ptr, -offset);
gnamem->bind_ptr(const_connections[prevLayer->name], ptr, offset);
}
return prevLayer;
@@ -2146,17 +2140,17 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
if (memoryLayer.reserved_size == 0) {
auto memorySize = InferenceEngine::details::product(memoryLayer.getDims()) * memoryLayer.elementSizeBytes();
// negative offset used for indicate that memory layer should be bound to given buffer
if (offset >= 0) {
// connectTo used for indicate that memory layer should be bound to given buffer
if (connectTo) {
memorySize = std::max(memorySize, num_data_bytes_in);
gnamem->reserve_ptr(&memoryLayer.gna_ptr, ALIGN64(memorySize), 64);
gnamem->bind_ptr(ptr, &memoryLayer.gna_ptr, offset);
} else {
if (num_data_bytes_in > memorySize - offset) {
if (num_data_bytes_in < memorySize + offset) {
THROW_GNA_LAYER_EXCEPTION(layer) <<" invalid allocation request of "
<< num_data_bytes_in << " is more then state tensor size of: " << memorySize;
<< num_data_bytes_in << " is more then state tensor size of: " << memorySize + offset;
}
gnamem->bind_ptr(&memoryLayer.gna_ptr, ptr, -offset);
gnamem->bind_ptr(&memoryLayer.gna_ptr, ptr, offset);
}
memoryLayer.reserved_size = ALIGN64(memorySize);

View File

@@ -84,13 +84,16 @@ public:
* @param num_data_bytes_in - size
* @param offset - num bytes to advance in buffer
* @param idx - index of input port that we are connecting
* @param connectTo - connectTo is true is alternative to positive or equal to zero offset
* in case when we would like to use zero offset and connect from pointer set this to negative
* @return layer used as input
*/
GNAPluginNS::ConnectionDetails connectInput(InferenceEngine::CNNLayerPtr layer,
void *pVoid,
size_t num_data_bytes_in,
int32_t offset = 0,
int idx = 0);
int idx = 0,
bool connectTo = true);
/**
* Fill in the Affine layer weights

View File

@@ -0,0 +1,38 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "subgraph_tests/first_connect_input_concat.hpp"
#include "common_test_utils/test_constants.hpp"
using namespace LayerTestsDefinitions;
namespace {
std::vector<std::vector<std::vector<size_t>>> inShapes = {
{{1, 1288}},
{{1, 56}},
{{1, 6456}}
};
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16,
};
std::map<std::string, std::string> additional_config = {
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"},
{"GNA_COMPACT_MODE", "NO"},
};
INSTANTIATE_TEST_CASE_P(smoke_concat_first_input, ConcatFirstInputTest,
::testing::Combine(
::testing::ValuesIn(inShapes),
::testing::ValuesIn(netPrecisions),
::testing::Values(CommonTestUtils::DEVICE_GNA),
::testing::Values(additional_config)),
ConcatFirstInputTest::getTestCaseName);
} //namespace

View File

@@ -0,0 +1,33 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <tuple>
#include <vector>
#include <string>
#include <memory>
#include <ngraph_functions/builders.hpp>
#include <functional_test_utils/layer_test_utils.hpp>
typedef std::tuple<
std::vector<std::vector<size_t>>, // Input shapes
InferenceEngine::Precision, // Network Precision
std::string, // Target Device
std::map<std::string, std::string> // Config
> concatFirstInputParams;
namespace LayerTestsDefinitions {
class ConcatFirstInputTest : public testing::WithParamInterface<concatFirstInputParams>,
virtual public LayerTestsUtils::LayerTestsCommon {
public:
static std::string getTestCaseName(testing::TestParamInfo<concatFirstInputParams> obj);
protected:
void SetUp() override;
};
} // namespace LayerTestsDefinitions

View File

@@ -0,0 +1,58 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <memory>
#include <tuple>
#include <vector>
#include <string>
#include <ie_core.hpp>
#include "common_test_utils/common_utils.hpp"
#include "functional_test_utils/plugin_cache.hpp"
#include "functional_test_utils/layer_test_utils.hpp"
#include "functional_test_utils/blob_utils.hpp"
#include "ngraph_functions/pass/convert_prc.hpp"
#include "subgraph_tests/first_connect_input_concat.hpp"
namespace LayerTestsDefinitions {
std::string ConcatFirstInputTest::getTestCaseName(testing::TestParamInfo<concatFirstInputParams> obj) {
std::vector<std::vector<size_t>> inputShapes;
InferenceEngine::Precision netPrecision;
std::string targetDevice;
std::map<std::string, std::string> additional_config;
std::tie(inputShapes, netPrecision, targetDevice, additional_config) = obj.param;
std::ostringstream result;
result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "targetDevice=" << targetDevice;
return result.str();
}
void ConcatFirstInputTest::SetUp() {
std::vector<std::vector<size_t>> inputShapes;
InferenceEngine::Precision netPrecision;
std::map<std::string, std::string> additional_config;
std::tie(inputShapes, netPrecision, targetDevice, configuration) = this->GetParam();
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto params = ngraph::builder::makeParams(ngPrc, inputShapes);
auto const_second_param = ngraph::builder::makeConstant(ngPrc, {1, 8}, std::vector<float>{-1.0f});
auto concat = std::make_shared<ngraph::opset1::Concat>(ngraph::OutputVector{params[0], const_second_param}, 1);
auto relu = std::make_shared<ngraph::opset1::Relu>(concat);
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(relu)};
function = std::make_shared<ngraph::Function>(results, params, "ConcatMultiInput");
}
TEST_P(ConcatFirstInputTest, CompareWithRefImpl) {
Run();
};
} // namespace LayerTestsDefinitions