diff --git a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp index dbc1c9f3166..03f901eea27 100644 --- a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp +++ b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp @@ -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; diff --git a/inference-engine/src/gna_plugin/gna_groups.hpp b/inference-engine/src/gna_plugin/gna_groups.hpp index 30faed46731..1844be79fc6 100644 --- a/inference-engine/src/gna_plugin/gna_groups.hpp +++ b/inference-engine/src/gna_plugin/gna_groups.hpp @@ -5,6 +5,7 @@ #pragma once #include +#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(); } diff --git a/inference-engine/src/gna_plugin/gna_model_serial.cpp b/inference-engine/src/gna_plugin/gna_model_serial.cpp index 3effccfb85e..6cc23248a14 100644 --- a/inference-engine/src/gna_plugin/gna_model_serial.cpp +++ b/inference-engine/src/gna_plugin/gna_model_serial.cpp @@ -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(nameSize), os); writeNBytes(transpositionInfo.first.c_str(), nameSize, os); auto fragmentsNum = transpositionInfo.second.size(); diff --git a/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp b/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp index 21ac4b2c47c..a91b049c1b2 100644 --- a/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp +++ b/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp @@ -270,6 +270,9 @@ class LayerInfo { } return true; } + bool isNonValuesChangable() const { + return isNonFunctional() || isSplit() || isSlice() || isConcat(); + } bool isPooling() const noexcept { return isOfType("pooling"); } diff --git a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp index 02e0d7434b0..03750a079ef 100644 --- a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp +++ b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp @@ -81,9 +81,13 @@ static void insertDiagonalLayerBetween(InferenceEngine::CNNLayerPtr prevLayer, auto diagLayer = std::make_shared(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 weightsValues(weightsSize, fillValue); IE_ASSERT(diagLayer != nullptr); diagLayer->_weights = make_shared_blob( diff --git a/inference-engine/src/gna_plugin/runtime/gna_float_runtime_op.cpp b/inference-engine/src/gna_plugin/runtime/gna_float_runtime_op.cpp index f91ba6c9f31..49c1727fd5d 100644 --- a/inference-engine/src/gna_plugin/runtime/gna_float_runtime_op.cpp +++ b/inference-engine/src/gna_plugin/runtime/gna_float_runtime_op.cpp @@ -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 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); } } diff --git a/inference-engine/tests/functional/plugin/gna/Import_export_tests/import_export_act_conv_act.cpp b/inference-engine/tests/functional/plugin/gna/Import_export_tests/import_export_act_conv_act.cpp new file mode 100644 index 00000000000..283d232e0ce --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/Import_export_tests/import_export_act_conv_act.cpp @@ -0,0 +1,178 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include +#include +#include + +#include +#include + +#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, // Input shape + InferenceEngine::Precision, // Network Precision + std::string, // Target Device + std::map, // Export Configuration + std::map // Import Configuration +> exportImportNetworkParams; + +namespace LayerTestsDefinitions { + +class ImportActConvActTest : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj) { + std::vector inputShape; + InferenceEngine::Precision netPrecision; + std::string targetDevice; + std::map exportConfiguration; + std::map 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 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{}; + 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 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(params[0]); + + size_t num_out_channels = 8; + size_t kernel_size = 8; + std::vector 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(conv); + ngraph::ResultVector results{std::make_shared(relu2)}; + function = std::make_shared(results, params, "ExportImportNetwork"); + } + +private: + std::map exportConfiguration; + std::map importConfiguration; +}; + +TEST_P(ImportActConvActTest, CompareWithRefImpl) { + Run(); +}; + +const std::vector> inputShape = { + {1, 1, 1, 240}, + {1, 1, 1, 160}, + {1, 2, 1, 80} +}; + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 +}; + +const std::vector> exportConfigs = { + { + {"GNA_DEVICE_MODE", "GNA_SW_EXACT"} + } +}; + +const std::vector> 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 + diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp index d114747234a..1eb8e7a275a 100644 --- a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/single_layer_tests/activation.cpp @@ -39,11 +39,7 @@ std::map, std::vector>> 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}, {{}}}, diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/eltwise_reshape_activation.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/eltwise_reshape_activation.cpp new file mode 100644 index 00000000000..332da49fb38 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/eltwise_reshape_activation.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "subgraph_tests/eltwise_reshape_activation.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace SubgraphTestsDefinitions; +namespace { +const std::vector>> shapes = { + {{1, 64}, {64, 1}}, + {{8, 256}, {16, 128}}, + {{6, 384}, {18, 128}}, + {{8, 2048}, {32, 512}} +}; + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 +}; + +std::vector> 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 diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/eltwise_reshape_activation.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/eltwise_reshape_activation.hpp new file mode 100644 index 00000000000..17232b3efad --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/eltwise_reshape_activation.hpp @@ -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 diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/eltwise_reshape_activation.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/eltwise_reshape_activation.hpp new file mode 100644 index 00000000000..5a20bfe40f0 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/subgraph/eltwise_reshape_activation.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "shared_test_classes/base/layer_test_utils.hpp" + +namespace SubgraphTestsDefinitions { + +using EltwiseReshapeActivationParams = typename std::tuple< + std::vector>, // input shape and shape after reshape + InferenceEngine::Precision, // precision + std::string, // device name + std::map // configuration +>; + +class EltwiseReshapeActivation : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; +}; + +} // namespace SubgraphTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/subgraph/eltwise_reshape_activation.cpp b/inference-engine/tests/functional/shared_test_classes/src/subgraph/eltwise_reshape_activation.cpp new file mode 100644 index 00000000000..74b8e76bf16 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/src/subgraph/eltwise_reshape_activation.cpp @@ -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 obj) { + InferenceEngine::Precision netPrecision; + std::vector> shapes; + std::string targetDevice; + std::map 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> shapes; + std::map 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::element::i64, ngraph::Shape{shapes[1].size()}, shapes[1]); + auto reshape1 = std::make_shared(eltw, reshape_pattern1, false); + + auto relu = ngraph::builder::makeActivation(reshape1, ngPrc, ngraph::helpers::ActivationTypes::Relu); + + auto reshape_pattern2 = std::make_shared(ngraph::element::i64, ngraph::Shape{shapes[0].size()}, shapes[0]); + auto reshape2 = std::make_shared(relu, reshape_pattern2, false); + + function = std::make_shared(reshape2, input, "EltwiseReshapeActivation"); +} +} // namespace SubgraphTestsDefinitions