From 1220fb2fe898d944ab5bc7f63fd76a5a31d80ee1 Mon Sep 17 00:00:00 2001 From: Anna Alberska Date: Mon, 9 Nov 2020 14:40:31 +0100 Subject: [PATCH] [GNA] Add support for SubstituteSoftSign for pattern with addition (#2789) * [GNA] add changes for SubstituteSoftSign for IRv10 * cpplint fix * [GNA] add requested changes & change SoftSign test validation * [GNA] SubstituteSoftsign refactor * [GNA] enable 3d input tests for softsign --- .../gna_plugin/optimizer/gna_pass_manager.cpp | 44 +++++++-- .../subgraph_tests/softsign.cpp | 43 +++++++++ .../include/subgraph_tests/softsign.hpp | 39 ++++++++ .../shared/src/subgraph_tests/softsign.cpp | 91 +++++++++++++++++++ 4 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/softsign.cpp create mode 100644 inference-engine/tests/functional/plugin/shared/include/subgraph_tests/softsign.hpp create mode 100644 inference-engine/tests/functional/plugin/shared/src/subgraph_tests/softsign.cpp 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 4823f4a29b5..0825a526d72 100644 --- a/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp +++ b/inference-engine/src/gna_plugin/optimizer/gna_pass_manager.cpp @@ -291,6 +291,21 @@ void ReorderMaxPoolPass::run() { } void SubstituteSoftSignPass::run() { + //detecting following pattern + // irv7 model: irv10 model: + // a layer a layer + // | \ | \ + // abs \ abs \ + // | | | | + // | | add | + // | | | | + // power | power | + // \ / \ / + // mul mul + auto fp32eq = [](float p1, float p2) { + return (std::abs(p1 - p2) <= 0.00001f * std::min(std::abs(p1), std::abs(p2))); + }; + auto hasNChildren = [](CNNLayerPtr l, int N){ if (l->outData.size() != 1) return false; if (getInputTo(l->outData.front()).size() != N) return false; @@ -319,13 +334,24 @@ void SubstituteSoftSignPass::run() { } if (cont) continue; if (!hasNChildren(abs, 1)) continue; - auto power = getNthChild(abs, 0); + auto addition = getNthChild(abs, 0); + InferenceEngine::CNNLayerPtr power = nullptr; - if (!LayerInfo(power).isPower()) continue; - auto powerLayer = LayerInfo(power).as(); - if (powerLayer->power != -1) continue; - if (powerLayer->offset != 1) continue; - if (powerLayer->scale != 1) continue; + if (!LayerInfo(addition).isPower()) continue; + auto powerLayer = LayerInfo(addition).as(); + + // first layer after abs must have scale of 1, offset of 1 and power of either 1 or -1 + if (!fp32eq(powerLayer->scale, 1.0f) || !fp32eq(powerLayer->offset, 1.0f) || !fp32eq(std::abs(powerLayer->power), 1.0f)) continue; + // power == -1, offset = 1, scale = 1 + if (fp32eq(powerLayer->power, -1.0f)) { + std::swap(addition, power); + } else { // power = 1, offset = 1, scale - 1 + power = getNthChild(addition, 0); + if (!LayerInfo(power).isPower()) continue; + auto powerLayer_1 = LayerInfo(power).as(); + // layer after addition must have power of -1, offset of 0 and scale of 1 + if (!fp32eq(powerLayer_1->power, -1.0f) || !fp32eq(powerLayer_1->offset, 0.0f) || !fp32eq(powerLayer_1->scale, 1.0f)) continue; + } if (!hasNChildren(power, 1)) continue; auto mulSame = getNthChild(power, 0); @@ -333,9 +359,9 @@ void SubstituteSoftSignPass::run() { // pattern matched - lets substitute gnalog() << "SoftSign subgraph found consits of: \n" - << "\t" << abs->name << "\n" - << "\t" << power->name << "\n" - << "\t" << mul->name << "\n" + << "\t" << abs->name << "\n"; + if (addition == nullptr) gnalog() << "\t" << addition->name << "\n"; + gnalog() << "\t" << mul->name << "\n" << std::endl; // creating softsign layer diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/softsign.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/softsign.cpp new file mode 100644 index 00000000000..8bc43c55fe3 --- /dev/null +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/softsign.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "common_test_utils/test_constants.hpp" +#include "subgraph_tests/softsign.hpp" + +using namespace LayerTestsDefinitions; + +namespace { +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::FP16 +}; + +const std::vector> configs = { + { + {"GNA_DEVICE_MODE", "GNA_SW_EXACT"}, + {"GNA_SCALE_FACTOR_0", "3276.7"}, + {"GNA_COMPACT_MODE", "NO"} + } +}; + +std::vector> input_shapes = { + {1, 8}, + {1, 42}, + {1, 100}, + {1, 128}, + {1, 1, 64}, + {1, 1, 1, 64}, + {1, 1, 1, 100} +}; + +INSTANTIATE_TEST_CASE_P(smoke_Softsign, SoftsignTest, + ::testing::Combine( + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_GNA), + ::testing::ValuesIn(configs), + ::testing::ValuesIn(input_shapes)), + SoftsignTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/softsign.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/softsign.hpp new file mode 100644 index 00000000000..0911c795b45 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/softsign.hpp @@ -0,0 +1,39 @@ +// 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/builders.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" + +typedef std::tuple< + InferenceEngine::Precision, // Network Precision + std::string, // Target Device + std::map, // Configuration + std::vector // Input Shapes +> softsignParams; + +namespace LayerTestsDefinitions { + +class SoftsignTest : public testing::WithParamInterface, + public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + + void Run() override; + +protected: + void SetUp() override; + +private: + std::shared_ptr GenerateNgraphFriendlySoftSign(); +}; + +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/softsign.cpp b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/softsign.cpp new file mode 100644 index 00000000000..0a223272e8b --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/softsign.cpp @@ -0,0 +1,91 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/common_utils.hpp" +#include "functional_test_utils/blob_utils.hpp" +#include "functional_test_utils/layer_test_utils.hpp" +#include "functional_test_utils/plugin_cache.hpp" +#include "ngraph_functions/pass/convert_prc.hpp" +#include +#include "subgraph_tests/softsign.hpp" + +#include "ngraph_functions/builders.hpp" + +namespace LayerTestsDefinitions { + +std::string SoftsignTest::getTestCaseName(testing::TestParamInfo obj) { + InferenceEngine::Precision netPrecision; + std::vector inputShape; + std::string targetDevice; + std::map configuration; + std::tie(netPrecision, targetDevice, configuration, inputShape) = obj.param; + + std::ostringstream result; + result << "IS=" << CommonTestUtils::vec2str(inputShape) << "_"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "targetDevice=" << targetDevice; + for (auto const& configItem : configuration) { + result << "_configItem=" << configItem.first << "_" << configItem.second; + } + return result.str(); +} + +void SoftsignTest::SetUp() { + InferenceEngine::Precision netPrecision; + std::map tempConfig; + std::vector inputShape; + std::tie(netPrecision, targetDevice, tempConfig, inputShape) = this->GetParam(); + configuration.insert(tempConfig.begin(), tempConfig.end()); + + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + + auto params = ngraph::builder::makeParams(ngPrc, { inputShape }); + + auto abs = std::make_shared(params[0]); + auto add = std::make_shared(abs, 1, 1, 1); + auto power = std::make_shared(add, -1, 1, 0); + auto mul = std::make_shared(power, params[0]); + ngraph::ResultVector results{ std::make_shared(mul) }; + function = std::make_shared(results, params, "SoftSignTest"); +} + +void SoftsignTest::Run() { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + + LoadNetwork(); + Infer(); + + function = GenerateNgraphFriendlySoftSign(); + Validate(); +} + +std::shared_ptr SoftsignTest::GenerateNgraphFriendlySoftSign() { + InferenceEngine::Precision netPrecision = std::get<0>(this->GetParam()); + std::vector inputShape = std::get<3>(this->GetParam()); + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + + auto params = ngraph::builder::makeParams(ngPrc, { inputShape }); + auto abs = std::make_shared(params[0]); + auto constant_0 = ngraph::builder::makeConstant(ngPrc, inputShape, { 1 }); + auto add = std::make_shared(abs, constant_0); + auto constant_1 = ngraph::builder::makeConstant(ngPrc, inputShape, { -1 }); + auto power = std::make_shared(add, constant_1); + auto mul = std::make_shared(power, params[0]); + + ngraph::ResultVector results{ std::make_shared(mul) }; + return std::make_shared(results, params, "SoftSignTest"); +} + +TEST_P(SoftsignTest, CompareWithRefImpl) { + Run(); +}; + +} // namespace LayerTestsDefinitions