[GNA] Prohibit 2D data reshaping for diagonal layer if it's the first functional layer in network (#5097)
This commit is contained in:
parent
e864972f83
commit
69be1f1c02
@ -1204,16 +1204,17 @@ void GNAGraphCompiler::EltwisePrimitive(InferenceEngine::CNNLayerPtr layer) {
|
||||
auto in_2b_width = GetDataDimSize(inputs2Bytes, InferenceEngine::DataDimName::W);
|
||||
auto in_2b_total_size = in_2b_batch * in_2b_channels * in_2b_height * in_2b_width;
|
||||
|
||||
if (((in_2b_batch > 1) || (in_4b_batch > 1)) && in_2b_batch != in_4b_batch) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << " Inputs with different batch sizes that not equals 1 is not supported";
|
||||
if (in_2b_batch != in_4b_batch) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << " Inputs with different batch sizes are not supported";
|
||||
}
|
||||
|
||||
if (in_4b_total_size != in_2b_total_size) {
|
||||
THROW_GNA_LAYER_EXCEPTION(layer) << " Inputs size mismatch " << in_4b_total_size << " != " << in_2b_total_size;
|
||||
}
|
||||
|
||||
uint32_t num_rows_in = in_4b_channels * in_4b_height * in_4b_width;
|
||||
uint32_t num_columns_in = in_4b_batch;
|
||||
// If batch size > 1 the data is reshaped to one with batch size = 1
|
||||
uint32_t num_rows_in = in_4b_total_size;
|
||||
uint32_t num_columns_in = 1;
|
||||
uint32_t num_rows_out = num_rows_in;
|
||||
uint32_t num_padding = ALIGN(num_rows_in, noOfInputsDivisor) - num_rows_in;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <legacy/graph_tools.hpp>
|
||||
#include "gna_graph_tools.hpp"
|
||||
#include "gna_plugin_log.hpp"
|
||||
#include "layers/gna_layer_info.hpp"
|
||||
|
||||
@ -54,6 +55,14 @@ inline bool HasTo2DReshapeData(InferenceEngine::CNNLayerPtr layer) {
|
||||
if (layer->name.rfind("SyntheticScaleShift", 0) == std::string::npos)
|
||||
return false;
|
||||
|
||||
// Don't reshape the first dnn layer since it breaks groups recognition
|
||||
auto prevLayer = InferenceEngine::CNNNetPrevLayerSkipCertain(layer, 0, [](InferenceEngine::CNNLayerPtr ptr) {
|
||||
return LayerInfo(ptr).isNonValuesChangable();
|
||||
});
|
||||
IE_ASSERT(prevLayer != nullptr);
|
||||
if (LayerInfo(prevLayer).isInput())
|
||||
return false;
|
||||
|
||||
// Don't reshape diagonallayers with bias connection
|
||||
return !GNAPluginNS::LayerInfo(getCreatorLayer(layer->insData.front().lock()).lock()).has32BOutput();
|
||||
}
|
||||
|
@ -913,7 +913,7 @@ void GNAModelSerial::ImportTranspositionInfo(std::istream &is,
|
||||
void GNAModelSerial::ExportTranspositionInfo(std::ostream &os,
|
||||
const TranspositionInfoMap &transpositionInfoMap) const {
|
||||
for (const auto &transpositionInfo : transpositionInfoMap) {
|
||||
auto nameSize = strlen(transpositionInfo.first.c_str()) + 1;
|
||||
auto nameSize = strlen(transpositionInfo.first.c_str());
|
||||
writeBits(static_cast<uint32_t>(nameSize), os);
|
||||
writeNBytes(transpositionInfo.first.c_str(), nameSize, os);
|
||||
auto fragmentsNum = transpositionInfo.second.size();
|
||||
|
@ -270,6 +270,9 @@ class LayerInfo {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool isNonValuesChangable() const {
|
||||
return isNonFunctional() || isSplit() || isSlice() || isConcat();
|
||||
}
|
||||
bool isPooling() const noexcept {
|
||||
return isOfType("pooling");
|
||||
}
|
||||
|
@ -81,9 +81,13 @@ static void insertDiagonalLayerBetween(InferenceEngine::CNNLayerPtr prevLayer,
|
||||
auto diagLayer = std::make_shared<ScaleShiftLayer>(LayerParams({diagName, "ScaleShift", Precision::FP32}));
|
||||
IE_ASSERT(diagLayer != nullptr);
|
||||
|
||||
// TODO: diagonal size
|
||||
size_t weightsSize = LayerInfo(prevLayer).has32BOutput() ? weightsSize = nextLayer->outData[0]->getDims().back() :
|
||||
Get2DReshapedData(nextLayer->outData[0], 8)->getDims()[1];
|
||||
auto inputLayer = InferenceEngine::CNNNetPrevLayerSkipCertain(nextLayer, 0, [](InferenceEngine::CNNLayerPtr ptr) {
|
||||
return LayerInfo(ptr).isNonValuesChangable();
|
||||
});
|
||||
IE_ASSERT(inputLayer != nullptr);
|
||||
size_t weightsSize = (LayerInfo(prevLayer).has32BOutput() || LayerInfo(inputLayer).isInput()) ?
|
||||
weightsSize = nextLayer->outData[0]->getDims().back() :
|
||||
Get2DReshapedData(nextLayer->outData[0], 8)->getDims()[1];
|
||||
std::vector<float> weightsValues(weightsSize, fillValue);
|
||||
IE_ASSERT(diagLayer != nullptr);
|
||||
diagLayer->_weights = make_shared_blob<float>(
|
||||
|
@ -79,10 +79,12 @@ void FP::ApplyDiagonalTransform(intel_dnn_component_t *component) {
|
||||
C[i * ldc + j] = bias[i];
|
||||
}
|
||||
}
|
||||
for (uint32_t j = 0; j < n; j++) {
|
||||
float *Bcol = B + j * component->num_rows_in;
|
||||
float *Ccol = C + j * component->num_rows_out;
|
||||
cblas_ssbmv1(CblasRowMajor, CblasLower, m, 0, 1.0, A, 1, Bcol, 1, 1.0, Ccol, 1);
|
||||
std::vector<float> Arow(n);
|
||||
for (uint32_t i = 0; i < m; i++) {
|
||||
float *Brow = B + i * n;
|
||||
float *Crow = C + i * ldc;
|
||||
std::fill(std::begin(Arow), std::end(Arow), A[i]);
|
||||
cblas_ssbmv1(CblasRowMajor, CblasLower, n, 0, 1.0, Arow.data(), 1, Brow, 1, 1.0, Crow, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,178 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <ie_core.hpp>
|
||||
#include <ie_layouts.h>
|
||||
|
||||
#include "shared_test_classes/base/layer_test_utils.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
typedef std::tuple<
|
||||
std::vector<size_t>, // Input shape
|
||||
InferenceEngine::Precision, // Network Precision
|
||||
std::string, // Target Device
|
||||
std::map<std::string, std::string>, // Export Configuration
|
||||
std::map<std::string, std::string> // Import Configuration
|
||||
> exportImportNetworkParams;
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
class ImportActConvActTest : public testing::WithParamInterface<exportImportNetworkParams>,
|
||||
public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<exportImportNetworkParams> obj) {
|
||||
std::vector<size_t> inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::string targetDevice;
|
||||
std::map<std::string, std::string> exportConfiguration;
|
||||
std::map<std::string, std::string> importConfiguration;
|
||||
std::tie(inputShape, netPrecision, targetDevice, exportConfiguration, importConfiguration) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "targetDevice=" << targetDevice << "_";
|
||||
for (auto const &configItem : exportConfiguration) {
|
||||
result << "_exportConfigItem=" << configItem.first << "_" << configItem.second;
|
||||
}
|
||||
for (auto const &configItem : importConfiguration) {
|
||||
result << "_importConfigItem=" << configItem.first << "_" << configItem.second;
|
||||
}
|
||||
result << CommonTestUtils::vec2str(inputShape);
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
|
||||
configuration.insert(exportConfiguration.begin(), exportConfiguration.end());
|
||||
LoadNetwork();
|
||||
GenerateInputs();
|
||||
Infer();
|
||||
|
||||
executableNetwork.Export("exported_model.blob");
|
||||
for (auto const &configItem : importConfiguration) {
|
||||
configuration[configItem.first] = configItem.second;
|
||||
}
|
||||
std::fstream inputStream("exported_model.blob", std::ios_base::in | std::ios_base::binary);
|
||||
if (inputStream.fail()) {
|
||||
FAIL() << "Cannot open file to import model: exported_model.blob";
|
||||
}
|
||||
|
||||
auto importedNetwork = core->ImportNetwork(inputStream, targetDevice, configuration);
|
||||
|
||||
// Generate inputs
|
||||
std::vector<InferenceEngine::Blob::Ptr> inputs;
|
||||
auto inputsInfo = importedNetwork.GetInputsInfo();
|
||||
auto functionParams = function->get_parameters();
|
||||
for (int i = 0; i < functionParams.size(); ++i) {
|
||||
const auto& param = functionParams[i];
|
||||
const auto infoIt = inputsInfo.find(param->get_friendly_name());
|
||||
GTEST_ASSERT_NE(infoIt, inputsInfo.cend());
|
||||
|
||||
const auto& info = infoIt->second;
|
||||
auto blob = GenerateInput(*info);
|
||||
inputs.push_back(blob);
|
||||
}
|
||||
|
||||
// Infer imported network
|
||||
InferenceEngine::InferRequest importInfer = importedNetwork.CreateInferRequest();
|
||||
inputsInfo = importedNetwork.GetInputsInfo();
|
||||
functionParams = function->get_parameters();
|
||||
for (int i = 0; i < functionParams.size(); ++i) {
|
||||
const auto& param = functionParams[i];
|
||||
const auto infoIt = inputsInfo.find(param->get_friendly_name());
|
||||
GTEST_ASSERT_NE(infoIt, inputsInfo.cend());
|
||||
|
||||
const auto& info = infoIt->second;
|
||||
auto blob = inputs[i];
|
||||
importInfer.SetBlob(info->name(), blob);
|
||||
}
|
||||
importInfer.Infer();
|
||||
|
||||
// Validate
|
||||
auto expectedOutputs = CalculateRefs();
|
||||
auto actualOutputs = std::vector<InferenceEngine::Blob::Ptr>{};
|
||||
for (const auto &output : importedNetwork.GetOutputsInfo()) {
|
||||
const auto &name = output.first;
|
||||
actualOutputs.push_back(importInfer.GetBlob(name));
|
||||
}
|
||||
IE_ASSERT(actualOutputs.size() == expectedOutputs.size())
|
||||
<< "nGraph interpreter has " << expectedOutputs.size() << " outputs, while IE " << actualOutputs.size();
|
||||
Compare(expectedOutputs, actualOutputs);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
std::vector<size_t> inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(inputShape, netPrecision, targetDevice, exportConfiguration, importConfiguration) = this->GetParam();
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
|
||||
auto params = ngraph::builder::makeParams(ngPrc, {inputShape});
|
||||
auto relu1 = std::make_shared<ngraph::opset1::Relu>(params[0]);
|
||||
|
||||
size_t num_out_channels = 8;
|
||||
size_t kernel_size = 8;
|
||||
std::vector<float> filter_weights = CommonTestUtils::generate_float_numbers(num_out_channels * inputShape[1] * kernel_size,
|
||||
-0.2f, 0.2f);
|
||||
auto conv = ngraph::builder::makeConvolution(relu1, ngPrc, { 1, kernel_size }, { 1, 1 }, { 0, 0 }, { 0, 0 }, { 1, 1 },
|
||||
ngraph::op::PadType::VALID, num_out_channels, true, filter_weights);
|
||||
|
||||
auto relu2 = std::make_shared<ngraph::opset1::Relu>(conv);
|
||||
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(relu2)};
|
||||
function = std::make_shared<ngraph::Function>(results, params, "ExportImportNetwork");
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> exportConfiguration;
|
||||
std::map<std::string, std::string> importConfiguration;
|
||||
};
|
||||
|
||||
TEST_P(ImportActConvActTest, CompareWithRefImpl) {
|
||||
Run();
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> inputShape = {
|
||||
{1, 1, 1, 240},
|
||||
{1, 1, 1, 160},
|
||||
{1, 2, 1, 80}
|
||||
};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> netPrecisions = {
|
||||
InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16
|
||||
};
|
||||
|
||||
const std::vector<std::map<std::string, std::string>> exportConfigs = {
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}
|
||||
}
|
||||
};
|
||||
|
||||
const std::vector<std::map<std::string, std::string>> importConfigs = {
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_ImportActConvAct, ImportActConvActTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShape),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GNA),
|
||||
::testing::ValuesIn(exportConfigs),
|
||||
::testing::ValuesIn(importConfigs)),
|
||||
ImportActConvActTest::getTestCaseName);
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
|
@ -39,11 +39,7 @@ std::map<std::vector<size_t>, std::vector<std::vector<size_t>>> basic = {
|
||||
{{1, 50}, {{}}},
|
||||
{{1, 128}, {{}}},
|
||||
{{1, 10 * 1024}, {{}}},
|
||||
{{64, 1}, {{}}},
|
||||
{{8, 128}, {{}}},
|
||||
{{16, 128}, {{}}},
|
||||
{{18, 128}, {{}}},
|
||||
{{32, 512}, {{}}},
|
||||
{{1, 4, 2, 256}, {{}}},
|
||||
{{4, 4, 4, 4}, {{}}},
|
||||
{{1, 16, 1, 128}, {{}}},
|
||||
|
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "subgraph_tests/eltwise_reshape_activation.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace SubgraphTestsDefinitions;
|
||||
namespace {
|
||||
const std::vector<std::vector<std::vector<size_t>>> shapes = {
|
||||
{{1, 64}, {64, 1}},
|
||||
{{8, 256}, {16, 128}},
|
||||
{{6, 384}, {18, 128}},
|
||||
{{8, 2048}, {32, 512}}
|
||||
};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> netPrecisions = {
|
||||
InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16
|
||||
};
|
||||
|
||||
std::vector<std::map<std::string, std::string>> additional_config = {
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_FP32"}
|
||||
},
|
||||
{
|
||||
{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_EltwiseReshapeActivationTest, EltwiseReshapeActivation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(shapes),
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GNA),
|
||||
::testing::ValuesIn(additional_config)),
|
||||
EltwiseReshapeActivation::getTestCaseName);
|
||||
|
||||
} // namespace
|
@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared_test_classes/subgraph/eltwise_reshape_activation.hpp"
|
||||
|
||||
namespace SubgraphTestsDefinitions {
|
||||
|
||||
TEST_P(EltwiseReshapeActivation, CompareWithRefs) {
|
||||
Run();
|
||||
}
|
||||
|
||||
} // namespace SubgraphTestsDefinitions
|
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "shared_test_classes/base/layer_test_utils.hpp"
|
||||
|
||||
namespace SubgraphTestsDefinitions {
|
||||
|
||||
using EltwiseReshapeActivationParams = typename std::tuple<
|
||||
std::vector<std::vector<size_t>>, // input shape and shape after reshape
|
||||
InferenceEngine::Precision, // precision
|
||||
std::string, // device name
|
||||
std::map<std::string, std::string> // configuration
|
||||
>;
|
||||
|
||||
class EltwiseReshapeActivation : public testing::WithParamInterface<EltwiseReshapeActivationParams>,
|
||||
public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<ParamType> obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace SubgraphTestsDefinitions
|
@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "shared_test_classes/subgraph/eltwise_reshape_activation.hpp"
|
||||
|
||||
namespace SubgraphTestsDefinitions {
|
||||
|
||||
using namespace CommonTestUtils;
|
||||
using namespace InferenceEngine;
|
||||
|
||||
std::string EltwiseReshapeActivation::getTestCaseName(testing::TestParamInfo<ParamType> obj) {
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::vector<std::vector<size_t>> shapes;
|
||||
std::string targetDevice;
|
||||
std::map<std::string, std::string> configuration;
|
||||
std::tie(shapes, netPrecision, targetDevice, configuration) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=" << CommonTestUtils::vec2str(shapes[0]) << "_";
|
||||
result << "AS=" << CommonTestUtils::vec2str(shapes[1]) << "_";
|
||||
result << "PRC=" << netPrecision.name() << "_";
|
||||
result << "dev=" << targetDevice;
|
||||
for (auto const& configItem : configuration) {
|
||||
result << "_configItem=" << configItem.first << "_" << configItem.second;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void EltwiseReshapeActivation::SetUp() {
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::vector<std::vector<size_t>> shapes;
|
||||
std::map<std::string, std::string> config;
|
||||
std::tie(shapes, netPrecision, targetDevice, config) = this->GetParam();
|
||||
configuration.insert(config.begin(), config.end());
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
|
||||
auto input = ngraph::builder::makeParams(ngPrc, { shapes[0], shapes[0] });
|
||||
auto eltw = ngraph::builder::makeEltwise(input[0], input[1], ngraph::helpers::EltwiseTypes::ADD);
|
||||
|
||||
auto reshape_pattern1 = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{shapes[1].size()}, shapes[1]);
|
||||
auto reshape1 = std::make_shared<ngraph::op::v1::Reshape>(eltw, reshape_pattern1, false);
|
||||
|
||||
auto relu = ngraph::builder::makeActivation(reshape1, ngPrc, ngraph::helpers::ActivationTypes::Relu);
|
||||
|
||||
auto reshape_pattern2 = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{shapes[0].size()}, shapes[0]);
|
||||
auto reshape2 = std::make_shared<ngraph::op::v1::Reshape>(relu, reshape_pattern2, false);
|
||||
|
||||
function = std::make_shared<ngraph::Function>(reshape2, input, "EltwiseReshapeActivation");
|
||||
}
|
||||
} // namespace SubgraphTestsDefinitions
|
Loading…
Reference in New Issue
Block a user