From 8c6c46425b1a3dbaebfe8d397652a55b32648ced Mon Sep 17 00:00:00 2001 From: Marcin Kacprzak Date: Mon, 29 May 2023 13:00:13 +0200 Subject: [PATCH] [GNA] Fix for unsupported concat on axis 0 (#17558) --- .../intel_gna/src/backend/gna_limitations.cpp | 2 + .../pass_tests/concat_restrictions.cpp | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/src/plugins/intel_gna/src/backend/gna_limitations.cpp b/src/plugins/intel_gna/src/backend/gna_limitations.cpp index ab4cad4faa5..a1d86060aab 100644 --- a/src/plugins/intel_gna/src/backend/gna_limitations.cpp +++ b/src/plugins/intel_gna/src/backend/gna_limitations.cpp @@ -1009,6 +1009,8 @@ bool Limitations::validate_concat_axis(const InferenceEngine::CNNLayerPtr layer, if (LayerInfo(pre_prev_layer).isConst()) { continue; + } else if (LayerInfo(pre_prev_layer).isPermute()) { + continue; } concat_all_const_or_inputs = false; diff --git a/src/plugins/intel_gna/tests/functional/pass_tests/concat_restrictions.cpp b/src/plugins/intel_gna/tests/functional/pass_tests/concat_restrictions.cpp index de5576c7252..cc9062fb0b2 100644 --- a/src/plugins/intel_gna/tests/functional/pass_tests/concat_restrictions.cpp +++ b/src/plugins/intel_gna/tests/functional/pass_tests/concat_restrictions.cpp @@ -13,6 +13,7 @@ #include "ngraph_functions/builders.hpp" #include "ngraph_functions/pass/convert_prc.hpp" #include "ngraph_functions/utils/ngraph_helpers.hpp" +#include "openvino/opsets/opset11.hpp" #include "shared_test_classes/base/layer_test_utils.hpp" /* ============= Concat Layer Restrictions Tests ============= */ @@ -25,6 +26,26 @@ using ConcatRestrictionsParamsTuple = typename std::tuple create_fq_node(const Type& type, + const shared_ptr& node, + float fqMin, + float fqMax, + size_t levels) { + auto fqInpMin = makeConstant(type, {1}, {fqMin}); + auto fqInpMax = makeConstant(type, {1}, {fqMax}); + auto fqOutMin = makeConstant(type, {1}, {fqMin}); + auto fqOutMax = makeConstant(type, {1}, {fqMax}); + return make_shared(node, fqInpMin, fqInpMax, fqOutMin, fqOutMax, levels); +} + struct ReLUConcatAxis { static const char* getName() { return "ReLUConcatAxis"; @@ -320,6 +341,103 @@ struct ConvConcatConcatNHWCAxis { } }; +// This test performs checks on the following network: +// Param1 +// | +// Reshape Param2 +// | | +// Convolution FQ +// | | +// ReLU Reshape +// | | +// FQ Transpose +// | | +// Reshape Reshape +// | | +// Transpose Transpose +// \ / +// Concat +// | +// Reshape +// | +// Result +// +// We want to ensure this Concat topology will not be detected as unsupported one. + +struct TransposeTransposeConcat { + static const char* getName() { + return "TransposeTransposeConcat"; + } + + static std::shared_ptr createTopology(const SizeVector& input_shapes, + const unsigned int& axis, + const Precision& net_precision) { + const float fq1 = 5.5, fq2 = 10.0; + const size_t levels = 65536; + const vector invert = {1, 0}; + const vector kernel_shape = {1, 3}; + const size_t input_channels = 8; + const size_t output_channels = 64; + + IE_ASSERT(input_shapes[0] % input_channels == 0); + IE_ASSERT(input_shapes[1] % input_shapes[0] == 0); + + vector concat_input_shape = {input_shapes[1] / input_shapes[0], input_shapes[0]}; + vector conv_input_shape = {1, input_channels, 1, input_shapes[0] / input_channels}; + + auto ng_prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(net_precision); + auto inputs = makeParams(ng_prc, {{1, input_shapes[0]}, {1, input_shapes[1]}}); + + // 1st concat input + auto reshape_l1_const = make_shared(i64, Shape{conv_input_shape.size()}, conv_input_shape); + auto reshape_l1 = make_shared(inputs[0], reshape_l1_const, false); + + auto conv_l1_weights = makeConstant(ng_prc, + {output_channels, input_channels, kernel_shape[0], kernel_shape[1]}, + {}, + true, + 1.0f, + -1.0f); + auto conv_l1_weights_fq = create_fq_node(ng_prc, conv_l1_weights, -fq1, fq1, levels); + auto conv_l1 = make_shared(reshape_l1, + conv_l1_weights_fq, + vector{1, 1}, + vector{0, 0}, + vector{0, 0}, + vector{1, 1}, + ov::op::PadType::VALID); + auto relu_l1 = make_shared(conv_l1); + auto fq_l1 = create_fq_node(ng_prc, relu_l1, -fq1, fq1, levels); + auto reshape_l2_const = make_shared(i64, Shape{concat_input_shape.size()}, concat_input_shape); + auto reshape_l2 = make_shared(fq_l1, reshape_l2_const, false); + auto transpose_l1_const = Constant::create(i64, Shape{invert.size()}, invert); + auto transpose_l1 = make_shared(reshape_l2, transpose_l1_const); + + // 2nd concat input + auto fq_r1 = create_fq_node(ng_prc, inputs[1], -fq2, fq2, levels); + auto reshape_r1_const = make_shared(i64, Shape{2}, concat_input_shape); + auto reshape_r1 = make_shared(fq_r1, reshape_r1_const, false); + auto transpose_r1_const = Constant::create(i64, Shape{invert.size()}, invert); + auto transpose_r1 = make_shared(reshape_r1, transpose_r1_const); + auto reshape_r3_const = make_shared(i64, Shape{concat_input_shape.size()}, concat_input_shape); + auto reshape_r3 = make_shared(transpose_r1, reshape_r3_const, false); + auto transpose_r2_const = Constant::create(i64, Shape{invert.size()}, invert); + auto transpose_r2 = make_shared(reshape_r3, transpose_r2_const); + + // Concat + auto concat = makeConcat({transpose_l1, transpose_r2}, 0); + + auto width_after_conv = (conv_input_shape[3] - kernel_shape[1]) + 1; + auto reshape_const = + make_shared(i64, Shape{2}, vector{1, 2 * output_channels * width_after_conv}); + auto reshape = make_shared(concat, reshape_const, false); + + ResultVector result{make_shared(reshape)}; + auto model = make_shared(result, inputs, getName()); + return model; + } +}; + template class ConcatRestrictions : public testing::WithParamInterface, public LayerTestsUtils::LayerTestsCommon { @@ -346,6 +464,18 @@ public: return T::getMatch(); } + Blob::Ptr GenerateInput(const InferenceEngine::InputInfo& info) const override { + InferenceEngine::Blob::Ptr blob = make_blob_with_precision(info.getTensorDesc()); + blob->allocate(); + + auto* rawBlobDataPtr = blob->buffer().as(); + vector values = generate_float_numbers(blob->size(), -0.2f, 0.2f); + for (size_t i = 0; i < blob->size(); i++) { + rawBlobDataPtr[i] = values[i]; + } + return blob; + } + protected: void SetUp() override { InferenceEngine::SizeVector inputShape; @@ -368,6 +498,7 @@ using ConvConcatNHWCRestrictionsNeg = ConcatRestrictions; using ConvConcatNHWCRestrictionsPos = ConcatRestrictions; using ConvConcatConcatNHWCRestrictionsNeg = ConcatRestrictions; using ConvConcatConcatNHWCRestrictionsPos = ConcatRestrictions; +using TransposeTransposeConcatPos = ConcatRestrictions; TEST_P(ReLUConcatRestrictionsNeg, CompareWithRefImpl) { ExpectLoadNetworkToThrow(getMatch()); @@ -419,6 +550,10 @@ TEST_P(ConvConcatConcatNHWCRestrictionsPos, CompareWithRefImpl) { Run(); }; +TEST_P(TransposeTransposeConcatPos, CompareWithRefImpl) { + Run(); +}; + const std::vector netPrecisions = {InferenceEngine::Precision::FP32}; const std::vector> configs = {{{"GNA_DEVICE_MODE", "GNA_SW_FP32"}}}; @@ -631,4 +766,23 @@ INSTANTIATE_TEST_SUITE_P(smoke_concat_restrictions, ::testing::ValuesIn(configs), ::testing::Values(CommonTestUtils::DEVICE_GNA)), ConvConcatConcatNHWCRestrictionsPos::getTestCaseName); + +const vector ttc_input_shapes = {{64, 384}}; +const vector> ttc_configs = { + {{"GNA_DEVICE_MODE", "GNA_SW_FP32"}}, + {{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, {"GNA_EXEC_TARGET", "GNA_TARGET_2_0"}}, + {{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, {"GNA_EXEC_TARGET", "GNA_TARGET_3_0"}}, + {{"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, {"GNA_EXEC_TARGET", "GNA_TARGET_3_5"}}, +}; +const vector ttc_axis = {0}; + +INSTANTIATE_TEST_SUITE_P(smoke_concat_restrictions, + TransposeTransposeConcatPos, + ::testing::Combine(::testing::ValuesIn(ttc_input_shapes), + ::testing::ValuesIn(ttc_axis), + ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(ttc_configs), + ::testing::Values(CommonTestUtils::DEVICE_GNA)), + TransposeTransposeConcatPos::getTestCaseName); + } // namespace ConcatTestsDefinitions