From 9405359335fcfac4754bb2057ba6cc339121f9cb Mon Sep 17 00:00:00 2001 From: Vladislav Golubev Date: Sat, 19 Sep 2020 15:57:34 +0300 Subject: [PATCH 1/2] [LPT] Functional tests: added test-cases "Concat with intermediate with constant" --- ...ermediate_with_constant_transformation.cpp | 321 ++++++++++++++++++ .../concat_function.hpp | 19 ++ .../concat_function.cpp | 149 ++++++++ 3 files changed, 489 insertions(+) create mode 100644 inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_intermediate_with_constant_transformation.cpp diff --git a/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_intermediate_with_constant_transformation.cpp b/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_intermediate_with_constant_transformation.cpp new file mode 100644 index 00000000000000..f865178503cbcf --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/lp_transformations/concat_with_intermediate_with_constant_transformation.cpp @@ -0,0 +1,321 @@ +// Copyright (C) 2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "layer_transformation.hpp" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common_test_utils/ngraph_test_utils.hpp" +#include "ngraph_functions/low_precision_transformations/concat_function.hpp" +#include "ngraph_functions/low_precision_transformations/common/fake_quantize_on_data.hpp" +#include "simple_low_precision_transformer.hpp" + +using namespace testing; +using namespace ngraph; +using namespace ngraph::pass; + +namespace { + +class ConcatTransformationActualValues { +public: + ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize1; + ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize2; +}; + +inline std::ostream& operator<<(std::ostream& out, const ConcatTransformationActualValues& values) { + return out << "_" << values.fakeQuantize1 << "_" << values.fakeQuantize2; +} + +class ConcatTransformationResultValues { +public: + ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize1; + ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize2; + ngraph::builder::subgraph::DequantizationOperations dequantizationOperations1; + ngraph::element::Type precisionBeforeOp; + ngraph::element::Type precisionAfterOperation; + ngraph::builder::subgraph::DequantizationOperations dequantizationOperations2; + ngraph::element::Type precisionAfterDequantization; +}; + +inline std::ostream& operator<<(std::ostream& out, const ConcatTransformationResultValues& values) { + return out << "_" << + values.fakeQuantize1 << "_" << + values.fakeQuantize2 << "_" << + values.precisionBeforeOp << "_" << + values.dequantizationOperations1 << "_" << + values.dequantizationOperations2; +} + +class ConcatTransformationTestValues { +public: + ngraph::pass::low_precision::LayerTransformation::Params params; + bool multiChannels; + bool transparentIntermediate; + ConcatTransformationActualValues actual; + ConcatTransformationResultValues result; +}; + +inline std::ostream& operator<<(std::ostream& out, const ConcatTransformationTestValues& values) { + return out << "_" << values.multiChannels << "_" << values.actual << "_" << values.result; +} + +typedef std::tuple < + ngraph::element::Type, + ngraph::Shape, + ConcatTransformationTestValues +> ConcatTransformationParams; + +class ConcatWithIntermediateWithConstantTransformation : public LayerTransformation, public testing::WithParamInterface { +public: + void SetUp() override { + const ngraph::element::Type precision = std::get<0>(GetParam()); + const ngraph::Shape shape = std::get<1>(GetParam()); + ConcatTransformationTestValues testValues = std::get<2>(GetParam()); + + actualFunction = ngraph::builder::subgraph::ConcatFunction::getOriginalWithIntermediateWithConstant( + precision, + shape, + testValues.transparentIntermediate, + testValues.actual.fakeQuantize1, + testValues.actual.fakeQuantize2); + + SimpleLowPrecisionTransformer transform; + if (testValues.multiChannels) { + transform.add(testValues.params); + } else { + transform.add(testValues.params); + } + transform.add(testValues.params); + transform.add(testValues.params); + transform.transform(actualFunction); + + referenceFunction = ngraph::builder::subgraph::ConcatFunction::getReferenceWithIntermediateWithConstant( + precision, + shape, + testValues.transparentIntermediate, + testValues.result.fakeQuantize1, + testValues.result.fakeQuantize2, + testValues.result.precisionBeforeOp, + testValues.result.dequantizationOperations1, + testValues.result.precisionAfterOperation, + testValues.result.dequantizationOperations2, + testValues.result.precisionAfterDequantization); + } + + static std::string getTestCaseName(testing::TestParamInfo obj) { + const ngraph::element::Type precision = std::get<0>(obj.param); + const ngraph::Shape shape = std::get<1>(obj.param); + ConcatTransformationTestValues testValues = std::get<2>(obj.param); + + std::ostringstream result; + result << + toString(testValues.params) << "_" << + shape << "_" << + (testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") << + testValues.actual << "_" << + testValues.result << "_"; + return result.str(); + } +}; + +TEST_P(ConcatWithIntermediateWithConstantTransformation, CompareFunctions) { + actualFunction->validate_nodes_and_infer_types(); + auto res = compare_functions(referenceFunction, actualFunction, true, true, true); + ASSERT_TRUE(res.first) << res.second; +} + +const std::vector precisions = { + ngraph::element::f32, + // ngraph::element::f16 +}; + +const std::vector testValues = { + // U8: concat + { + LayerTransformation::createParamsU8I8(), + false, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { {}, {}, {} }, + ngraph::element::u8, + ngraph::element::u8, + { ngraph::element::f32, {}, { 0.01f } }, + ngraph::element::f32 + } + }, + // I8: concat + { + LayerTransformation::createParamsI8I8(), + false, + true, + { + { 256ul, ngraph::Shape({}), {-1.28f}, {1.27f}, {-1.28f}, {1.27f} }, + { 256ul, ngraph::Shape({}), {-1.28f / 2.f}, {1.27f / 2.f}, {-1.28f / 2.f}, {1.27f / 2.f} } + }, + { + { 256ul, ngraph::Shape({}), {-1.28f}, {1.27f}, {-128.f}, {127.f} }, + { 256ul, ngraph::Shape({}), {-1.28f / 2.f}, {1.27f / 2.f}, {-64.f}, { 64.f} }, + { {}, {}, {} }, + ngraph::element::i8, + ngraph::element::i8, + { ngraph::element::f32, {}, { 0.01f } }, + ngraph::element::f32 + } + }, + // U8: concat with subtract + { + LayerTransformation::createParamsU8I8(), + false, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {1.275f}, {2.55f} } + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {128.f}, {255.f} }, + { {}, {}, {} }, + ngraph::element::u8, + ngraph::element::u8, + { ngraph::element::f32, {}, { 0.01f } }, + ngraph::element::f32 + } + }, + // U8: not update precisions + { + LayerTransformation::createParamsU8I8().setUpdatePrecisions(false), + false, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {1.275f}, {2.55f} } + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {128.f}, {255.f} }, + { {}, {}, {} }, + ngraph::element::f32, + ngraph::element::f32, + { ngraph::element::f32, {}, { 0.01f } }, + ngraph::element::f32 + } + }, + // U8: concat multi channels + { + LayerTransformation::createParamsU8I8(), + true, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {0.f}, {2.55f / 2.f}, {0.f}, {2.55f / 2.f} } + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {0.f}, {2.55f / 2.f}, {0.f}, { 255.f} }, + { {}, {}, {} }, + ngraph::element::u8, + ngraph::element::u8, + { ngraph::element::f32, {}, {{ 0.005f, 0.005f, 0.005f, 0.01f, 0.01f, 0.01f }} }, + ngraph::element::f32 + } + }, + // I8: concat multi channels + { + LayerTransformation::createParamsI8I8(), + true, + true, + { + { 256ul, ngraph::Shape({}), {-1.28f}, {1.27f}, {-1.28f}, {1.27f} }, + { 256ul, ngraph::Shape({}), {-1.28f / 2.f}, {1.27f / 2.f}, {-1.28f / 2.f}, {1.27f / 2.f} } + }, + { + { 256ul, ngraph::Shape({}), {-1.28f}, {1.27f}, {-128.f}, {127.f} }, + { 256ul, ngraph::Shape({}), {-1.28f / 2.f}, {1.27f / 2.f}, {-128.f}, {127.f} }, + { {}, {}, {} }, + ngraph::element::i8, + ngraph::element::i8, + { ngraph::element::f32, {}, {{ 0.005f, 0.005f, 0.005f, 0.01f, 0.01f, 0.01f }} }, + ngraph::element::f32 + } + }, + // U8: concat multi channels with subtract + { + LayerTransformation::createParamsU8I8(), + true, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {1.275f}, {2.55f} } + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {0.f}, {255.f} }, + { {}, {}, {} }, + ngraph::element::u8, + ngraph::element::u8, + { + ngraph::element::f32, + {{ -255.f, -255.f, -255.f, 0.f, 0.f, 0.f }}, + {{ 0.005f, 0.005f, 0.005f, 0.01f, 0.01f, 0.01f }} + }, + ngraph::element::f32 + } + }, + // U8: concat multi channels, not update precisions + { + LayerTransformation::createParamsU8I8().setUpdatePrecisions(false), + true, + true, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {2.55f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {1.275f}, {2.55f} } + }, + { + { 256ul, ngraph::Shape({}), {0.f}, {2.55f}, {0.f}, {255.f} }, + { 256ul, ngraph::Shape({}), {1.275f}, {2.55f}, {0.f}, {255.f} }, + { {}, {}, {} }, + ngraph::element::f32, + ngraph::element::f32, + { + ngraph::element::f32, + {{ -255.f, -255.f, -255.f, 0.f, 0.f, 0.f }}, + {{ 0.005f, 0.005f, 0.005f, 0.01f, 0.01f, 0.01f }} + }, + ngraph::element::f32 + } + }, +}; + +const std::vector shapes = { + { 1, 3, 9, 9 }, + { 4, 3, 9, 9 } +}; + +INSTANTIATE_TEST_CASE_P( + LPT, + ConcatWithIntermediateWithConstantTransformation, + ::testing::Combine( + ::testing::ValuesIn(precisions), + ::testing::ValuesIn(shapes), + ::testing::ValuesIn(testValues)), + ConcatWithIntermediateWithConstantTransformation::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/ngraph_functions/include/ngraph_functions/low_precision_transformations/concat_function.hpp b/inference-engine/tests/ngraph_functions/include/ngraph_functions/low_precision_transformations/concat_function.hpp index c38057dcae1441..8426699205447b 100644 --- a/inference-engine/tests/ngraph_functions/include/ngraph_functions/low_precision_transformations/concat_function.hpp +++ b/inference-engine/tests/ngraph_functions/include/ngraph_functions/low_precision_transformations/concat_function.hpp @@ -56,6 +56,13 @@ class ConcatFunction { const FakeQuantizeOnData& fqOnData1, const FakeQuantizeOnData& fqOnData2); + static std::shared_ptr getOriginalWithIntermediateWithConstant( + const ngraph::element::Type precision, + const ngraph::Shape& inputShape, + const bool transparentIntermediate, + const FakeQuantizeOnData& fqOnData1, + const FakeQuantizeOnData& fqOnData2); + static std::shared_ptr getReference( const ngraph::element::Type precision, const ngraph::Shape& inputShape, @@ -106,6 +113,18 @@ class ConcatFunction { const FakeQuantizeOnData& fqOnData2, const DequantizationOperations& dequantizationOperations1, const DequantizationOperations& dequantizationOperations2); + + static std::shared_ptr getReferenceWithIntermediateWithConstant( + const ngraph::element::Type precision, + const ngraph::Shape& inputShape, + const bool transparentIntermediate, + const FakeQuantizeOnData& fqOnData1, + const FakeQuantizeOnData& fqOnData2, + const ngraph::element::Type precisionBeforeOp, + const DequantizationOperations& dequantizationBefore, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const ngraph::element::Type precisionAfterDequantization); }; } // namespace subgraph diff --git a/inference-engine/tests/ngraph_functions/src/low_precision_transformations/concat_function.cpp b/inference-engine/tests/ngraph_functions/src/low_precision_transformations/concat_function.cpp index 3120824d6ce509..6893909596177d 100644 --- a/inference-engine/tests/ngraph_functions/src/low_precision_transformations/concat_function.cpp +++ b/inference-engine/tests/ngraph_functions/src/low_precision_transformations/concat_function.cpp @@ -383,6 +383,74 @@ std::shared_ptr ConcatFunction::getOriginalWithDifferentPrecis return function; } +std::shared_ptr ConcatFunction::getOriginalWithIntermediateWithConstant( + const ngraph::element::Type precision, + const ngraph::Shape& inputShape, + const bool transparentIntermediate, + const FakeQuantizeOnData& fqOnData1, + const FakeQuantizeOnData& fqOnData2) { + const auto input1 = std::make_shared(precision, ngraph::Shape(inputShape)); + input1->set_friendly_name("input"); + const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1); + fakeQuantize1->set_friendly_name("fakeQuantize1"); + + const auto input2 = std::make_shared(precision, ngraph::Shape(inputShape)); + input2->set_friendly_name("input"); + const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2); + fakeQuantize2->set_friendly_name("fakeQuantize2"); + + + std::shared_ptr intermediateOp; + + if (transparentIntermediate) { + const std::vector kernel = { 3, 3 }; + 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( + fakeQuantize1->output(0), + stride, + padBegin, + padEnd, + kernel, + roundingType, + padType); + + ngraph::op::v0::InterpolateAttrs attributes; + attributes.axes = ngraph::AxisSet{ 2, 3 }; + attributes.mode = "nearest"; + attributes.align_corners = false; + attributes.antialias = false; + attributes.pads_begin = { 0 }; + attributes.pads_end = { 0 }; + const auto outputShape = op::Constant::create( + ngraph::element::i64, ngraph::Shape{ 2 }, + ngraph::Shape{ inputShape[2], inputShape[3] }); + intermediateOp = std::make_shared(pooling->output(0), outputShape, attributes); + intermediateOp->set_friendly_name("intermediate"); + } else { + intermediateOp = fakeQuantize1; + } + + const std::shared_ptr concat = std::make_shared( + ngraph::OutputVector{ fakeQuantize2->output(0), intermediateOp->output(0) }, 1); + concat->set_friendly_name("concat"); + + ngraph::ResultVector results{ + std::make_shared(concat), + }; + + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "ConcatWithIntermediateWithConstantTransformation"); + + return function; +} + std::shared_ptr ConcatFunction::getReference( const ngraph::element::Type precision, const ngraph::Shape& inputShape, @@ -918,6 +986,87 @@ std::shared_ptr ConcatFunction::getReferenceWithDifferentPreci return function; } +std::shared_ptr ConcatFunction::getReferenceWithIntermediateWithConstant( + const ngraph::element::Type precision, + const ngraph::Shape& inputShape, + const bool transparentIntermediate, + const FakeQuantizeOnData& fqOnData1, + const FakeQuantizeOnData& fqOnData2, + const ngraph::element::Type precisionBeforeOp, + const DequantizationOperations& dequantizationBefore, + const ngraph::element::Type precisionAfterOperation, + const DequantizationOperations& dequantizationAfter, + const ngraph::element::Type precisionAfterDequantization) { + const auto input1 = std::make_shared(precision, ngraph::Shape(inputShape)); + input1->set_friendly_name("input"); + const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1); + fakeQuantize1->set_friendly_name("fakeQuantize1"); + ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, precisionBeforeOp); + + const auto input2 = std::make_shared(precision, ngraph::Shape(inputShape)); + input2->set_friendly_name("input"); + const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2); + fakeQuantize2->set_friendly_name("fakeQuantize2"); + ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, precisionBeforeOp); + + std::shared_ptr intermediateOp; + + if (transparentIntermediate) { + const auto deqBefore = makeDequantization(fakeQuantize1->output(0), dequantizationBefore); + const std::vector kernel = { 3, 3 }; + 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( + fakeQuantize1->output(0), + stride, + padBegin, + padEnd, + kernel, + roundingType, + padType); + + ngraph::op::v0::InterpolateAttrs attributes; + attributes.axes = ngraph::AxisSet{ 2, 3 }; + attributes.mode = "nearest"; + attributes.align_corners = false; + attributes.antialias = false; + attributes.pads_begin = { 0 }; + attributes.pads_end = { 0 }; + + const auto outputShape = op::Constant::create( + ngraph::element::i64, ngraph::Shape{ 2 }, + ngraph::Shape{ inputShape[2], inputShape[3] }); + intermediateOp = std::make_shared(pooling->output(0), outputShape, attributes); + intermediateOp->set_friendly_name("intermediate"); + } else { + intermediateOp = fakeQuantize1; + } + + const std::shared_ptr concat = std::make_shared( + ngraph::OutputVector{ fakeQuantize2->output(0), intermediateOp->output(0) }, + 1); + concat->set_friendly_name("concat"); + ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat, precisionAfterOperation); + + const auto deqAfter = makeDequantization(concat->output(0), dequantizationAfter); + deqAfter->set_friendly_name("concat"); + + ngraph::ResultVector results{ + std::make_shared(deqAfter) + }; + + std::shared_ptr function = std::make_shared( + results, + ngraph::ParameterVector{ input1, input2 }, + "ConcatWithIntermediateTransformation"); + + return function; +} + } // namespace subgraph } // namespace builder } // namespace ngraph From 4445ad25b49be62e21a2a43300a3d426c06f2ed5 Mon Sep 17 00:00:00 2001 From: Vladislav Golubev Date: Mon, 21 Sep 2020 20:12:58 +0300 Subject: [PATCH 2/2] [LPT] Clamp transformation: GPU tests fix --- .../clamp_transformation.cpp | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/clamp_transformation.cpp b/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/clamp_transformation.cpp index 95a27cf70ccefd..f873cd96c47919 100644 --- a/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/clamp_transformation.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/low_precision_transformations/clamp_transformation.cpp @@ -67,25 +67,19 @@ void ClampTransformation::validateNGraph() { std::shared_ptr parent = output->get_input_node_shared_ptr(0); ASSERT_FALSE(parent == nullptr); const std::string typeName = parent->get_type_name(); - if (params.updatePrecisions) { - if (!param.dequantizationAfter.empty()) { - EXPECT_EQ("ScaleShiftIE", typeName); - EXPECT_EQ(3, parent->get_input_size()); - - const auto expectedScale = param.dequantizationAfter.multiply.values; - const auto actualScale = - ngraph::as_type_ptr(parent->get_input_node_shared_ptr(1))->cast_vector(); - EXPECT_EQ(expectedScale.size(), actualScale.size()); - - const auto expectedShift = param.dequantizationAfter.subtract.values; - const auto actualShift = - ngraph::as_type_ptr(parent->get_input_node_shared_ptr(2))->cast_vector(); - EXPECT_EQ(expectedShift.size(), actualShift.size()); - } - } else { - if (!param.dequantizationAfter.empty()) { - EXPECT_EQ("ConvolutionIE", typeName); - } + if (!param.dequantizationAfter.empty()) { + EXPECT_EQ("ScaleShiftIE", typeName); + EXPECT_EQ(3, parent->get_input_size()); + + const auto expectedScale = param.dequantizationAfter.multiply.values; + const auto actualScale = + ngraph::as_type_ptr(parent->get_input_node_shared_ptr(1))->cast_vector(); + EXPECT_EQ(expectedScale.size(), actualScale.size()); + + const auto expectedShift = param.dequantizationAfter.subtract.values; + const auto actualShift = + ngraph::as_type_ptr(parent->get_input_node_shared_ptr(2))->cast_vector(); + EXPECT_EQ(expectedShift.size(), actualShift.size()); } }