From dbb72f8d50d43a45311531bf1bf5a3e144d532e3 Mon Sep 17 00:00:00 2001 From: Nikita Demashov Date: Mon, 19 Jul 2021 18:37:48 +0300 Subject: [PATCH 1/4] add move_fake_quantize_for_concat_transformation, mfk and mfk_function --- .../low_precision/move_fake_quatize.hpp | 26 ++ .../src/move_fake_quantize.cpp | 61 ++++ ...ake_quantize_for_concat_transformation.cpp | 262 ++++++++++++++++++ .../move_fake_quantize_function.hpp | 41 +++ .../src/move_fake_quantize_function.cpp | 114 ++++++++ 5 files changed, 504 insertions(+) create mode 100644 inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp create mode 100644 inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp create mode 100644 inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp create mode 100644 inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp create mode 100644 inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp new file mode 100644 index 00000000000000..a2ba2767ef7a4f --- /dev/null +++ b/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include "low_precision/layer_transformation.hpp" + +namespace ngraph { +namespace pass { +namespace low_precision { + +class TRANSFORMATIONS_API MoveFakeQuantize : public LayerTransformation { +public: + MaxPoolTransformation(const Params& params); + void registerMatcherIn(GraphRewrite& pass, TransformationContext& context) const override; + bool canBeTransformed(const TransformationContext& context, std::shared_ptr op) const override; + bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) const override; + bool isPrecisionPreserved(std::shared_ptr layer) const noexcept override; +}; + +} // namespace low_precision +} // namespace pass +} // namespace ngraph diff --git a/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp new file mode 100644 index 00000000000000..a2289eae30ee5e --- /dev/null +++ b/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "low_precision/max_pool.hpp" + +#include +#include +#include + +#include "low_precision/network_helper.hpp" + +namespace ngraph { +namespace pass { +namespace low_precision { + +MaxPoolTransformation::MaxPoolTransformation(const Params& params) : LayerTransformation(params) { +} + +void MaxPoolTransformation::registerMatcherIn(GraphRewrite &pass, TransformationContext &context) const { + addPattern( + pass, + context, + make_op_pattern({ make_op_label() })); +} + +bool MaxPoolTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr op) const { + if (!LayerTransformation::canBeTransformed(context, op)) { + return false; + } + + const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op); + if (dequantization.empty()) { + return false; + } + + const std::vector scales = as_type_ptr(dequantization.multiply->get_input_node_shared_ptr(1))->cast_vector(); + if (std::any_of(scales.begin(), scales.end(), [](const float value) { return value < 0.0; })) { + return false; + } + + return true; +} + +bool MaxPoolTransformation::transform(TransformationContext& context, ngraph::pattern::Matcher &m) const { + if (!canBeTransformed(context, m.get_match_root())) { + return false; + } + + const std::shared_ptr pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root()); + moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling), false); + return true; +} + +bool MaxPoolTransformation::isPrecisionPreserved(std::shared_ptr layer) const noexcept { + return true; +} + +} // namespace low_precision +} // namespace pass +} // namespace ngraph diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp new file mode 100644 index 00000000000000..9bf23897efa2e9 --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp @@ -0,0 +1,262 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "layer_transformation.hpp" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include "lpt_ngraph_functions/move_fake_quantize_function.hpp" +#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp" +#include "lpt_ngraph_functions/relu_function.hpp" +#include "simple_low_precision_transformer.hpp" +//nd/lpt/move_fake_quantize +using namespace testing; +using namespace ngraph; +using namespace ngraph::pass; + +namespace { + +class MoveFakeQuantizeActualValues { +public: + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize1; + ngraph::builder::subgraph::DequantizationOperations::Convert convert1; + ngraph::builder::subgraph::DequantizationOperations dequantization1; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize2; + ngraph::builder::subgraph::DequantizationOperations::Convert convert2; + ngraph::builder::subgraph::DequantizationOperations dequantization2; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize3; + ngraph::builder::subgraph::DequantizationOperations::Convert convert3; + ngraph::builder::subgraph::DequantizationOperations dequantization3; +}; + +inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeActualValues& values) { + return out << "_" << + values.fakeQuantize1 << "_" << + values.convert1.outPrecision << "_" << + values.dequantization1 << "_" << + values.fakeQuantize2 << "_" << + values.convert2.outPrecision << "_" << + values.dequantization2; +} + +class MoveFakeQuantizeResultValues { +public: + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize1; + ngraph::builder::subgraph::DequantizationOperations::Convert convert1; + ngraph::builder::subgraph::DequantizationOperations dequantization1; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize2; + ngraph::builder::subgraph::DequantizationOperations::Convert convert2; + ngraph::builder::subgraph::DequantizationOperations dequantization2; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize3; + ngraph::builder::subgraph::DequantizationOperations::Convert convert3; + ngraph::builder::subgraph::DequantizationOperations dequantization3; + ngraph::element::Type precisionAfterOperation; + ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; +}; + +inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeResultValues& values) { + return out << "_" << + values.fakeQuantize1 << "_" << + values.convert1.outPrecision << "_" << + values.dequantization1 << "_" << + values.fakeQuantize2 << "_" << + values.convert2.outPrecision << "_" << + values.dequantization2 << "_" << + values.dequantizationAfter; +} + +class MoveFakeQuantizeTestValues { +public: + ngraph::pass::low_precision::LayerTransformation::Params params; + bool multiChannels; + std::int64_t axis; + MoveFakeQuantizeActualValues actual; + MoveFakeQuantizeResultValues result; +}; + +inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeTestValues& values) { + return out << "_" << values.multiChannels << "_" << values.actual << "_" << values.result; +} + +typedef std::tuple < + ngraph::element::Type, + ngraph::PartialShape, + MoveFakeQuantizeTestValues +> MoveFakeQuantizeParams; + +class MoveFakeQuantize : public LayerTransformation, public testing::WithParamInterface { +public: + void SetUp() override { + const ngraph::element::Type precision = std::get<0>(GetParam()); + const ngraph::PartialShape shape = std::get<1>(GetParam()); + MoveFakeQuantizeTestValues testValues = std::get<2>(GetParam()); + + // dequantization output precision depends on input precision + // to avoid huge amount of tests cases let's define dequantization output precision as input precision + if (!testValues.actual.dequantization1.multiply.empty()) { + testValues.actual.dequantization1.multiply.outPrecision = precision; + } + if (!testValues.actual.dequantization2.multiply.empty()) { + testValues.actual.dequantization2.multiply.outPrecision = precision; + } + actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.actual.fakeQuantize1, + testValues.actual.convert1, + testValues.actual.dequantization1, + testValues.actual.fakeQuantize2, + testValues.actual.convert2, + testValues.actual.dequantization2, + testValues.actual.fakeQuantize3, + testValues.actual.convert3, + testValues.actual.dequantization3, + ngraph::element::undefined, + {}, + testValues.axis); + /* + actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.actual.fakeQuantize1, + testValues.actual.fakeQuantize2, + testValues.actual.fakeQuantize3, + testValues.axis); + */ + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.actual").run_on_function(actualFunction); + + SimpleLowPrecisionTransformer transform; + transform.add(testValues.params); + transform.transform(actualFunction); + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.transform").run_on_function(actualFunction); + + // dequantization output precision depends on input precision + // to avoid huge amount of tests cases let's define dequantization output precision as input precision + if (!testValues.result.dequantizationAfter.multiply.empty()) { + testValues.result.dequantizationAfter.multiply.outPrecision = precision; + } + + if (!testValues.params.updatePrecisions && + (precision == ngraph::element::f32) && + !testValues.result.dequantizationAfter.convert.empty()) { + testValues.result.dequantizationAfter.convert = {}; + } + referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.actual.fakeQuantize1, + testValues.actual.convert1, + testValues.actual.dequantization1, + testValues.actual.fakeQuantize2, + testValues.actual.convert2, + testValues.actual.dequantization2, + testValues.actual.fakeQuantize3, + testValues.actual.convert3, + testValues.actual.dequantization3, + testValues.result.precisionAfterOperation, + testValues.result.dequantizationAfter, + testValues.axis); + /* + referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.actual.fakeQuantize1, + testValues.actual.fakeQuantize2, + testValues.actual.fakeQuantize3, + testValues.axis); + */ + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.reference").run_on_function(referenceFunction); + } + + static std::string getTestCaseName(testing::TestParamInfo obj) { + const ngraph::element::Type precision = std::get<0>(obj.param); + const ngraph::PartialShape shape = std::get<1>(obj.param); + const MoveFakeQuantizeTestValues testValues = std::get<2>(obj.param); + + std::ostringstream result; + result << + LayerTransformation::getTestCaseNameByParams(precision, shape, testValues.params) << "_" << + (testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") << + "axis_" << testValues.axis << "_" << + testValues.actual << "_" << + testValues.result << "_"; + return result.str(); + } +}; + +TEST_P(MoveFakeQuantize, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, referenceFunction, true, true, true); + ASSERT_TRUE(res.first) << res.second; +} + +const std::vector precisions = { + ngraph::element::f32, + //ngraph::element::f16 +}; + +namespace testValues1 { +const std::vector shapes = { + { 1, 3, 9, 9 }, + //{ 4, 3, 9, 9 }, + //{ Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() } +}; + +const std::vector testValues = { + // U8: concat + { + LayerTransformation::createParamsU8I8(), + false, + 1, + { + {}, + {}, + {}, + {}, + {}, + {}, + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} }, + { ngraph::element::u8 }, + { + { element::f32 }, + {}, + { 0.01f } + }, + }, + { + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} }, + {}, + {}, + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} }, + {}, + {}, + {}, + {}, + {}, + ngraph::element::undefined, + {}, + } + }, +}; +INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + MoveFakeQuantize, + ::testing::Combine( + ::testing::ValuesIn(precisions), + ::testing::ValuesIn(shapes), + ::testing::ValuesIn(testValues)), + MoveFakeQuantize::getTestCaseName); +} // namespace testValues1 +} // namespace diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp new file mode 100644 index 00000000000000..efe2e5b429f5de --- /dev/null +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include "low_precision/layer_transformation.hpp" +#include "common/fake_quantize_on_data.hpp" +#include "common/dequantization_operations.hpp" + +namespace ngraph { +namespace builder { +namespace subgraph { + +class MoveFakeQuantize { +public: + static std::shared_ptr get( + const ngraph::element::Type inputPrecision, + const ngraph::PartialShape& inputShape, + const FakeQuantizeOnDataWithConstant& fakeQuantize1, + const DequantizationOperations::Convert& convert1, + const DequantizationOperations& dequantization1, + const FakeQuantizeOnDataWithConstant& fakeQuantize2, + const DequantizationOperations::Convert& convert2, + const DequantizationOperations& dequantization2, + const FakeQuantizeOnDataWithConstant& fakeQuantize3, + const DequantizationOperations::Convert& convert3, + const DequantizationOperations& dequantization3, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const std::int64_t& axis); +private: + static std::shared_ptr makeMaxPool(const Output& parent, const std::vector& kernel); +}; + +} // namespace subgraph +} // namespace builder +} // namespace ngraph diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp new file mode 100644 index 00000000000000..5ae934202125e7 --- /dev/null +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "lpt_ngraph_functions/move_fake_quantize_function.hpp" + +#include +#include "ngraph_ops/type_relaxed.hpp" +#include "low_precision/network_helper.hpp" + +#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp" +#include "lpt_ngraph_functions/common/dequantization_operations.hpp" +#include "lpt_ngraph_functions/common/builders.hpp" + +namespace ngraph { +namespace builder { +namespace subgraph { + +using namespace ngraph::pass; + +std::shared_ptr MoveFakeQuantize::get( + const ngraph::element::Type inputPrecision, + const ngraph::PartialShape& inputShape, + const FakeQuantizeOnDataWithConstant& fqOnData1, + const DequantizationOperations::Convert& convert1, + const DequantizationOperations& dequantization1, + const FakeQuantizeOnDataWithConstant& fqOnData2, + const DequantizationOperations::Convert& convert2, + const DequantizationOperations& dequantization2, + const FakeQuantizeOnDataWithConstant& fqOnData3, + const DequantizationOperations::Convert& convert3, + const DequantizationOperations& dequantization3, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const std::int64_t& axis) { + + const auto input1 = std::make_shared(inputPrecision, inputShape); + input1->set_friendly_name("input1"); + + const auto input2 = std::make_shared(inputPrecision, inputShape); + input2->set_friendly_name("input2"); + + if (fqOnData3.empty()) { + std::shared_ptr parent1 = makeFakeQuantizeTypeRelaxed(input1, inputPrecision, fqOnData1); + if (!convert1.empty()) { + parent1 = std::make_shared(parent1, convert1.outPrecision); + } + if (!dequantization1.empty()) { + parent1 = makeDequantization(parent1, dequantization1); + } + + std::shared_ptr parent2 = makeFakeQuantizeTypeRelaxed(input2, inputPrecision, fqOnData2); + if (!convert2.empty()) { + parent2 = std::make_shared(parent2, convert2.outPrecision); + } + if (!dequantization2.empty()) { + parent2 = makeDequantization(parent2, dequantization2); + } + + const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ parent1, parent2 }, axis); + + auto& rtInfo = concat->get_rt_info(); + rtInfo["Variant::std::string"] = std::make_shared>("concat"); + + const auto lastDequantization = makeDequantization(concat, dequantizationAfter); + lastDequantization->set_friendly_name("output"); + + ngraph::ResultVector results{ std::make_shared(lastDequantization) }; + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "MoveFakeQuantize"); + return function; + } + else { + const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ input1, input2 }, axis); + + auto& rtInfo = concat->get_rt_info(); + rtInfo["Variant::std::string"] = std::make_shared>("concat"); + + std::shared_ptr fq = makeFakeQuantizeTypeRelaxed(concat, inputPrecision, fqOnData3); + + const auto lastDequantization = makeDequantization(fq, dequantizationAfter); + lastDequantization->set_friendly_name("output"); + + ngraph::ResultVector results{ std::make_shared(lastDequantization) }; + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "MoveFakeQuantize"); + return function; + } +} + +std::shared_ptr MoveFakeQuantize::makeMaxPool(const Output& parent, const std::vector& kernel) { + const std::vector stride = { 1, 1 }; + const std::vector padBegin = { 0, 0 }; + const std::vector padEnd = { 0, 0 }; + const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET; + const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR; + const auto pooling = std::make_shared( + parent, + stride, + padBegin, + padEnd, + kernel, + roundingType, + padType); + return pooling; +} + +} // namespace subgraph +} // namespace builder +} // namespace ngraph From 133f038d36473b61c8d8a9b0c264a92f8f2a559b Mon Sep 17 00:00:00 2001 From: NikDemoShow Date: Tue, 3 Aug 2021 12:18:18 +0300 Subject: [PATCH 2/4] fix relu_transformation.cpp --- .../relu_transformation.cpp | 268 +++++++++--------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp index 50777c1e29526b..2a575d10316cde 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp @@ -41,7 +41,7 @@ class ReluTransformationTestValues { ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; }; - ngraph::pass::low_precision::LayerTransformation::Params params; + TestTransformationParams params; Actual actual; Expected expected; }; @@ -92,11 +92,11 @@ class ReluTransformation : public LayerTransformation, public testing::WithParam std::shared_ptr referenceFunction; }; -TEST_P(ReluTransformation, CompareFunctions) { - actualFunction->validate_nodes_and_infer_types(); - auto res = compare_functions(referenceFunction, actualFunction, true, true, true); - ASSERT_TRUE(res.first) << res.second; -} + TEST_P(ReluTransformation, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, actualFunction, true, true, false); + ASSERT_TRUE(res.first) << res.second; + } namespace testValues1 { const std::vector shapes = { @@ -104,134 +104,134 @@ const std::vector shapes = { { Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() }, }; -const std::vector testValues = { - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {0.1f}} - }, - { - ngraph::element::u8, - {{}, {}, {}}, - ngraph::element::u8, - {{ngraph::element::f32}, {}, {0.1f}} - } - }, - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} - }, - { - ngraph::element::u8, - {{}, {}, {}}, - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} - } - }, - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}} - }, - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: no subtract - { - LayerTransformation::createParamsI8I8(), - { - ngraph::element::i8, - {{ngraph::element::f32}, {}, {0.1f}} - }, - { - ngraph::element::i8, - {{}, {}, {}}, - ngraph::element::i8, - {{ngraph::element::f32}, {}, {0.1f}} - } - }, - // U8: with subtract value - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, { 128 }, {0.1f}} - }, - { - ngraph::element::u8, - {{ngraph::element::f32}, { 128 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: with subtract value - { - LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(true), - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}} - }, - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: with subtract value - { - LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(false), - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}} - }, - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // U8: empty - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {} - }, - { - ngraph::element::u8, - {}, - ngraph::element::u8, - {} - } - }, - // FP32: empty - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::f32, - {} - }, - { - ngraph::element::f32, - {}, - ngraph::element::f32, - {} - } - } -}; + const std::vector testValues = { + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {0.1f}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {0.1f}} + } + }, + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} + } + }, + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: no subtract + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {0.1f}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {}, {0.1f}} + } + }, + // U8: with subtract value + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, { 128 }, {0.1f}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, { 128 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: with subtract value + { + LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(true), + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: with subtract value + { + LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(false), + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // U8: empty + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {} + }, + { + ngraph::element::u8, + {}, + ngraph::element::u8, + {} + } + }, + // FP32: empty + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::f32, + {} + }, + { + ngraph::element::f32, + {}, + ngraph::element::f32, + {} + } + } + }; INSTANTIATE_TEST_SUITE_P( smoke_LPT, From 91fe70da58b1da881b1bbb8be0296555fa3456a7 Mon Sep 17 00:00:00 2001 From: NikDemoShow Date: Tue, 3 Aug 2021 12:18:18 +0300 Subject: [PATCH 3/4] backup --- .../relu_transformation.cpp | 266 +++++++++--------- 1 file changed, 133 insertions(+), 133 deletions(-) diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp index 2a575d10316cde..a567374acdffb8 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/relu_transformation.cpp @@ -92,11 +92,11 @@ class ReluTransformation : public LayerTransformation, public testing::WithParam std::shared_ptr referenceFunction; }; - TEST_P(ReluTransformation, CompareFunctions) { - actualFunction->validate_nodes_and_infer_types(); - auto res = compare_functions(referenceFunction, actualFunction, true, true, false); - ASSERT_TRUE(res.first) << res.second; - } +TEST_P(ReluTransformation, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, actualFunction, true, true, false); + ASSERT_TRUE(res.first) << res.second; +} namespace testValues1 { const std::vector shapes = { @@ -104,134 +104,134 @@ const std::vector shapes = { { Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() }, }; - const std::vector testValues = { - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {0.1f}} - }, - { - ngraph::element::u8, - {{}, {}, {}}, - ngraph::element::u8, - {{ngraph::element::f32}, {}, {0.1f}} - } - }, - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} - }, - { - ngraph::element::u8, - {{}, {}, {}}, - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} - } - }, - // U8: no subtract - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}} - }, - { - ngraph::element::u8, - {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: no subtract - { - LayerTransformation::createParamsI8I8(), - { - ngraph::element::i8, - {{ngraph::element::f32}, {}, {0.1f}} - }, - { - ngraph::element::i8, - {{}, {}, {}}, - ngraph::element::i8, - {{ngraph::element::f32}, {}, {0.1f}} - } - }, - // U8: with subtract value - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {{ngraph::element::f32}, { 128 }, {0.1f}} - }, - { - ngraph::element::u8, - {{ngraph::element::f32}, { 128 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: with subtract value - { - LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(true), - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}} - }, - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // I8: with subtract value - { - LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(false), - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}} - }, - { - ngraph::element::i8, - {{ngraph::element::f32}, { 127 }, {0.1f}}, - ngraph::element::f32, - {{}, {}, {}} - } - }, - // U8: empty - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::u8, - {} - }, - { - ngraph::element::u8, - {}, - ngraph::element::u8, - {} - } - }, - // FP32: empty - { - LayerTransformation::createParamsU8I8(), - { - ngraph::element::f32, - {} - }, - { - ngraph::element::f32, - {}, - ngraph::element::f32, - {} - } - } - }; +const std::vector testValues = { + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {0.1f}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {0.1f}} + } + }, + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} + }, + { + ngraph::element::u8, + {{}, {}, {}}, + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, 0.2f, 0.3f}}} + } + }, + // U8: no subtract + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, {}, {{0.1f, -0.2f, 0.3f}}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: no subtract + { + LayerTransformation::createParamsI8I8(), + { + ngraph::element::i8, + {{ngraph::element::f32}, {}, {0.1f}} + }, + { + ngraph::element::i8, + {{}, {}, {}}, + ngraph::element::i8, + {{ngraph::element::f32}, {}, {0.1f}} + } + }, + // U8: with subtract value + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {{ngraph::element::f32}, { 128 }, {0.1f}} + }, + { + ngraph::element::u8, + {{ngraph::element::f32}, { 128 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: with subtract value + { + LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(true), + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // I8: with subtract value + { + LayerTransformation::createParamsI8I8().setSupportAsymmetricQuantization(false), + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}} + }, + { + ngraph::element::i8, + {{ngraph::element::f32}, { 127 }, {0.1f}}, + ngraph::element::f32, + {{}, {}, {}} + } + }, + // U8: empty + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::u8, + {} + }, + { + ngraph::element::u8, + {}, + ngraph::element::u8, + {} + } + }, + // FP32: empty + { + LayerTransformation::createParamsU8I8(), + { + ngraph::element::f32, + {} + }, + { + ngraph::element::f32, + {}, + ngraph::element::f32, + {} + } + } +}; INSTANTIATE_TEST_SUITE_P( smoke_LPT, From d3f2779243103cbd159d46e486d9f7ea0ffaec27 Mon Sep 17 00:00:00 2001 From: NikDemoShow Date: Tue, 3 Aug 2021 15:46:03 +0300 Subject: [PATCH 4/4] add change --- .../low_precision/move_fake_quatize.hpp | 8 +- .../src/move_fake_quantize.cpp | 120 ++-- ...ake_quantize_for_concat_transformation.cpp | 534 ++++++++++-------- .../move_fake_quantize_function.hpp | 49 +- .../src/move_fake_quantize_function.cpp | 212 +++---- 5 files changed, 523 insertions(+), 400 deletions(-) diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp index a2ba2767ef7a4f..701ffaec40d505 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/move_fake_quatize.hpp @@ -12,12 +12,10 @@ namespace ngraph { namespace pass { namespace low_precision { -class TRANSFORMATIONS_API MoveFakeQuantize : public LayerTransformation { +class LP_TRANSFORMATIONS_API MoveFakeQuantize : public LayerTransformation { public: - MaxPoolTransformation(const Params& params); - void registerMatcherIn(GraphRewrite& pass, TransformationContext& context) const override; - bool canBeTransformed(const TransformationContext& context, std::shared_ptr op) const override; - bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) const override; + MoveFakeQuantize(const Params& params); + bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override; bool isPrecisionPreserved(std::shared_ptr layer) const noexcept override; }; diff --git a/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp index a2289eae30ee5e..553a2889cfef68 100644 --- a/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/move_fake_quantize.cpp @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "low_precision/max_pool.hpp" +#include "low_precision/move_fake_quatize.hpp" + +#include +#include #include #include @@ -11,51 +14,72 @@ #include "low_precision/network_helper.hpp" namespace ngraph { -namespace pass { -namespace low_precision { - -MaxPoolTransformation::MaxPoolTransformation(const Params& params) : LayerTransformation(params) { -} - -void MaxPoolTransformation::registerMatcherIn(GraphRewrite &pass, TransformationContext &context) const { - addPattern( - pass, - context, - make_op_pattern({ make_op_label() })); -} - -bool MaxPoolTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr op) const { - if (!LayerTransformation::canBeTransformed(context, op)) { - return false; - } - - const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op); - if (dequantization.empty()) { - return false; - } - - const std::vector scales = as_type_ptr(dequantization.multiply->get_input_node_shared_ptr(1))->cast_vector(); - if (std::any_of(scales.begin(), scales.end(), [](const float value) { return value < 0.0; })) { - return false; - } - - return true; -} - -bool MaxPoolTransformation::transform(TransformationContext& context, ngraph::pattern::Matcher &m) const { - if (!canBeTransformed(context, m.get_match_root())) { - return false; - } - - const std::shared_ptr pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root()); - moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling), false); - return true; -} - -bool MaxPoolTransformation::isPrecisionPreserved(std::shared_ptr layer) const noexcept { - return true; -} - -} // namespace low_precision -} // namespace pass + namespace pass { + namespace low_precision { + + MoveFakeQuantize::MoveFakeQuantize(const Params& params) : LayerTransformation(params) { + auto matcher = ngraph::pattern::wrap_type(); + + ngraph::graph_rewrite_callback callback = [this](pattern::Matcher& m) { + auto op = m.get_match_root(); + if (transformation_callback(op)) { + return false; + } + + return transform(*context, m); + }; + + auto m = std::make_shared(matcher, "MoveFakeQuantize"); + this->register_matcher(m, callback); + } + + bool MoveFakeQuantize::transform(TransformationContext& context, ngraph::pattern::Matcher& m) { + auto fq = m.get_match_root(); + auto result = *fq->output(0).get_target_inputs().begin(); + auto operation = fq->get_input_node_shared_ptr(0); + auto type = operation->get_type_name(); + std::shared_ptr concat, fq1input, fq2input; + if (strcmp(type, "Concat") == 0) { + concat = operation; + fq1input = operation->get_input_node_shared_ptr(0); + fq2input = operation->get_input_node_shared_ptr(1); + } + else { + concat = operation->get_input_node_shared_ptr(0); + auto input1 = concat->get_input_node_shared_ptr(0); + auto input2 = concat->get_input_node_shared_ptr(1); + if (strcmp(type, "Relu") == 0) { + fq1input = std::make_shared(input1->output(0)); + fq2input = std::make_shared(input2->output(0)); + } + } + auto fq1 = std::make_shared(fq1input, + fq->get_input_node_shared_ptr(1), + fq->get_input_node_shared_ptr(2), + fq->get_input_node_shared_ptr(3), + fq->get_input_node_shared_ptr(4), + as_type_ptr(fq)->get_levels()); + auto fq2 = std::make_shared(fq2input, + fq->get_input_node_shared_ptr(1), + fq->get_input_node_shared_ptr(2), + fq->get_input_node_shared_ptr(3), + fq->get_input_node_shared_ptr(4), + as_type_ptr(fq)->get_levels()); + + auto new_concat = concat->clone_with_new_inputs({ fq1->output(0), fq2->output(0) }); + auto& rtInfo = new_concat->get_rt_info(); + new_concat->set_friendly_name("output"); + rtInfo["Variant::std::string"] = std::make_shared>("concat"); + + replace_node(concat, new_concat); + replace_node(fq, new_concat); + return true; + } + + bool MoveFakeQuantize::isPrecisionPreserved(std::shared_ptr layer) const noexcept { + return true; + } + + } // namespace low_precision + } // namespace pass } // namespace ngraph diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp index 9bf23897efa2e9..5155de259624a4 100644 --- a/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/move_fake_quantize_for_concat_transformation.cpp @@ -7,256 +7,340 @@ #include #include #include +#include #include +#include + #include #include -#include #include -#include + +#include + +#include "low_precision/move_fake_quantize.hpp" +#include +#include +#include +#include +#include +#include +#include #include "common_test_utils/ngraph_test_utils.hpp" #include "lpt_ngraph_functions/move_fake_quantize_function.hpp" +#include "lpt_ngraph_functions/common/builders.hpp" #include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp" #include "lpt_ngraph_functions/relu_function.hpp" #include "simple_low_precision_transformer.hpp" -//nd/lpt/move_fake_quantize + using namespace testing; using namespace ngraph; using namespace ngraph::pass; namespace { -class MoveFakeQuantizeActualValues { -public: - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize1; - ngraph::builder::subgraph::DequantizationOperations::Convert convert1; - ngraph::builder::subgraph::DequantizationOperations dequantization1; - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize2; - ngraph::builder::subgraph::DequantizationOperations::Convert convert2; - ngraph::builder::subgraph::DequantizationOperations dequantization2; - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize3; - ngraph::builder::subgraph::DequantizationOperations::Convert convert3; - ngraph::builder::subgraph::DequantizationOperations dequantization3; -}; - -inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeActualValues& values) { - return out << "_" << - values.fakeQuantize1 << "_" << - values.convert1.outPrecision << "_" << - values.dequantization1 << "_" << - values.fakeQuantize2 << "_" << - values.convert2.outPrecision << "_" << - values.dequantization2; -} - -class MoveFakeQuantizeResultValues { -public: - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize1; - ngraph::builder::subgraph::DequantizationOperations::Convert convert1; - ngraph::builder::subgraph::DequantizationOperations dequantization1; - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize2; - ngraph::builder::subgraph::DequantizationOperations::Convert convert2; - ngraph::builder::subgraph::DequantizationOperations dequantization2; - ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantize3; - ngraph::builder::subgraph::DequantizationOperations::Convert convert3; - ngraph::builder::subgraph::DequantizationOperations dequantization3; - ngraph::element::Type precisionAfterOperation; - ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; -}; - -inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeResultValues& values) { - return out << "_" << - values.fakeQuantize1 << "_" << - values.convert1.outPrecision << "_" << - values.dequantization1 << "_" << - values.fakeQuantize2 << "_" << - values.convert2.outPrecision << "_" << - values.dequantization2 << "_" << - values.dequantizationAfter; -} - -class MoveFakeQuantizeTestValues { -public: - ngraph::pass::low_precision::LayerTransformation::Params params; - bool multiChannels; - std::int64_t axis; - MoveFakeQuantizeActualValues actual; - MoveFakeQuantizeResultValues result; -}; - -inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeTestValues& values) { - return out << "_" << values.multiChannels << "_" << values.actual << "_" << values.result; -} - -typedef std::tuple < - ngraph::element::Type, - ngraph::PartialShape, - MoveFakeQuantizeTestValues -> MoveFakeQuantizeParams; - -class MoveFakeQuantize : public LayerTransformation, public testing::WithParamInterface { -public: - void SetUp() override { - const ngraph::element::Type precision = std::get<0>(GetParam()); - const ngraph::PartialShape shape = std::get<1>(GetParam()); - MoveFakeQuantizeTestValues testValues = std::get<2>(GetParam()); + class MoveFakeQuantizeActualValues { + public: + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeBefore1; //before1 + ngraph::builder::subgraph::DequantizationOperations::Convert convertBefore1; + ngraph::builder::subgraph::DequantizationOperations dequantizationBefore1; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeBefore2; //before1 + ngraph::builder::subgraph::DequantizationOperations::Convert convertBefore2; + ngraph::builder::subgraph::DequantizationOperations dequantizationBefore2; + std::string operation; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeAfter; // after + ngraph::builder::subgraph::DequantizationOperations::Convert convertAfter; + ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; + }; - // dequantization output precision depends on input precision - // to avoid huge amount of tests cases let's define dequantization output precision as input precision - if (!testValues.actual.dequantization1.multiply.empty()) { - testValues.actual.dequantization1.multiply.outPrecision = precision; - } - if (!testValues.actual.dequantization2.multiply.empty()) { - testValues.actual.dequantization2.multiply.outPrecision = precision; + inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeActualValues& values) { + return out << "_" << + values.fakeQuantizeBefore1 << "_" << + values.convertBefore1.outPrecision << "_" << + values.dequantizationBefore1 << "_" << + values.fakeQuantizeBefore2 << "_" << + values.convertBefore2.outPrecision << "_" << + values.dequantizationBefore2 << "_" << + values.operation << "_" << + values.fakeQuantizeAfter << "_" << + values.convertAfter.outPrecision << "_" << + values.dequantizationAfter; + } + + class MoveFakeQuantizeResultValues { + public: + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeBefore1; + ngraph::builder::subgraph::DequantizationOperations::Convert convertBefore1; + ngraph::builder::subgraph::DequantizationOperations dequantizationBefore1; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeBefore2; + ngraph::builder::subgraph::DequantizationOperations::Convert convertBefore2; + ngraph::builder::subgraph::DequantizationOperations dequantizationBefore2; + std::string operation; + ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeAfter; + ngraph::builder::subgraph::DequantizationOperations::Convert convertAfter; + ngraph::builder::subgraph::DequantizationOperations dequantizationAfter; + ngraph::element::Type precisionAfterOperation; + ngraph::builder::subgraph::DequantizationOperations dequantizationAfterNotFQ; + }; + + inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeResultValues& values) { + return out << "_" << + values.fakeQuantizeBefore1 << "_" << + values.convertBefore1.outPrecision << "_" << + values.dequantizationBefore1 << "_" << + values.fakeQuantizeBefore2 << "_" << + values.convertBefore2.outPrecision << "_" << + values.dequantizationBefore2 << "_" << + values.operation << "_" << + values.fakeQuantizeAfter << "_" << + values.convertAfter << "_" << + values.dequantizationAfter << "_" << + values.dequantizationAfterNotFQ; + } + + class MoveFakeQuantizeTestValues { + public: + MoveFakeQuantizeTestValues() = default; + MoveFakeQuantizeTestValues( + const TestTransformationParams& params, + const bool multiChannels, + const std::int64_t axis, + const MoveFakeQuantizeActualValues& actual, + const MoveFakeQuantizeResultValues& result, + const bool addNotPrecisionPreservedOperation = false, + const bool checkIntervalsAlignmentAttributes = true) : + params(params), + multiChannels(multiChannels), + axis(axis), + actual(actual), + result(result), + addNotPrecisionPreservedOperation(addNotPrecisionPreservedOperation), + checkIntervalsAlignmentAttributes(checkIntervalsAlignmentAttributes) {} + + TestTransformationParams params; + bool multiChannels; + std::int64_t axis; + MoveFakeQuantizeActualValues actual; + MoveFakeQuantizeResultValues result; + // add not precision preserved operation to set output precision for FakeQuantize + // don't set to 'true' by default to keep test cases with tested operation as output + bool addNotPrecisionPreservedOperation; + bool checkIntervalsAlignmentAttributes; + }; + + inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeTestValues& values) { + return out << "_" << values.multiChannels << "_" << values.actual << "_" << values.result; + } + + typedef std::tuple < + ngraph::element::Type, + ngraph::PartialShape, + MoveFakeQuantizeTestValues + > MoveFakeQuantizeParams; + + class MoveFakeQuantize : public LayerTransformation, public testing::WithParamInterface { + public: + void SetUp() override { + const ngraph::element::Type precision = std::get<0>(GetParam()); + const ngraph::PartialShape shape = std::get<1>(GetParam()); + MoveFakeQuantizeTestValues testValues = std::get<2>(GetParam()); + + // dequantization output precision depends on input precision + // to avoid huge amount of tests cases let's define dequantization output precision as input precision + if (!testValues.actual.dequantizationBefore1.multiply.empty()) { + testValues.actual.dequantizationBefore1.multiply.outPrecision = precision; + } + if (!testValues.actual.dequantizationBefore2.multiply.empty()) { + testValues.actual.dequantizationBefore2.multiply.outPrecision = precision; + } + actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.actual.fakeQuantizeBefore1, + testValues.actual.convertBefore1, + testValues.actual.dequantizationBefore1, + testValues.actual.fakeQuantizeBefore2, + testValues.actual.convertBefore2, + testValues.actual.dequantizationBefore2, + testValues.actual.operation, + testValues.actual.fakeQuantizeAfter, + testValues.actual.convertAfter, + testValues.actual.dequantizationAfter, + ngraph::element::undefined, + {}, + testValues.axis); + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.actual").run_on_function(actualFunction); + + auto supportedPrecisionsOnActivation = std::vector({ + ngraph::pass::low_precision::OperationPrecisionRestriction::create({{0, testValues.params.precisionsOnActivations}}) + }); + + auto quantizationRestrictions = testValues.multiChannels ? + std::vector() : + std::vector({ + ngraph::pass::low_precision::OperationPerTensorQuantizationRestriction::create() + }); + + const auto params = TestTransformationParams::toParams(testValues.params); + SimpleLowPrecisionTransformer transformer(supportedPrecisionsOnActivation, quantizationRestrictions); + //SimpleLowPrecisionTransformer transformer({}, {}); + transformer.commonGraphRewrite->add_matcher(params); + transformer.transform(actualFunction); + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.transform").run_on_function(actualFunction); + + // dequantization output precision depends on input precision + // to avoid huge amount of tests cases let's define dequantization output precision as input precision + if (!testValues.result.dequantizationAfter.multiply.empty()) { + testValues.result.dequantizationAfter.multiply.outPrecision = precision; + } + + if (!testValues.params.updatePrecisions && + (precision == ngraph::element::f32) && + !testValues.result.dequantizationAfter.convert.empty()) { + testValues.result.dequantizationAfter.convert = {}; + } + + //IntervalsAlignmentSharedValue::Interval interval{ -1.28f, 2.55f }; + + referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( + precision, + shape, + testValues.result.fakeQuantizeBefore1, + testValues.result.convertBefore1, + testValues.result.dequantizationBefore1, + testValues.result.fakeQuantizeBefore2, + testValues.result.convertBefore2, + testValues.result.dequantizationBefore2, + testValues.result.operation, + testValues.result.fakeQuantizeAfter, + testValues.result.convertAfter, + testValues.result.dequantizationAfter, + testValues.result.precisionAfterOperation, + {}, + testValues.axis); + ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.reference").run_on_function(referenceFunction); } - actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( - precision, - shape, - testValues.actual.fakeQuantize1, - testValues.actual.convert1, - testValues.actual.dequantization1, - testValues.actual.fakeQuantize2, - testValues.actual.convert2, - testValues.actual.dequantization2, - testValues.actual.fakeQuantize3, - testValues.actual.convert3, - testValues.actual.dequantization3, - ngraph::element::undefined, - {}, - testValues.axis); - /* - actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( - precision, - shape, - testValues.actual.fakeQuantize1, - testValues.actual.fakeQuantize2, - testValues.actual.fakeQuantize3, - testValues.axis); - */ - ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.actual").run_on_function(actualFunction); - - SimpleLowPrecisionTransformer transform; - transform.add(testValues.params); - transform.transform(actualFunction); - ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.transform").run_on_function(actualFunction); - - // dequantization output precision depends on input precision - // to avoid huge amount of tests cases let's define dequantization output precision as input precision - if (!testValues.result.dequantizationAfter.multiply.empty()) { - testValues.result.dequantizationAfter.multiply.outPrecision = precision; + + static std::string getTestCaseName(testing::TestParamInfo obj) { + const ngraph::element::Type precision = std::get<0>(obj.param); + const ngraph::PartialShape shape = std::get<1>(obj.param); + const MoveFakeQuantizeTestValues testValues = std::get<2>(obj.param); + + std::ostringstream result; + result << + LayerTransformation::getTestCaseNameByParams(precision, shape, testValues.params) << "_" << + (testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") << + "axis_" << testValues.axis << "_" << + testValues.actual << "_" << + testValues.result << "_"; + return result.str(); } + }; - if (!testValues.params.updatePrecisions && - (precision == ngraph::element::f32) && - !testValues.result.dequantizationAfter.convert.empty()) { - testValues.result.dequantizationAfter.convert = {}; + TEST_P(MoveFakeQuantize, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, actualFunction, true, true, false, true, false); + ASSERT_TRUE(res.first) << res.second; + + const auto actualFakeQuantizes = LayerTransformation::get(actualFunction); + ASSERT_TRUE(checkIfOutputAttributesSharedValuesAreTheSame>(actualFakeQuantizes)) << + "PrecisionsAttribute are not the same"; + + MoveFakeQuantizeTestValues testValues = std::get<2>(GetParam()); + if (testValues.checkIntervalsAlignmentAttributes) { + auto operations = LayerTransformation::get(actualFunction); + operations.insert(operations.end(), actualFakeQuantizes.begin(), actualFakeQuantizes.end()); + ASSERT_TRUE(checkIfAttributesSharedValuesAreTheSame>(operations)) << + "IntervalsAlignmentAttribute are not the same"; } - referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( - precision, - shape, - testValues.actual.fakeQuantize1, - testValues.actual.convert1, - testValues.actual.dequantization1, - testValues.actual.fakeQuantize2, - testValues.actual.convert2, - testValues.actual.dequantization2, - testValues.actual.fakeQuantize3, - testValues.actual.convert3, - testValues.actual.dequantization3, - testValues.result.precisionAfterOperation, - testValues.result.dequantizationAfter, - testValues.axis); - /* - referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get( - precision, - shape, - testValues.actual.fakeQuantize1, - testValues.actual.fakeQuantize2, - testValues.actual.fakeQuantize3, - testValues.axis); - */ - ngraph::pass::VisualizeTree("c:\\Users\\ndemasho\\rep\\Visual\\MFQtest.reference").run_on_function(referenceFunction); } - static std::string getTestCaseName(testing::TestParamInfo obj) { - const ngraph::element::Type precision = std::get<0>(obj.param); - const ngraph::PartialShape shape = std::get<1>(obj.param); - const MoveFakeQuantizeTestValues testValues = std::get<2>(obj.param); - - std::ostringstream result; - result << - LayerTransformation::getTestCaseNameByParams(precision, shape, testValues.params) << "_" << - (testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") << - "axis_" << testValues.axis << "_" << - testValues.actual << "_" << - testValues.result << "_"; - return result.str(); - } -}; - -TEST_P(MoveFakeQuantize, CompareFunctions) { - actualFunction->validate_nodes_and_infer_types(); - auto res = compare_functions(referenceFunction, referenceFunction, true, true, true); - ASSERT_TRUE(res.first) << res.second; -} - -const std::vector precisions = { - ngraph::element::f32, - //ngraph::element::f16 -}; - -namespace testValues1 { -const std::vector shapes = { - { 1, 3, 9, 9 }, - //{ 4, 3, 9, 9 }, - //{ Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() } -}; - -const std::vector testValues = { - // U8: concat - { - LayerTransformation::createParamsU8I8(), - false, - 1, - { - {}, - {}, - {}, - {}, - {}, - {}, - { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} }, - { ngraph::element::u8 }, + const std::vector precisions = { + ngraph::element::f32, + //ngraph::element::f16 + }; + + namespace testValues1 { + const std::vector shapes = { + { 1, 3, 9, 9 }, + //{ 4, 3, 9, 9 }, + //{ Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() } + }; + + const std::vector testValues = { + // U8: concat { - { element::f32 }, - {}, - { 0.01f } + LayerTransformation::createParamsU8I8(), + false, + 1, + { + {}, + {}, + {}, + {}, + {}, + {}, + "", + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {} + }, + { + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {}, + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {}, + "", + {}, + {}, + {}, + }, + false, + false }, - }, - { - { 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} }, - {}, - {}, - { 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} }, - {}, - {}, - {}, - {}, - {}, - ngraph::element::undefined, - {}, - } - }, -}; -INSTANTIATE_TEST_SUITE_P( - smoke_LPT, - MoveFakeQuantize, - ::testing::Combine( - ::testing::ValuesIn(precisions), - ::testing::ValuesIn(shapes), - ::testing::ValuesIn(testValues)), - MoveFakeQuantize::getTestCaseName); -} // namespace testValues1 + { + LayerTransformation::createParamsU8I8(), + false, + 1, + { + {}, + {}, + {}, + {}, + {}, + {}, + "relu", + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {} + }, + { + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {}, + { 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}}, + {}, + {}, + "relu", + {}, + {}, + {}, + }, + false, + false + } + }; + INSTANTIATE_TEST_SUITE_P( + smoke_LPT, + MoveFakeQuantize, + ::testing::Combine( + ::testing::ValuesIn(precisions), + ::testing::ValuesIn(shapes), + ::testing::ValuesIn(testValues)), + MoveFakeQuantize::getTestCaseName); + } // namespace testValues1 } // namespace diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp index efe2e5b429f5de..d31c8217d49bc6 100644 --- a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/include/lpt_ngraph_functions/move_fake_quantize_function.hpp @@ -12,30 +12,31 @@ #include "common/dequantization_operations.hpp" namespace ngraph { -namespace builder { -namespace subgraph { + namespace builder { + namespace subgraph { -class MoveFakeQuantize { -public: - static std::shared_ptr get( - const ngraph::element::Type inputPrecision, - const ngraph::PartialShape& inputShape, - const FakeQuantizeOnDataWithConstant& fakeQuantize1, - const DequantizationOperations::Convert& convert1, - const DequantizationOperations& dequantization1, - const FakeQuantizeOnDataWithConstant& fakeQuantize2, - const DequantizationOperations::Convert& convert2, - const DequantizationOperations& dequantization2, - const FakeQuantizeOnDataWithConstant& fakeQuantize3, - const DequantizationOperations::Convert& convert3, - const DequantizationOperations& dequantization3, - const ngraph::element::Type precisionAfterOperation, - const DequantizationOperations& dequantizationAfter, - const std::int64_t& axis); -private: - static std::shared_ptr makeMaxPool(const Output& parent, const std::vector& kernel); -}; + class MoveFakeQuantize { + public: + static std::shared_ptr get( + const ngraph::element::Type inputPrecision, + const ngraph::PartialShape& inputShape, + const FakeQuantizeOnDataWithConstant& fakeQuantize1, + const DequantizationOperations::Convert& convert1, + const DequantizationOperations& dequantization1, + const FakeQuantizeOnDataWithConstant& fakeQuantize2, + const DequantizationOperations::Convert& convert2, + const DequantizationOperations& dequantization2, + const std::string operation, + const FakeQuantizeOnDataWithConstant& fakeQuantize3, + const DequantizationOperations::Convert& convert3, + const DequantizationOperations& dequantization3, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const std::int64_t& axis); + private: + static std::shared_ptr makeMaxPool(const Output& parent, const std::vector& kernel); + }; -} // namespace subgraph -} // namespace builder + } // namespace subgraph + } // namespace builder } // namespace ngraph diff --git a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp index 5ae934202125e7..c5b9d92610aa4b 100644 --- a/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp +++ b/inference-engine/tests/ngraph_helpers/lpt_ngraph_functions/src/move_fake_quantize_function.cpp @@ -3,6 +3,7 @@ // #include "lpt_ngraph_functions/move_fake_quantize_function.hpp" +#include #include #include "ngraph_ops/type_relaxed.hpp" @@ -13,102 +14,117 @@ #include "lpt_ngraph_functions/common/builders.hpp" namespace ngraph { -namespace builder { -namespace subgraph { - -using namespace ngraph::pass; - -std::shared_ptr MoveFakeQuantize::get( - const ngraph::element::Type inputPrecision, - const ngraph::PartialShape& inputShape, - const FakeQuantizeOnDataWithConstant& fqOnData1, - const DequantizationOperations::Convert& convert1, - const DequantizationOperations& dequantization1, - const FakeQuantizeOnDataWithConstant& fqOnData2, - const DequantizationOperations::Convert& convert2, - const DequantizationOperations& dequantization2, - const FakeQuantizeOnDataWithConstant& fqOnData3, - const DequantizationOperations::Convert& convert3, - const DequantizationOperations& dequantization3, - const ngraph::element::Type precisionAfterOperation, - const DequantizationOperations& dequantizationAfter, - const std::int64_t& axis) { - - const auto input1 = std::make_shared(inputPrecision, inputShape); - input1->set_friendly_name("input1"); - - const auto input2 = std::make_shared(inputPrecision, inputShape); - input2->set_friendly_name("input2"); - - if (fqOnData3.empty()) { - std::shared_ptr parent1 = makeFakeQuantizeTypeRelaxed(input1, inputPrecision, fqOnData1); - if (!convert1.empty()) { - parent1 = std::make_shared(parent1, convert1.outPrecision); - } - if (!dequantization1.empty()) { - parent1 = makeDequantization(parent1, dequantization1); - } - - std::shared_ptr parent2 = makeFakeQuantizeTypeRelaxed(input2, inputPrecision, fqOnData2); - if (!convert2.empty()) { - parent2 = std::make_shared(parent2, convert2.outPrecision); - } - if (!dequantization2.empty()) { - parent2 = makeDequantization(parent2, dequantization2); - } - - const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ parent1, parent2 }, axis); - - auto& rtInfo = concat->get_rt_info(); - rtInfo["Variant::std::string"] = std::make_shared>("concat"); - - const auto lastDequantization = makeDequantization(concat, dequantizationAfter); - lastDequantization->set_friendly_name("output"); - - ngraph::ResultVector results{ std::make_shared(lastDequantization) }; - std::shared_ptr function = std::make_shared( - results, - ngraph::ParameterVector{ input1, input2 }, - "MoveFakeQuantize"); - return function; - } - else { - const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ input1, input2 }, axis); - - auto& rtInfo = concat->get_rt_info(); - rtInfo["Variant::std::string"] = std::make_shared>("concat"); - - std::shared_ptr fq = makeFakeQuantizeTypeRelaxed(concat, inputPrecision, fqOnData3); - - const auto lastDequantization = makeDequantization(fq, dequantizationAfter); - lastDequantization->set_friendly_name("output"); - - ngraph::ResultVector results{ std::make_shared(lastDequantization) }; - std::shared_ptr function = std::make_shared( - results, - ngraph::ParameterVector{ input1, input2 }, - "MoveFakeQuantize"); - return function; - } -} - -std::shared_ptr MoveFakeQuantize::makeMaxPool(const Output& parent, const std::vector& kernel) { - const std::vector stride = { 1, 1 }; - const std::vector padBegin = { 0, 0 }; - const std::vector padEnd = { 0, 0 }; - const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET; - const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR; - const auto pooling = std::make_shared( - parent, - stride, - padBegin, - padEnd, - kernel, - roundingType, - padType); - return pooling; -} - -} // namespace subgraph -} // namespace builder + namespace builder { + namespace subgraph { + + using namespace ngraph::pass; + + std::shared_ptr MoveFakeQuantize::get( + const ngraph::element::Type inputPrecision, + const ngraph::PartialShape& inputShape, + const FakeQuantizeOnDataWithConstant& fqOnData1, + const DequantizationOperations::Convert& convert1, + const DequantizationOperations& dequantization1, + const FakeQuantizeOnDataWithConstant& fqOnData2, + const DequantizationOperations::Convert& convert2, + const DequantizationOperations& dequantization2, + const std::string operation, + const FakeQuantizeOnDataWithConstant& fqOnData3, + const DequantizationOperations::Convert& convert3, + const DequantizationOperations& dequantization3, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const std::int64_t& axis) { + + const auto input1 = std::make_shared(inputPrecision, inputShape); + input1->set_friendly_name("input1"); + + const auto input2 = std::make_shared(inputPrecision, inputShape); + input2->set_friendly_name("input2"); + + + if (fqOnData3.empty()) { + std::shared_ptr parent1, parent2; + if (operation == "relu") { + auto relu1 = std::make_shared(input1->output(0)); + auto relu2 = std::make_shared(input2->output(0)); + parent1 = makeFakeQuantizeTypeRelaxed(relu1, inputPrecision, fqOnData1); + parent2 = makeFakeQuantizeTypeRelaxed(relu2, inputPrecision, fqOnData2); + } + else { + parent1 = makeFakeQuantizeTypeRelaxed(input1, inputPrecision, fqOnData1); + parent2 = makeFakeQuantizeTypeRelaxed(input1, inputPrecision, fqOnData2); + } + + if (!convert1.empty()) { + parent1 = std::make_shared(parent1, convert1.outPrecision); + } + if (!dequantization1.empty()) { + parent1 = makeDequantization(parent1, dequantization1); + } + + if (!convert2.empty()) { + parent2 = std::make_shared(parent2, convert2.outPrecision); + } + if (!dequantization2.empty()) { + parent2 = makeDequantization(parent2, dequantization2); + } + + const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ parent1, parent2 }, axis); + auto& rtInfo = concat->get_rt_info(); + rtInfo["Variant::std::string"] = std::make_shared>("concat"); + + const auto lastDequantization = makeDequantization(concat, dequantizationAfter); + lastDequantization->set_friendly_name("output"); + + ngraph::ResultVector results{ std::make_shared(lastDequantization) }; + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "MoveFakeQuantize"); + return function; + } + else { + const std::shared_ptr concat = std::make_shared(ngraph::OutputVector{ input1, input2 }, axis); + auto& rtInfo = concat->get_rt_info(); + rtInfo["Variant::std::string"] = std::make_shared>("concat"); + + concat->set_friendly_name("output"); + std::shared_ptr fq; + if (operation == "relu") { + auto relu = std::make_shared(concat->output(0)); + fq = makeFakeQuantize(relu, inputPrecision, fqOnData3); + } + else { + fq = makeFakeQuantize(concat, inputPrecision, fqOnData3); + } + + ngraph::ResultVector results{ std::make_shared(fq) }; + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "MoveFakeQuantize"); + return function; + } + } + + std::shared_ptr MoveFakeQuantize::makeMaxPool(const Output& parent, const std::vector& kernel) { + const std::vector stride = { 1, 1 }; + const std::vector padBegin = { 0, 0 }; + const std::vector padEnd = { 0, 0 }; + const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET; + const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR; + const auto pooling = std::make_shared( + parent, + stride, + padBegin, + padEnd, + kernel, + roundingType, + padType); + return pooling; + } + + } // namespace subgraph + } // namespace builder } // namespace ngraph