diff --git a/inference-engine/src/gna_plugin/backend/am_intel_dnn.cpp b/inference-engine/src/gna_plugin/backend/am_intel_dnn.cpp index 8c7d8f22255..49fcb03d330 100644 --- a/inference-engine/src/gna_plugin/backend/am_intel_dnn.cpp +++ b/inference-engine/src/gna_plugin/backend/am_intel_dnn.cpp @@ -311,6 +311,65 @@ void GNAPluginNS::backend::AMIntelDNN::InitPiecewiseLinearComponentPrivate(intel } } +void GNAPluginNS::backend::AMIntelDNN::InitInterleaveComponentPrivate(intel_dnn_component_t &comp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + void *&ptr_inputs, + void *&ptr_outputs, + bool postInitMem) { + comp.num_rows_in = num_rows_in; + comp.num_columns_in = num_columns_in; + comp.num_rows_out = num_columns_in; + comp.num_columns_out = num_rows_in; + comp.num_bytes_per_input = num_bytes_per_input; + comp.num_bytes_per_output = num_bytes_per_output; + comp.operation = kDnnInterleaveOp; + comp.macro_operation = kDnnMacroOpNone; + comp.orientation_in = kDnnNonInterleavedOrientation; + comp.orientation_out = kDnnInterleavedOrientation; + comp.output_scale_factor = output_scale_factor; + comp.input_scale_factor = output_scale_factor; + if (!postInitMem) { + comp.ptr_inputs = ptr_inputs; + comp.ptr_outputs = ptr_outputs; + } else { + ptr_inputs = &comp.ptr_inputs; + ptr_outputs = &comp.ptr_outputs; + } +} + +void GNAPluginNS::backend::AMIntelDNN::InitDeinterleaveComponentPrivate(intel_dnn_component_t &comp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + void *&ptr_inputs, + void *&ptr_outputs, + bool postInitMem) { + comp.num_rows_in = num_rows_in; + comp.num_columns_in = num_columns_in; + comp.num_rows_out = num_columns_in; + comp.num_columns_out = num_rows_in; + comp.num_bytes_per_input = num_bytes_per_input; + comp.num_bytes_per_output = num_bytes_per_output; + comp.operation = kDnnDeinterleaveOp; + comp.macro_operation = kDnnMacroOpNone; + comp.orientation_in = kDnnInterleavedOrientation; + comp.orientation_out = kDnnNonInterleavedOrientation; + comp.output_scale_factor = output_scale_factor; + comp.input_scale_factor = output_scale_factor; + if (!postInitMem) { + comp.ptr_inputs = ptr_inputs; + comp.ptr_outputs = ptr_outputs; + } else { + ptr_inputs = &comp.ptr_inputs; + ptr_outputs = &comp.ptr_outputs; + } +} void GNAPluginNS::backend::AMIntelDNN::Propagate() { for (uint32_t i = 0; i < component.size(); i++) { diff --git a/inference-engine/src/gna_plugin/backend/am_intel_dnn.hpp b/inference-engine/src/gna_plugin/backend/am_intel_dnn.hpp index 66536ff519e..97092148c03 100644 --- a/inference-engine/src/gna_plugin/backend/am_intel_dnn.hpp +++ b/inference-engine/src/gna_plugin/backend/am_intel_dnn.hpp @@ -193,6 +193,46 @@ public: true); } + template + static void InitDeinterleaveComponent(intel_dnn_component_t &cmp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + A *&ptr_inputs, + B *&ptr_outputs) { + InitDeinterleaveComponentPrivate(cmp, + num_rows_in, + num_columns_in, + num_bytes_per_input, + num_bytes_per_output, + output_scale_factor, + (void *&) ptr_inputs, + (void *&) ptr_outputs, + true); + } + + template + static void InitInterleaveComponent(intel_dnn_component_t &cmp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + A *&ptr_inputs, + B *&ptr_outputs) { + InitInterleaveComponentPrivate(cmp, + num_rows_in, + num_columns_in, + num_bytes_per_input, + num_bytes_per_output, + output_scale_factor, + (void *&) ptr_inputs, + (void *&) ptr_outputs, + true); + } + template static void InitCopyComponent(intel_dnn_component_t &cmp, @@ -343,6 +383,26 @@ private: intel_pwl_segment_t *ptr_segments, bool postInitMem); + static void InitInterleaveComponentPrivate(intel_dnn_component_t &cmp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + void *&ptr_inputs, + void *&ptr_outputs, + bool postInitMem); + + static void InitDeinterleaveComponentPrivate(intel_dnn_component_t &cmp, + uint32_t num_rows_in, + uint32_t num_columns_in, + uint32_t num_bytes_per_input, + uint32_t num_bytes_per_output, + float output_scale_factor, + void *&ptr_inputs, + void *&ptr_outputs, + bool postInitMem); + static void InitConvolutional1DComponentPrivate(intel_dnn_component_t &comp, uint32_t num_rows_in, uint32_t num_columns_in, diff --git a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp index 46f41199ee9..ef0649d061d 100644 --- a/inference-engine/src/gna_plugin/gna_graph_compiler.cpp +++ b/inference-engine/src/gna_plugin/gna_graph_compiler.cpp @@ -1412,30 +1412,76 @@ case name:\ } void GNAGraphCompiler::PermutePrimitive(InferenceEngine::CNNLayerPtr layer) { + if (LayerInfo(layer).isTrivialPermute()) { + return; + } auto layerOrder = layer->GetParamAsInts("order"); + auto quantized = InferenceEngine::getInjectedData(layer); + auto inputs = layer->insData.begin()->lock(); + auto inputsOrder = inputs->getTensorDesc().getDims(); + auto outputs = layer->outData.front(); - string dimMessage; - if (layerOrder == vector({0, 3, 2, 1})) { - return; // supported case + // squeeze order vector + SizeVector squeezedInputOrder; + for (auto input_shape : inputsOrder) { + if (input_shape != 1) squeezedInputOrder.push_back(input_shape); + } + SizeVector squeezedOutputOrder; + for (auto output_shape : layerOrder) { + if (output_shape != 0) squeezedOutputOrder.push_back(output_shape); } - if (layerOrder == vector({1, 0, 2})) { - IE_ASSERT(!layer->insData.empty()); - auto inputs = layer->insData.begin()->lock(); - auto inputs_size = inputs->getTensorDesc().getDims().size(); - if (inputs_size != layerOrder.size()) { - THROW_IE_EXCEPTION << "[GNA plugin] Invalid input tensor size for permute layer " << - layer->GetParamAsString("order"); - } - auto permuteDim0 = FROM_IR_DIM(inputs, inputs_size); - auto permuteDim1 = FROM_IR_DIM(inputs, inputs_size - 1); - if (permuteDim0 == 1 || permuteDim1 == 1) { - return; // supported case - } - dimMessage = " (with first dim = " + to_string(permuteDim0) + ", second dim = " + to_string(permuteDim1) + ")"; + void* ptr_inputs = nullptr; + void* ptr_outputs = nullptr; + + if (squeezedInputOrder.size() > 2) { + THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (requested transpose is not 2D)"; } - THROW_IE_EXCEPTION << "[GNA plugin] Unsupported permute order: was " << layer->GetParamAsString("order") << - dimMessage << ", but only support 1,0,2 (with first or second dim = 1) and 0,3,2,1"; + + if (std::min(squeezedInputOrder[0], squeezedInputOrder[1]) > 8) { + THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (minor dimension=" + << std::min(squeezedInputOrder[0], squeezedInputOrder[1]) << " > 8)"; + } + + // now this can be run on GNA + if (squeezedInputOrder[0] < squeezedInputOrder[1]) { // interleave case + if (ALIGN(squeezedInputOrder[1], 8) != squeezedInputOrder[1]) { + THROW_GNA_LAYER_EXCEPTION(layer) << "unsupported permute (row size not a multiple of 8)"; + } else { + auto& currentComponent = dnnComponents.addComponent(layer->name, "interleave"); + dnn->InitInterleaveComponent(currentComponent, + squeezedInputOrder[0], + squeezedInputOrder[1], + inputs->getPrecision().size(), + outputs->getPrecision().size(), + (quantized == nullptr) ? 1.0f : quantized->_dst_quant.scale, + ptr_inputs, + ptr_outputs); + } + + } else { // deinterleave case + if (ALIGN(squeezedInputOrder[0], 8) != squeezedInputOrder[0]) { + THROW_GNA_LAYER_EXCEPTION(layer) << "[GNA plugin] unsupported permute (column size not a multiple of 8)"; + } else { + auto& currentComponent = dnnComponents.addComponent(layer->name, "deinterleave"); + dnn->InitDeinterleaveComponent(currentComponent, + squeezedInputOrder[0], + squeezedInputOrder[1], + inputs->getPrecision().size(), + outputs->getPrecision().size(), + quantized == nullptr ? 1 : quantized->_dst_quant.scale, + ptr_inputs, + ptr_outputs); + } + } + + size_t num_data_bytes_out = ALIGN(InferenceEngine::details::product( + begin(outputs->getDims()), end(outputs->getDims())), 8) + * outputs->getPrecision().size(); + size_t num_data_bytes_in = squeezedInputOrder[0] * squeezedInputOrder[1] * inputs->getPrecision().size(); + + connectInput(layer, ptr_inputs, num_data_bytes_in); + connectOutput(layer, ptr_outputs, num_data_bytes_out); } void SKIP(GNAGraphCompiler*, CNNLayerPtr) {} @@ -1795,9 +1841,14 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, return connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0); } + // permute layer resulted in trivial permute if (LayerInfo(prevLayer).isPermute()) { - gnalog() << "Skipping permute layer: " << prevLayer->name << "\n"; - return {connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0).input, true, prevLayer}; + if (!LayerInfo(prevLayer).isTrivialPermute()) { + // we should have GNA primitive for it + THROW_GNA_EXCEPTION << "missed gna primitive for permute: " << prevLayer->name; + } + gnalog() << "Skipping trivial permute layer: " << prevLayer->name << "\n"; + return connectInput(prevLayer, ptr, num_data_bytes_in, offset, 0); } 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 4cc135e1087..4c665ebdb7f 100644 --- a/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp +++ b/inference-engine/src/gna_plugin/layers/gna_layer_info.hpp @@ -11,6 +11,7 @@ #include "details/caseless.hpp" #include "ie_algorithm.hpp" #include "gna-api.h" +#include "gna_permute.hpp" namespace GNAPluginNS { @@ -194,6 +195,42 @@ class LayerInfo { bool isPermute() const noexcept { return isOfType("permute"); } + // @brief this not only mathematically trivial, has some WA for kaldi case + bool isTrivialPermute() { + if (!isPermute()) return false; + + auto layerOrder = layer->GetParamAsInts("order"); + + if (layerOrder == std::vector({ 0, 3, 2, 1 })) { + return true; // supported case + } + auto inputs = layer->insData.begin()->lock(); + auto inputsOrder = inputs->getTensorDesc().getDims(); + + // cases when all permutations happened either between 1 and X shape where no other dims in between + auto permuteSequence = genPermutations(layerOrder.begin(), layerOrder.end()); + auto inputsOrderTransformed = inputsOrder; + for (auto && permute : permuteSequence) { + // check dims of permuted + if (inputsOrderTransformed[permute.first] == 1 && + inputsOrderTransformed[permute.second] == 1) { + return true; + } + if (inputsOrderTransformed[permute.first] != 1 && + inputsOrderTransformed[permute.second] != 1) { + return false; + } + // check dims in between + for (int j = permute.first + 1; j != permute.second; j++) { + if (inputsOrderTransformed[j] != 1) { + return false; + } + } + // apply permutation + std::swap(inputsOrderTransformed[permute.first], inputsOrderTransformed[permute.second]); + } + return true; + } bool isPooling() const noexcept { return isOfType("pooling"); } diff --git a/inference-engine/src/gna_plugin/layers/gna_permute.hpp b/inference-engine/src/gna_plugin/layers/gna_permute.hpp new file mode 100644 index 00000000000..609b7edef80 --- /dev/null +++ b/inference-engine/src/gna_plugin/layers/gna_permute.hpp @@ -0,0 +1,105 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + + +#pragma once +#include +#include +#include +#include "gna_plugin_log.hpp" + +namespace GNAPluginNS { +template +class PermuteSequence { +public: + using cnt_type = std::vector>; + +private: + std::vector orderVec; + cnt_type permutes; + +public: + explicit PermuteSequence(std::vector && orderVecIn) : orderVec(std::move(orderVecIn)) { + std::vector counter(orderVec.size()); + for (auto && x : this->orderVec) { + if (x < 0) { + THROW_GNA_EXCEPTION << "invalid order: element " << x << " should be >= 0"; + } + if (x >= counter.size()) { + THROW_GNA_EXCEPTION << "invalid order: element " << x << " should be < "<< counter.size(); + } + if (counter[x]) { + THROW_GNA_EXCEPTION << "invalid order: element " << x << " present more than once"; + } + counter[x] = true; + } + + // generating permutation graph + std::fill(counter.begin(), counter.end(), false); + + // length of current cycle + std::list permuteCycles; + int seqId = 0; + bool newSeq = false; + + for (int i = 0; i != orderVec.size();) { + // we have this permutation on the list already + if (counter[i]) { + newSeq = false; + i++; + continue; + } + counter[i] = true; + // looks we found a permutation + if (orderVec[i] != i) { + if (!newSeq) { + newSeq = true; + permuteCycles.push_back({}); + } + permuteCycles.back().push_back({i, orderVec[i]}); + counter[i] = true; + i = orderVec[i]; + continue; + } + // this dims not permuted + i++; + } + + for (auto && cycle : permuteCycles) { + for (int i = 0; i + 1 < cycle.size(); i++) { + permutes.push_back(cycle[i]); + } + } + } + const cnt_type & cnt() const noexcept { + return permutes; + } +}; + +/** + * @brief generates permutations sequence in order to reach given order + * @tparam Iterator + * @return + */ +template +inline typename PermuteSequence::value_type>::cnt_type genPermutations( + Iterator beg, Iterator en) { + static_assert( + std::is_same::iterator_category>::value, + "The genPermutations() function only accepts random access iterators or raw pointers to an array.\n"); + using value_type = typename std::iterator_traits::value_type; + std::vector v; + for (; beg != en; beg++) { + v.push_back(*beg); + } + auto permute = PermuteSequence (std::move(v)); + return permute.cnt(); +} + +template +inline typename PermuteSequence::cnt_type genPermutations(const std::initializer_list & lst) { + return genPermutations(lst.begin(), lst.end()); +} +} // namespace GNAPluginNS diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/reshapre_permute_reshape.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/reshapre_permute_reshape.cpp new file mode 100644 index 00000000000..6f816e07bb7 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/reshapre_permute_reshape.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +#include +#include "subgraph_tests/reshape_permute_reshape.hpp" +#include "common_test_utils/test_constants.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + std::vector>> inputs{ + {{1, 4 , 160}, {0, 2, 1}}, + {{8, 16}, {1, 0}}, + {{1, 1, 4, 16}, {3, 1, 2, 0}}, + {{1, 8, 200}, {0, 2, 1}}, + {{1, 8, 16}, {2, 1, 0}}, + }; + + std::vector netPrecisions = {InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16, + }; + + INSTANTIATE_TEST_CASE_P(reshape_permute_reshape, ReshapePermuteReshape, + ::testing::Combine( + ::testing::ValuesIn(inputs), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_GNA)), + ReshapePermuteReshape::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/reshape_permute_reshape.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/reshape_permute_reshape.hpp new file mode 100644 index 00000000000..eb45329fdb4 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/reshape_permute_reshape.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include +#include + +#include "functional_test_utils/layer_test_utils.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" +#include "ngraph_functions/builders.hpp" + +namespace LayerTestsDefinitions { +typedef std::tuple< + std::vector>, //input shapes and permute shapes + InferenceEngine::Precision, //Network precision + std::string //Device name + > ReshapePermuteReshapeTuple; + +class ReshapePermuteReshape : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/reshape_permute_reshape.cpp b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/reshape_permute_reshape.cpp new file mode 100644 index 00000000000..3deb52f69fa --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/reshape_permute_reshape.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#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/reshape_permute_reshape.hpp" + +namespace LayerTestsDefinitions { + std::string ReshapePermuteReshape::getTestCaseName(const testing::TestParamInfo &obj) { + std::vector> input; + InferenceEngine::Precision netPrecision; + std::string targetName; + std::tie(input, netPrecision, targetName) = obj.param; + std::ostringstream results; + + results << "IS=" << CommonTestUtils::vec2str(input[0]) << "_"; + results << "netPRC=" << netPrecision.name() << "_"; + results << "targetDevice=" << targetName << "_"; + return results.str(); + } + + void ReshapePermuteReshape::SetUp() { + std::vector> inputs; + InferenceEngine::Precision netPrecision; + std::tie(inputs, netPrecision, targetDevice) = this->GetParam(); + const std::size_t input_dim = InferenceEngine::details::product(inputs[0]); + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + std::vector shape_input{1, input_dim}; + auto input = ngraph::builder::makeParams(ngPrc, {shape_input}); + auto reshape1_pattern = std::make_shared(ngraph::element::i64, + ngraph::Shape{inputs[0].size()}, + inputs[0]); + auto reshape1 = std::make_shared(input[0], reshape1_pattern, false); + auto permute_params = std::make_shared(ngraph::element::i64, + ngraph::Shape{inputs[1].size()}, + inputs[1]); + auto permute = std::make_shared(reshape1, permute_params); + auto reshape2_pattern = std::make_shared(ngraph::element::i64, + ngraph::Shape{2}, + std::vector{1, input_dim}); + auto reshape2 = std::make_shared(permute, reshape2_pattern, false); + function = std::make_shared(reshape2, input, "reshape_permute_reshape"); + } + + TEST_P(ReshapePermuteReshape, CompareWithRefs){ + Run(); + if (targetDevice == std::string{CommonTestUtils::DEVICE_GPU}) { + PluginCache::get().reset(); + } }; +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/unit/gna/gna_permute_sequence_test.cpp b/inference-engine/tests/unit/gna/gna_permute_sequence_test.cpp new file mode 100644 index 00000000000..9ceec6cbaf7 --- /dev/null +++ b/inference-engine/tests/unit/gna/gna_permute_sequence_test.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2018-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +using namespace GNAPluginNS; + +class PermuteSequenceTest : public ::testing::Test { +}; + +TEST_F(PermuteSequenceTest, testImpossiblePermute_neg_value) { + ASSERT_ANY_THROW(genPermutations({-1})); +} + +TEST_F(PermuteSequenceTest, testImpossiblePermute_big_value) { + ASSERT_ANY_THROW(genPermutations({1})); +} + +TEST_F(PermuteSequenceTest, testImpossiblePermute_big_value_2) { + ASSERT_ANY_THROW(genPermutations({0, 2})); +} + +TEST_F(PermuteSequenceTest, testImpossiblePermute_same_value) { + ASSERT_ANY_THROW(genPermutations({0, 1, 0})); +} + +TEST_F(PermuteSequenceTest, testIdentity1d) { + ASSERT_EQ(0, genPermutations({0}).size()); +} + +TEST_F(PermuteSequenceTest, testIdentity2d) { + ASSERT_EQ(0, genPermutations({0, 1}).size()); +} + +TEST_F(PermuteSequenceTest, testIdentity3d) { + ASSERT_EQ(0, genPermutations({0, 1, 2}).size()); +} + +TEST_F(PermuteSequenceTest, testIdentity4d) { + ASSERT_EQ(0, genPermutations({0, 1, 2, 3}).size()); +} + +TEST_F(PermuteSequenceTest, test2d) { + ASSERT_EQ(1, genPermutations({1, 0}).size()); + ASSERT_EQ(std::make_pair(0, 1), genPermutations({1, 0}).front()); +} + +TEST_F(PermuteSequenceTest, test3d_1_Permutation) { + ASSERT_EQ(1, genPermutations({1, 0, 2}).size()); + ASSERT_EQ(std::make_pair(0, 1), genPermutations({1, 0, 2})[0]); +} + +TEST_F(PermuteSequenceTest, test3d_1_Permutation_2) { + ASSERT_EQ(1, genPermutations({2, 1, 0}).size()); + ASSERT_EQ(std::make_pair(0, 2), genPermutations({2, 1, 0})[0]); +} + +TEST_F(PermuteSequenceTest, test3d_2_Permutations) { + ASSERT_EQ(2, genPermutations({2, 0, 1}).size()); + ASSERT_EQ(std::make_pair(0, 2), genPermutations({2, 0, 1})[0]); + ASSERT_EQ(std::make_pair(2, 1), genPermutations({2, 0, 1})[1]); +} + +TEST_F(PermuteSequenceTest, test3d_4_Permutation) { + auto permutation = {2, 1, 4, 5, 6, 3, 0, 7}; + ASSERT_EQ(4, genPermutations(permutation).size()); + ASSERT_EQ(std::make_pair(0, 2), genPermutations(permutation)[0]); + ASSERT_EQ(std::make_pair(2, 4), genPermutations(permutation)[1]); + ASSERT_EQ(std::make_pair(4, 6), genPermutations(permutation)[2]); + ASSERT_EQ(std::make_pair(3, 5), genPermutations(permutation)[3]); +} diff --git a/inference-engine/tests_deprecated/unit/engines/gna/layers/gna_permute_test.cpp b/inference-engine/tests_deprecated/unit/engines/gna/layers/gna_permute_test.cpp index 94781af34da..8a560bada07 100644 --- a/inference-engine/tests_deprecated/unit/engines/gna/layers/gna_permute_test.cpp +++ b/inference-engine/tests_deprecated/unit/engines/gna/layers/gna_permute_test.cpp @@ -64,9 +64,9 @@ const Permute3dimTestParam gna_permute3d_test_params[] = { {{{1, 0, 2}, {8, 1, 1}}, true}, {{{1, 0, 2}, {4, 2, 1}}, false}, {{{1, 0, 2}, {2, 4, 1}}, false}, - {{{1, 2, 0}, {1, 2, 4}}, false}, - {{{0, 1, 2}, {1, 2, 4}}, false}, - {{{0, 2, 1}, {2, 1, 4}}, false}, + {{{1, 2, 0}, {1, 2, 4}}, true}, + {{{0, 1, 2}, {1, 2, 4}}, true}, + {{{0, 2, 1}, {2, 1, 4}}, true}, {{{2, 0, 1}, {1, 2, 4}}, false}, {{{2, 1, 0}, {2, 1, 4}}, false} };