From 818f385398310909ec69b7099f4ee055da310d19 Mon Sep 17 00:00:00 2001 From: Irina Efode Date: Mon, 27 Sep 2021 11:22:38 +0300 Subject: [PATCH 1/3] [IE TESTS] Add example for QueryNetwork in SLT (#7628) * [IE TESTS] Add example for QueryNetwork in SLT * Update mul_conv_fusion.cpp * Skip * skip[ --- .../skip_tests_config.cpp | 4 +++- .../include/single_layer_tests/activation.hpp | 12 ++++++++++++ .../subgraph_tests/split_conv_concat.hpp | 4 ++++ .../base/layer_test_utils.hpp | 2 ++ .../src/base/layer_test_utils.cpp | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/skip_tests_config.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/skip_tests_config.cpp index 8305e65ccae..e5ab5d90491 100644 --- a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/skip_tests_config.cpp +++ b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/skip_tests_config.cpp @@ -50,8 +50,10 @@ std::vector disabledTestPatterns() { R"(.*smoke_MemoryTest.*iteration_count=3.*IS=\(1.10\).*)", R"(.*smoke_MemoryTest.*iteration_count=4.*IS=\(1.10\).*)", R"(.*smoke_MemoryTest.*iteration_count=10.*IS=\(1.10\).*)", - R"(.*smoke_MemoryTest.*LOW_LATENCY.*iteration_count=10.*IS=\(1.2\).*)", + R"(.*smoke_MemoryTest.*LOW_LATENCY.*iteration_count=10.*IS=\(1.2\).*)",/**/ // CVS-58963: Not implemented yet R"(.*Behavior.*InferRequest.*OutOfFirstOutIsInputForSecondNetwork.*)", + // TODO: Issue: 29577 + R"(.*QueryNetwork.*)", }; } diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/activation.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/activation.hpp index afcc5f6db69..33fa23dfa26 100644 --- a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/activation.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/activation.hpp @@ -20,4 +20,16 @@ TEST_P(ActivationDynamicLayerTest, CompareWithRefs) { Run(); } +TEST_P(ActivationLayerTest, QueryNetwork) { + QueryNetwork(); +} + +TEST_P(ActivationParamLayerTest, QueryNetwork) { + QueryNetwork(); +} + +TEST_P(ActivationDynamicLayerTest, QueryNetwork) { + QueryNetwork(); +} + } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/split_conv_concat.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/split_conv_concat.hpp index 801ec46c6ce..81e9c3f1c9d 100644 --- a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/split_conv_concat.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/split_conv_concat.hpp @@ -12,4 +12,8 @@ TEST_P(SplitConvConcat, CompareWithRefImpl) { Run(); }; +TEST_P(SplitConvConcat, QueryNetwork) { + QueryNetwork(); +} + } // namespace SubgraphTestsDefinitions \ No newline at end of file diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp index 0fffe60ead7..52190783857 100644 --- a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/base/layer_test_utils.hpp @@ -57,6 +57,8 @@ public: virtual void Serialize(); + virtual void QueryNetwork(); + static void Compare(const std::vector>> &expected, const std::vector &actual, float threshold); diff --git a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp index af21f3a39b7..e318a36f6be 100644 --- a/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp +++ b/inference-engine/tests/functional/shared_test_classes/src/base/layer_test_utils.cpp @@ -90,6 +90,23 @@ void LayerTestsCommon::Serialize() { CommonTestUtils::removeIRFiles(out_xml_path, out_bin_path); } +void LayerTestsCommon::QueryNetwork() { + SKIP_IF_CURRENT_TEST_IS_DISABLED(); + cnnNetwork = InferenceEngine::CNNNetwork(function); + + auto queryNetworkResult = PluginCache::get().ie()->QueryNetwork(cnnNetwork, targetDevice); + std::set expected; + for (auto&& node : function->get_ops()) { + expected.insert(node->get_friendly_name()); + } + + std::set actual; + for (auto&& res : queryNetworkResult.supportedLayersMap) { + actual.insert(res.first); + } + ASSERT_EQ(expected, actual); +} + InferenceEngine::Blob::Ptr LayerTestsCommon::GenerateInput(const InferenceEngine::InputInfo &info) const { return FuncTestUtils::createAndFillBlob(info.getTensorDesc()); } From 7fa9bbf6fc5a94e312ffc0ef4748175fc8dbddd1 Mon Sep 17 00:00:00 2001 From: Vladislav Golubev Date: Mon, 27 Sep 2021 11:50:17 +0300 Subject: [PATCH 2/3] [LPT] Avoid using std::shared_ptr when creating a node (#7357) * [LPT] Avoid using std::shared_ptr when creating a node * [LPT] removed unused files * [LPT] D2STransformation: transform & isPrecisionPreserved methods are moved to base class * [LPT] Revert redundant changes --- .../include/low_precision/concat.hpp | 2 - .../include/low_precision/depth_to_space.hpp | 2 - .../transparent_base_transformation.hpp | 1 + .../low_precision_transformations/src/add.cpp | 4 +- .../operation_precision_restriction.cpp | 19 --- .../src/concat.cpp | 34 +---- .../src/convert.cpp | 2 +- .../src/convolution_backprop_data.cpp | 2 +- .../create_precisions_dependent_attribute.cpp | 22 ---- .../src/depth_to_space.cpp | 15 --- .../src/fake_quantize.cpp | 18 +-- .../src/fold_convert.cpp | 2 +- .../src/fuse_convert.cpp | 18 +-- .../src/fuse_fake_quantize.cpp | 15 ++- .../src/fuse_multiply_to_fake_quantize.cpp | 12 +- .../src/fuse_subtract_to_fake_quantize.cpp | 12 +- .../src/mat_mul.cpp | 2 +- .../src/multiply.cpp | 10 +- .../low_precision_transformations/src/mvn.cpp | 2 +- .../src/network_helper.cpp | 124 ++++++++---------- .../pull_reshape_through_dequantization.cpp | 16 +-- .../pull_transpose_through_dequantization.cpp | 14 +- .../src/reshape.cpp | 2 +- .../rt_info/intervals_alignment_attribute.cpp | 6 +- .../src/rt_info/shared_value_attribute.cpp | 16 --- .../src/squeeze.cpp | 2 +- .../src/strided_slice.cpp | 6 +- .../src/subtract.cpp | 14 +- .../src/transparent_base_transformation.cpp | 29 ++-- .../src/unsqueeze.cpp | 2 +- 30 files changed, 158 insertions(+), 267 deletions(-) delete mode 100644 inference-engine/src/low_precision_transformations/src/common/operation_precision_restriction.cpp delete mode 100644 inference-engine/src/low_precision_transformations/src/create_precisions_dependent_attribute.cpp delete mode 100644 inference-engine/src/low_precision_transformations/src/rt_info/shared_value_attribute.cpp diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/concat.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/concat.hpp index 65cb9694eb8..c1f752972ad 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/concat.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/concat.hpp @@ -39,8 +39,6 @@ protected: NodeVector& convertNodes, NodeVector& subtractNodes, NodeVector& multiplyNodes) const; - - std::shared_ptr concatenateDeqNodes(NodeVector& nodes) const; }; } // namespace low_precision diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/depth_to_space.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/depth_to_space.hpp index b02ead7321b..5a199454eb6 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/depth_to_space.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/depth_to_space.hpp @@ -14,8 +14,6 @@ class LP_TRANSFORMATIONS_API DepthToSpaceTransformation : public TransparentBase public: NGRAPH_RTTI_DECLARATION; DepthToSpaceTransformation(const Params& params = Params()); - bool transform(TransformationContext &context, ngraph::pattern::Matcher &m) override; - bool isPrecisionPreserved(std::shared_ptr layer) const noexcept override; bool canBeTransformed(const TransformationContext& context, std::shared_ptr layer) const override; }; diff --git a/inference-engine/src/low_precision_transformations/include/low_precision/transparent_base_transformation.hpp b/inference-engine/src/low_precision_transformations/include/low_precision/transparent_base_transformation.hpp index 05b0dbebc01..d1f87f92f86 100644 --- a/inference-engine/src/low_precision_transformations/include/low_precision/transparent_base_transformation.hpp +++ b/inference-engine/src/low_precision_transformations/include/low_precision/transparent_base_transformation.hpp @@ -18,6 +18,7 @@ public: ~TransparentBaseTransformation() override {}; bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override; bool canBeTransformed(const TransformationContext& context, std::shared_ptr layer) const override; + bool isPrecisionPreserved(std::shared_ptr layer) const noexcept override; }; } // namespace low_precision diff --git a/inference-engine/src/low_precision_transformations/src/add.cpp b/inference-engine/src/low_precision_transformations/src/add.cpp index da720928ff7..e4068c74a51 100644 --- a/inference-engine/src/low_precision_transformations/src/add.cpp +++ b/inference-engine/src/low_precision_transformations/src/add.cpp @@ -176,13 +176,13 @@ bool AddTransformation::transform(TransformationContext& context, ngraph::patter // after : Y = SC2 * ( SC1' * (X1 - SH1') + X2 ) , where : // SC1' = SC1 / SC2 // SH1' = SH1 + SC2 * SH2 / SC1 - std::shared_ptr newSubtractFullPathValues = fold( + auto newSubtractFullPathValues = fold( subtractFullPathValues, fold( fold(subtractEmptyPathValues, multiplyEmptyPathValues), multiplyFullPathValues)); - std::shared_ptr newMultiplyFullPathValues = fold(multiplyFullPathValues, multiplyEmptyPathValues); + auto newMultiplyFullPathValues = fold(multiplyFullPathValues, multiplyEmptyPathValues); if (NetworkHelper::isZeroConst(newSubtractFullPathValues)) { newSubtractFullPathValues = nullptr; diff --git a/inference-engine/src/low_precision_transformations/src/common/operation_precision_restriction.cpp b/inference-engine/src/low_precision_transformations/src/common/operation_precision_restriction.cpp deleted file mode 100644 index 0ec085d7245..00000000000 --- a/inference-engine/src/low_precision_transformations/src/common/operation_precision_restriction.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "low_precision/common/operation_precision_restriction.hpp" - -#include -#include -#include -#include - -#include -#include -#include -#include "low_precision/network_helper.hpp" -#include "low_precision/rt_info/precisions_attribute.hpp" - -using namespace ngraph; - diff --git a/inference-engine/src/low_precision_transformations/src/concat.cpp b/inference-engine/src/low_precision_transformations/src/concat.cpp index 8df69b6fb21..19d4f8daa37 100644 --- a/inference-engine/src/low_precision_transformations/src/concat.cpp +++ b/inference-engine/src/low_precision_transformations/src/concat.cpp @@ -70,20 +70,11 @@ bool ConcatTransformation::transform(TransformationContext& context, ngraph::pat } } - auto broadcastElementWiseConst = []( - // FakeQuantize constant shape must be broadcastable to the shape on data. - std::shared_ptr operation, - const ngraph::Shape targetShape) -> std::shared_ptr { - auto targetShapeConst = std::make_shared( - element::i64, ngraph::Shape{ targetShape.size() }, - targetShape); - - auto broadcast = ngraph::pass::low_precision::fold( - operation, - targetShapeConst, - ngraph::op::AutoBroadcastType::NUMPY); - - return broadcast; + // FakeQuantize constant shape must be broadcastable to the shape on data. + auto broadcastElementWiseConst = [](std::shared_ptr operation, const Shape targetShape) { + auto targetShapeConst = std::make_shared(element::i64, Shape{ targetShape.size() }, targetShape); + auto broadcast = fold(operation, targetShapeConst); + return broadcast; }; bool someDqInLowPrecision = std::any_of( @@ -247,15 +238,8 @@ void ConcatTransformation::fillDequantizationNodes( // FakeQuantize constant shape must be broadcastable to the shape on data. std::shared_ptr operation, const ngraph::Shape targetShape) -> std::shared_ptr { - auto targetShapeConst = std::make_shared( - element::i64, ngraph::Shape{ targetShape.size() }, - targetShape); - - auto broadcast = ngraph::pass::low_precision::fold( - operation, - targetShapeConst, - ngraph::op::AutoBroadcastType::NUMPY); - + auto targetShapeConst = opset1::Constant::create(element::i64, ngraph::Shape{ targetShape.size() }, targetShape); + auto broadcast = fold(operation, targetShapeConst); return broadcast; }; @@ -308,10 +292,6 @@ void ConcatTransformation::fillDequantizationNodes( } } -std::shared_ptr ConcatTransformation::concatenateDeqNodes(NodeVector& nodes) const { - return nodes.size() == 1ul ? nodes[0] : fold(nodes, 1); -} - bool ConcatTransformation::isHandled(const TransformationContext& context, const std::vector>& quantizationOperations) { for (const std::shared_ptr& quantizationLayer : quantizationOperations) { if (context.quantizedFakeQuantizeNames.find(quantizationLayer->get_friendly_name()) != context.quantizedFakeQuantizeNames.end()) { diff --git a/inference-engine/src/low_precision_transformations/src/convert.cpp b/inference-engine/src/low_precision_transformations/src/convert.cpp index fbc64e0db62..82c6982b59a 100644 --- a/inference-engine/src/low_precision_transformations/src/convert.cpp +++ b/inference-engine/src/low_precision_transformations/src/convert.cpp @@ -49,7 +49,7 @@ bool ConvertTransformation::transform(TransformationContext& context, ngraph::pa const ngraph::element::Type precisionBefore = convert->get_input_element_type(0); std::shared_ptr subtract = std::make_shared>( - convert->get_input_node_shared_ptr(0), + convert->input_value(0), std::make_shared(precisionBefore, Shape{}, std::vector({ 0 }))); NetworkHelper::setOutDataPrecision(subtract, convert->get_output_element_type(0)); diff --git a/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp b/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp index 7802a498a0e..cec1b73b9a0 100644 --- a/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp +++ b/inference-engine/src/low_precision_transformations/src/convolution_backprop_data.cpp @@ -181,7 +181,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con zeroPointShape[1] = static_cast(weightsPShape[1].get_length()); auto zeroPointConstant = fold( - subtractFromWeights->get_input_node_shared_ptr(1), + subtractFromWeights->input_value(1), std::make_shared(element::i32, Shape{zeroPointShape.size()}, zeroPointShape)); replace_node(subtractFromWeights->get_input_node_shared_ptr(1), zeroPointConstant); } diff --git a/inference-engine/src/low_precision_transformations/src/create_precisions_dependent_attribute.cpp b/inference-engine/src/low_precision_transformations/src/create_precisions_dependent_attribute.cpp deleted file mode 100644 index 7ddd060b06d..00000000000 --- a/inference-engine/src/low_precision_transformations/src/create_precisions_dependent_attribute.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "low_precision/create_precisions_dependent_attribute.hpp" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "low_precision/rt_info/precisions_attribute.hpp" -#include "low_precision/rt_info/precision_preserved_attribute.hpp" -#include "low_precision/network_helper.hpp" - -using namespace ngraph; -using namespace ngraph::pass::low_precision; diff --git a/inference-engine/src/low_precision_transformations/src/depth_to_space.cpp b/inference-engine/src/low_precision_transformations/src/depth_to_space.cpp index b5de8dd661c..4339ad33503 100644 --- a/inference-engine/src/low_precision_transformations/src/depth_to_space.cpp +++ b/inference-engine/src/low_precision_transformations/src/depth_to_space.cpp @@ -29,21 +29,6 @@ DepthToSpaceTransformation::DepthToSpaceTransformation(const Params& params) : T this->register_matcher(m, callback); } -bool DepthToSpaceTransformation::transform(TransformationContext &context, ngraph::pattern::Matcher &m) { - std::shared_ptr depthToSpace = m.get_match_root(); - if (!canBeTransformed(context, depthToSpace)) { - return false; - } - - depthToSpace = NetworkHelper::separateInStandaloneBranch(depthToSpace); - moveDequantizationAfter(context, depthToSpace, NetworkHelper::getDequantization(depthToSpace), true); - return true; -} - -bool DepthToSpaceTransformation::isPrecisionPreserved(std::shared_ptr layer) const noexcept { - return true; -} - bool DepthToSpaceTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr layer) const { if (!LayerTransformation::canBeTransformed(context, layer)) { return false; diff --git a/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp index b731ed22a63..deb7ec1ea28 100644 --- a/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fake_quantize.cpp @@ -67,7 +67,7 @@ static std::shared_ptr updateShape(std::shared_ptr constantOp, const return constantOp; } -static std::shared_ptr getData(const std::shared_ptr& eltwise) { +static std::shared_ptr getDataNode(const std::shared_ptr& eltwise) { if (!ov::is_type(eltwise->get_input_node_shared_ptr(0))) { return eltwise->get_input_node_shared_ptr(0); } @@ -123,7 +123,7 @@ bool FakeQuantizeTransformation::checkElementwise(const std::shared_ptr& e } } - return fq::getData(eltwise) != nullptr; + return fq::getDataNode(eltwise) != nullptr; } std::shared_ptr FakeQuantizeTransformation::fuseElementwise( @@ -132,8 +132,8 @@ std::shared_ptr FakeQuantizeTransformation::fuseElementwis const std::shared_ptr& fakeQuantize) const { const std::shared_ptr eltwise = fakeQuantize->get_input_node_shared_ptr(0); - std::shared_ptr inputLowConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(1), deqPrecision); - std::shared_ptr inputHighConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(2), deqPrecision); + std::shared_ptr inputLowConst_f32 = foldConvert(fakeQuantize->input_value(1), deqPrecision); + std::shared_ptr inputHighConst_f32 = foldConvert(fakeQuantize->input_value(2), deqPrecision); std::shared_ptr constant = fq::getConstant(eltwise); if (ov::is_type(eltwise) && checkElementwise(eltwise)) { @@ -166,10 +166,10 @@ std::shared_ptr FakeQuantizeTransformation::fuseElementwis inputLowConst_f32 = fq::updateShape(fold(inputLowConst_f32, value), fakeQuantize->get_output_partial_shape(0)); inputHighConst_f32 = fq::updateShape(fold(inputHighConst_f32, value), fakeQuantize->get_output_partial_shape(0)); } else if (ov::is_type(eltwise) && checkElementwise(eltwise)) { - if (ov::is_type(fq::getData(eltwise)) || - ov::is_type(fq::getData(eltwise)) || - ov::is_type(fq::getData(eltwise)) || - ov::is_type(fq::getData(eltwise))) { + if (ov::is_type(fq::getDataNode(eltwise)) || + ov::is_type(fq::getDataNode(eltwise)) || + ov::is_type(fq::getDataNode(eltwise)) || + ov::is_type(fq::getDataNode(eltwise))) { return nullptr; } @@ -189,7 +189,7 @@ std::shared_ptr FakeQuantizeTransformation::fuseElementwis return nullptr; } - const auto data = fq::getData(eltwise); + const auto data = fq::getDataNode(eltwise); const size_t outputIdx = NetworkHelper::getParentOutputIndex(data, eltwise); const auto newFakeQuantize = ov::as_type_ptr(fakeQuantize->clone_with_new_inputs({ diff --git a/inference-engine/src/low_precision_transformations/src/fold_convert.cpp b/inference-engine/src/low_precision_transformations/src/fold_convert.cpp index f7a3255df49..d17ac6e1a82 100644 --- a/inference-engine/src/low_precision_transformations/src/fold_convert.cpp +++ b/inference-engine/src/low_precision_transformations/src/fold_convert.cpp @@ -42,7 +42,7 @@ bool FoldConvertTransformation::transform(TransformationContext& context, ngraph return; } - const auto resultConstant = ngraph::pass::low_precision::foldConvert(convert->get_input_node_shared_ptr(0), convert->output(0).get_element_type()); + const auto resultConstant = ngraph::pass::low_precision::foldConvert(convert->input_value(0), convert->get_output_element_type(0)); assert(ov::is_type(resultConstant)); replace_node(convert, resultConstant); diff --git a/inference-engine/src/low_precision_transformations/src/fuse_convert.cpp b/inference-engine/src/low_precision_transformations/src/fuse_convert.cpp index 3533bb66213..07f56f8b572 100644 --- a/inference-engine/src/low_precision_transformations/src/fuse_convert.cpp +++ b/inference-engine/src/low_precision_transformations/src/fuse_convert.cpp @@ -47,8 +47,8 @@ std::shared_ptr removeConvertIfPossibleForSubtract( if (NetworkHelper::checkConstantValuePrecision(precisionBeforeConvert, subtract->get_input_node_shared_ptr(1))) { newSubtract = std::make_shared>( std::vector{ element::f32, element::f32 }, std::vector{}, - ngraph::op::TemporaryReplaceOutputType(convert->get_input_source_output(0), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(subtract->get_input_node_shared_ptr(1), element::f32).get()); + ngraph::op::TemporaryReplaceOutputType(convert->input_value(0), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(subtract->input_value(1), element::f32).get()); NetworkHelper::setOutDataPrecisionForTypeRelaxed(newSubtract, subtract->get_output_element_type(0)); replace_node(subtract, newSubtract); } @@ -63,11 +63,11 @@ bool FuseConvertTransformation::transform(TransformationContext& context, ngraph } const auto convert = ov::as_type_ptr(op->get_input_node_shared_ptr(0)); - std::shared_ptr parent = convert->get_input_node_shared_ptr(0); + auto parent = convert->input_value(0); - if (ov::is_type(parent)) { + if (ov::is_type(parent.get_node_shared_ptr())) { auto convertedConstant = foldConvert(parent, convert->get_convert_element_type()); - NetworkHelper::copyInfo(parent, convertedConstant); + NetworkHelper::copyInfo(parent.get_node_shared_ptr(), convertedConstant); replace_node(convert, convertedConstant); } else { std::shared_ptr newOp; @@ -77,15 +77,15 @@ bool FuseConvertTransformation::transform(TransformationContext& context, ngraph } else if (ov::is_type(op)) { newOp = std::make_shared>( std::vector{ element::f32, element::f32 }, std::vector{}, - ngraph::op::TemporaryReplaceOutputType(convert->get_input_source_output(0), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(op->get_input_node_shared_ptr(1), element::f32).get()); + ngraph::op::TemporaryReplaceOutputType(convert->input_value(0), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(op->input_value(1), element::f32).get()); NetworkHelper::setOutDataPrecisionForTypeRelaxed(newOp, op->get_output_element_type(0)); replace_node(op, newOp); } else if (ov::is_type(op)) { newOp = std::make_shared>( std::vector{ element::f32, element::f32 }, std::vector{}, - ngraph::op::TemporaryReplaceOutputType(convert->get_input_source_output(0), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(op->get_input_node_shared_ptr(1), element::f32).get()); + ngraph::op::TemporaryReplaceOutputType(convert->input_value(0), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(op->input_value(1), element::f32).get()); NetworkHelper::setOutDataPrecisionForTypeRelaxed(newOp, op->get_output_element_type(0)); replace_node(op, newOp); } diff --git a/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp index 0c897f468a5..bb59172ff3a 100644 --- a/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fuse_fake_quantize.cpp @@ -54,7 +54,7 @@ std::shared_ptr updateShape(std::shared_ptr op, const PartialShape& return op; } -std::shared_ptr getData(const std::shared_ptr& eltwise) { +std::shared_ptr getDataNode(const std::shared_ptr& eltwise) { if (!ov::is_type(eltwise->get_input_node_shared_ptr(0))) { return eltwise->get_input_node_shared_ptr(0); } @@ -108,7 +108,7 @@ bool eltwiseWithConstant(const std::shared_ptr& eltwise) { } } - return getData(eltwise) != nullptr; + return getDataNode(eltwise) != nullptr; } } // namespace fuse_fq @@ -144,8 +144,8 @@ std::shared_ptr FuseFakeQuantizeTransformation::handle( inputLowConst = fuse_fq::updateShape(fold(inputLowConst, value), fakeQuantize->get_output_partial_shape(0)); inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (ov::is_type(eltwise) && fuse_fq::eltwiseWithConstant(eltwise)) { - if (ov::is_type(fuse_fq::getData(eltwise)) || - ov::is_type(fuse_fq::getData(eltwise))) { + if (ov::is_type(fuse_fq::getDataNode(eltwise)) || + ov::is_type(fuse_fq::getDataNode(eltwise))) { return nullptr; } @@ -157,15 +157,18 @@ std::shared_ptr FuseFakeQuantizeTransformation::handle( inputHightConst = fuse_fq::updateShape(fold(inputHightConst, value), fakeQuantize->get_output_partial_shape(0)); } else if (ov::is_type(eltwise)) { // issue #40611 - if ((eltwise->input(0).get_element_type() == element::i32) && (eltwise->output(0).get_element_type() == element::f32)) { + if ((eltwise->get_input_element_type(0) == element::i32) && (eltwise->get_output_element_type(0) == element::f32)) { return nullptr; } } else { return nullptr; } + const auto data = fuse_fq::getDataNode(eltwise); + const size_t outputIdx = NetworkHelper::getParentOutputIndex(data, eltwise); + std::shared_ptr newFakeQuantize = ov::as_type_ptr(fakeQuantize->clone_with_new_inputs({ - fuse_fq::getData(eltwise), + data->output(outputIdx), inputLowConst, inputHightConst, fakeQuantize->input_value(3), diff --git a/inference-engine/src/low_precision_transformations/src/fuse_multiply_to_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fuse_multiply_to_fake_quantize.cpp index 3cab73ba3e9..9d48b5a23f3 100644 --- a/inference-engine/src/low_precision_transformations/src/fuse_multiply_to_fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fuse_multiply_to_fake_quantize.cpp @@ -46,9 +46,12 @@ bool FuseMultiplyToFakeQuantizeTransformation::transform(TransformationContext& } const auto multiplyConstant = multiply->get_input_node_shared_ptr(1); + if (!ov::is_type(multiplyConstant)) { + return false; + } - auto outputLowConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(3), deqPrecision); - auto outputHighConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(4), deqPrecision); + auto outputLowConst_f32 = foldConvert(fakeQuantize->input_value(3), deqPrecision); + auto outputHighConst_f32 = foldConvert(fakeQuantize->input_value(4), deqPrecision); const auto value = multiplyConstant->get_output_element_type(0) == element::f32 ? multiplyConstant : @@ -57,9 +60,6 @@ bool FuseMultiplyToFakeQuantizeTransformation::transform(TransformationContext& outputLowConst_f32 = fold(outputLowConst_f32, value); outputHighConst_f32 = fold(outputHighConst_f32, value); - const auto fakeQuantizeParent = fakeQuantize->get_input_node_shared_ptr(0); - const size_t parentIndex = NetworkHelper::getParentOutputIndex(fakeQuantizeParent, fakeQuantize); - const auto inputLow = foldConvert(fakeQuantize->input_value(1), deqPrecision); const auto inputHigh = foldConvert(fakeQuantize->input_value(2), deqPrecision); NetworkHelper::copyInfo(fakeQuantize->get_input_node_shared_ptr(1), inputLow); @@ -69,7 +69,7 @@ bool FuseMultiplyToFakeQuantizeTransformation::transform(TransformationContext& auto newFakeQuantize = std::make_shared>( opset1::FakeQuantize( - fakeQuantizeParent->output(parentIndex), + fakeQuantize->input_value(0), inputLow, inputHigh, outputLowConst_f32, diff --git a/inference-engine/src/low_precision_transformations/src/fuse_subtract_to_fake_quantize.cpp b/inference-engine/src/low_precision_transformations/src/fuse_subtract_to_fake_quantize.cpp index edd8ee35cb4..d4e1aafee4c 100644 --- a/inference-engine/src/low_precision_transformations/src/fuse_subtract_to_fake_quantize.cpp +++ b/inference-engine/src/low_precision_transformations/src/fuse_subtract_to_fake_quantize.cpp @@ -45,9 +45,12 @@ bool FuseSubtractToFakeQuantizeTransformation::transform(TransformationContext& } const auto subtractConstant = subtract->get_input_node_shared_ptr(1); + if (!ov::is_type(subtractConstant)) { + return false; + } - auto outputLowConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(3), deqPrecision); - auto outputHighConst_f32 = foldConvert(fakeQuantize->get_input_node_shared_ptr(4), deqPrecision); + auto outputLowConst_f32 = foldConvert(fakeQuantize->input_value(3), deqPrecision); + auto outputHighConst_f32 = foldConvert(fakeQuantize->input_value(4), deqPrecision); const auto value = subtractConstant->get_output_element_type(0) == element::f32 ? subtractConstant : @@ -56,9 +59,6 @@ bool FuseSubtractToFakeQuantizeTransformation::transform(TransformationContext& outputLowConst_f32 = fold(outputLowConst_f32, value); outputHighConst_f32 = fold(outputHighConst_f32, value); - const auto fakeQuantizeParent = fakeQuantize->get_input_node_shared_ptr(0); - const size_t parentIndex = NetworkHelper::getParentOutputIndex(fakeQuantizeParent, fakeQuantize); - const auto inputLow = foldConvert(fakeQuantize->input_value(1), deqPrecision); const auto inputHigh = foldConvert(fakeQuantize->input_value(2), deqPrecision); NetworkHelper::copyInfo(fakeQuantize->get_input_node_shared_ptr(1), inputLow); @@ -68,7 +68,7 @@ bool FuseSubtractToFakeQuantizeTransformation::transform(TransformationContext& auto newFakeQuantize = std::make_shared>( opset1::FakeQuantize( - fakeQuantizeParent->output(parentIndex), + fakeQuantize->input_value(0), inputLow, inputHigh, outputLowConst_f32, diff --git a/inference-engine/src/low_precision_transformations/src/mat_mul.cpp b/inference-engine/src/low_precision_transformations/src/mat_mul.cpp index 6b0a1cdfeca..9d9fd8ecce0 100644 --- a/inference-engine/src/low_precision_transformations/src/mat_mul.cpp +++ b/inference-engine/src/low_precision_transformations/src/mat_mul.cpp @@ -109,7 +109,7 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat // multiply by weights: [1, ..., 1, Y] x [Y, Z] => [1, ..., 1, Z] const auto newSubConst = NetworkHelper::toScalarIfPossible(fold( broadcastedConst, - foldConvert(newMatMul->get_input_node_shared_ptr(1), newMatMul->get_element_type()), + foldConvert(newMatMul->input_value(1), newMatMul->get_element_type()), newMatMul->get_transpose_a(), newMatMul->get_transpose_b())); diff --git a/inference-engine/src/low_precision_transformations/src/multiply.cpp b/inference-engine/src/low_precision_transformations/src/multiply.cpp index ea713ee6b27..68792d2d3c7 100644 --- a/inference-engine/src/low_precision_transformations/src/multiply.cpp +++ b/inference-engine/src/low_precision_transformations/src/multiply.cpp @@ -77,10 +77,10 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p return false; } - auto multiplyParent = multiply->get_input_source_output(multiplyBranch.first); - auto constParent = multiply->get_input_source_output(multiplyBranch.first == 0 ? 1 : 0); - auto multiplyParentParent = multiplyParent.get_node_shared_ptr()->get_input_source_output(multiplyBranch.second); - auto multiplyParentConst = multiplyParent.get_node_shared_ptr()->get_input_source_output(multiplyBranch.second == 0 ? 1 : 0); + auto multiplyParent = multiply->input_value(multiplyBranch.first); + auto constParent = multiply->input_value(multiplyBranch.first == 0 ? 1 : 0); + auto multiplyParentParent = multiplyParent.get_node_shared_ptr()->input_value(multiplyBranch.second); + auto multiplyParentConst = multiplyParent.get_node_shared_ptr()->input_value(multiplyBranch.second == 0 ? 1 : 0); newMultiply = std::make_shared>( std::vector{ element::f32, element::f32 }, @@ -127,7 +127,7 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p // before: Y = (SC1 * (X1 - SH1)) * (SC2 * X2) // after : Y = (SC1' * (X1 - SH1)) * (X2) , where : // SC1' = SC1 * SC2 - std::shared_ptr newMultiplyValuesFullPath = fold(multiplyValuesEmptyPath, multiplyValuesFullPath); + auto newMultiplyValuesFullPath = fold(multiplyValuesEmptyPath, multiplyValuesFullPath); OutputVector inputs{ {}, {} }; inputs[emptyPathIndex] = dequantizationEmptyPath.data; inputs[fullPathIndex] = std::make_shared( diff --git a/inference-engine/src/low_precision_transformations/src/mvn.cpp b/inference-engine/src/low_precision_transformations/src/mvn.cpp index 34f43655604..72ca086ced5 100644 --- a/inference-engine/src/low_precision_transformations/src/mvn.cpp +++ b/inference-engine/src/low_precision_transformations/src/mvn.cpp @@ -149,7 +149,7 @@ bool MVNTransformation::transform(TransformationContext &context, ngraph::patter if (ov::is_type(mvn)) { newMVN = mvn->copy_with_new_inputs({dequantization.data}); } else { - newMVN = mvn->copy_with_new_inputs({dequantization.data, mvn->get_input_node_shared_ptr(1)}); + newMVN = mvn->copy_with_new_inputs({dequantization.data, mvn->input_value(1)}); } NetworkHelper::setOutDataPrecisionForTypeRelaxed(newMVN, deqPrecision); NetworkHelper::copyInfo(mvn, newMVN); diff --git a/inference-engine/src/low_precision_transformations/src/network_helper.cpp b/inference-engine/src/low_precision_transformations/src/network_helper.cpp index 6d38a1ba5f8..e026fe015c3 100644 --- a/inference-engine/src/low_precision_transformations/src/network_helper.cpp +++ b/inference-engine/src/low_precision_transformations/src/network_helper.cpp @@ -233,10 +233,10 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptrget_input_source_output(multiplyInputBranch); - auto a = multiply->get_input_node_shared_ptr(multiplyInputBranch == 0 ? 1 : 0); - auto b = addAfterMultiply->get_input_node_shared_ptr(multiplyBranch == 0 ? 1 : 0); - std::shared_ptr bDivA; + const auto x = multiply->input_value(multiplyInputBranch); + auto a = as_type_ptr(multiply->get_input_node_shared_ptr(multiplyInputBranch == 0 ? 1 : 0)); + auto b = as_type_ptr(addAfterMultiply->get_input_node_shared_ptr(multiplyBranch == 0 ? 1 : 0)); + std::shared_ptr bDivA; const auto aPShape = a->get_output_partial_shape(0); assert(aPShape.is_static()); @@ -248,8 +248,8 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptr bValues = ov::as_type_ptr(b)->cast_vector(); - const std::vector aValues = ov::as_type_ptr(a)->cast_vector(); + const std::vector bValues = b->cast_vector(); + const std::vector aValues = a->cast_vector(); const bool aBroadcasted = bValues.size() > aValues.size(); const bool bBroadcasted = bValues.size() < aValues.size(); std::vector bDivAValues(aBroadcasted ? bValues.size() : aValues.size()); @@ -271,16 +271,16 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptr(b, a); + b = as_type_ptr(foldConvert(b->output(0), element::f32)); + a = as_type_ptr(foldConvert(a->output(0), element::f32)); + bDivA = as_type_ptr(fold(b->output(0), a->output(0))); // TODO: issue #49868 - bDivA = foldConvert(bDivA, a->get_output_element_type(0)); + bDivA = as_type_ptr(foldConvert(bDivA->output(0), a->get_element_type())); } OutputVector inputs{ {}, {} }; inputs[0] = x; - inputs[1] = bDivA; + inputs[1] = bDivA->output(0); std::shared_ptr newAdd = std::make_shared>( std::vector{element::f32, element::f32}, @@ -292,8 +292,8 @@ std::shared_ptr NetworkHelper::swapMultiplyAndAdd(std::shared_ptr>( std::vector{element::f32, element::f32}, std::vector{ multiply->get_output_element_type(0) }, - ngraph::op::TemporaryReplaceOutputType(newAdd, element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(a, element::f32).get()); + ngraph::op::TemporaryReplaceOutputType(newAdd->output(0), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(a->output(0), element::f32).get()); copyInfo({ multiply, newMultiply }, newMultiply); replace_node(addAfterMultiply, newMultiply); @@ -460,7 +460,7 @@ std::shared_ptr NetworkHelper::optimizeMultipliesAfter } auto newInput = multiply->input_value(1 - constant1->output(0).get_target_inputs().begin()->get_index()); - auto multiplyResult = fold(constant1, constant2); + auto multiplyResult = fold(constant1->output(0), constant2->output(0)); { // optimize constant shape: used in rfcn-resnet101-coco const auto multiplyResultConstant = ov::as_type_ptr(multiplyResult); @@ -526,13 +526,13 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p } if (dequantization.subtract != nullptr) { - if (dequantization.subtract->input(0).get_element_type() != dequantization.subtract->input(1).get_element_type()) { + if (dequantization.subtract->get_input_element_type(0) != dequantization.subtract->get_input_element_type(1)) { return dequantization; } if (dequantization.subtractConvert != nullptr) { const auto convertionResult = foldConvert( - dequantization.subtractConstant, + dequantization.subtractConstant->output(0), dequantization.subtractConvert->get_element_type()); if (ov::is_type(convertionResult)) { replace_node(dequantization.subtractConvert, convertionResult); @@ -541,8 +541,8 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p } const std::shared_ptr result = fold( - dequantization.subtract->get_input_node_shared_ptr(0), - dequantization.subtract->get_input_node_shared_ptr(1)); + dequantization.subtract->input_value(0), + dequantization.subtract->input_value(1)); if (ov::is_type(result)) { if (inPlace) { copyInfo(dequantization.subtract, result); @@ -555,18 +555,18 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p } if (dequantization.multiply != nullptr) { - if (dequantization.multiply->input(0).get_element_type() != dequantization.multiply->input(1).get_element_type()) { + if (dequantization.multiply->get_input_element_type(0) != dequantization.multiply->get_input_element_type(1)) { return dequantization; } std::shared_ptr result = fold( - dequantization.multiply->get_input_node_shared_ptr(0), - dequantization.multiply->get_input_node_shared_ptr(1)); + dequantization.multiply->input_value(0), + dequantization.multiply->input_value(1)); if (!ov::is_type(result)) { return dequantization; } if (dequantization.multiply->get_output_element_type(0) != result->get_element_type()) { - result = foldConvert(result, dequantization.multiply->get_output_element_type(0)); + result = foldConvert(result->output(0), dequantization.multiply->get_output_element_type(0)); } if (inPlace) { copyInfo(dequantization.multiply, result); @@ -599,7 +599,7 @@ std::shared_ptr NetworkHelper::separateInStandaloneBranch(std::sha outputs.push_back(input.get_source_output()); } - auto subtract = dequantization.subtract->clone_with_new_inputs({parent, parentOnWeights->clone_with_new_inputs(outputs) }); + auto subtract = dequantization.subtract->clone_with_new_inputs({parent, parentOnWeights->clone_with_new_inputs(outputs)->output(0) }); subtract->set_friendly_name(""); copy_runtime_info(parent.get_node_shared_ptr(), subtract); parent = subtract->output(0); @@ -608,7 +608,7 @@ std::shared_ptr NetworkHelper::separateInStandaloneBranch(std::sha if (dequantization.multiply != nullptr) { auto multiply = dequantization.multiply->clone_with_new_inputs({ parent, - dequantization.multiply->get_input_node_shared_ptr(1)->clone_with_new_inputs({}) }); + dequantization.multiply->get_input_node_shared_ptr(1)->clone_with_new_inputs({})->output(0) }); multiply->set_friendly_name(""); copy_runtime_info(parent.get_node_shared_ptr(), multiply); parent = multiply->output(0); @@ -650,11 +650,11 @@ std::shared_ptr NetworkHelper::fuseConvert(const std::shar std::shared_ptr newFakeQuantize = std::make_shared>( std::vector{ element::f32, element::f32, element::f32, element::f32, element::f32 }, std::vector{}, - ngraph::op::TemporaryReplaceOutputType(fakeQuantize->get_input_node_shared_ptr(0), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(fakeQuantize->get_input_node_shared_ptr(1), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(fakeQuantize->get_input_node_shared_ptr(2), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(fakeQuantize->get_input_node_shared_ptr(3), element::f32).get(), - ngraph::op::TemporaryReplaceOutputType(fakeQuantize->get_input_node_shared_ptr(4), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(fakeQuantize->input_value(0), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(fakeQuantize->input_value(1), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(fakeQuantize->input_value(2), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(fakeQuantize->input_value(3), element::f32).get(), + ngraph::op::TemporaryReplaceOutputType(fakeQuantize->input_value(4), element::f32).get(), fakeQuantize->get_levels()); NetworkHelper::setOutDataPrecisionForTypeRelaxed(newFakeQuantize, node->get_output_element_type(0)); replace_node(node->shared_from_this(), newFakeQuantize); @@ -889,14 +889,14 @@ std::shared_ptr NetworkHelper::composeFakeQuantize(const s if (dequantization.subtract != nullptr) { const auto subtractValue = (dequantization.subtractConvert == nullptr) ? dequantization.subtractConstant : - foldConvert(dequantization.subtractConstant, dequantization.subtractConvert->output(0).get_element_type()); + foldConvert(dequantization.subtractConstant->output(0), dequantization.subtractConvert->get_destination_type()); const std::shared_ptr replacement = std::make_shared>( newFakeQuantize->input_value(0), newFakeQuantize->input_value(1), newFakeQuantize->input_value(2), - fold(newFakeQuantize->get_input_node_shared_ptr(3), subtractValue), - fold(newFakeQuantize->get_input_node_shared_ptr(4), subtractValue), + fold(newFakeQuantize->input_value(3), subtractValue), + fold(newFakeQuantize->input_value(4), subtractValue), newFakeQuantize->get_levels(), newFakeQuantize->get_auto_broadcast()); replace_node(dequantization.subtract, replacement); @@ -907,11 +907,9 @@ std::shared_ptr NetworkHelper::composeFakeQuantize(const s if (dequantization.multiply != nullptr) { // multiply different precision constants (value1 & value2) and convert result to first argument precision (value1) - auto multiply = []( - const std::shared_ptr& value1, - const std::shared_ptr& value2) -> std::shared_ptr { - const ngraph::element::Type precision1 = value1->output(0).get_element_type(); - const ngraph::element::Type precision2 = value2->output(0).get_element_type(); + auto multiply = [](const Output& value1, const Output& value2) { + const ngraph::element::Type precision1 = value1.get_element_type(); + const ngraph::element::Type precision2 = value2.get_element_type(); // 1) precision1 & precision2 are not equal but similar // 2) precision2 >= precision1 assert((precision2.is_real() == precision1.is_real()) && (precision2.bitwidth() >= precision1.bitwidth())); @@ -921,7 +919,7 @@ std::shared_ptr NetworkHelper::composeFakeQuantize(const s value2); if (output->output(0).get_element_type() != precision1) { - output = foldConvert(output, precision1); + output = foldConvert(output->output(0), precision1); } return output; @@ -931,8 +929,8 @@ std::shared_ptr NetworkHelper::composeFakeQuantize(const s newFakeQuantize->input_value(0ul), newFakeQuantize->input_value(1ul), newFakeQuantize->input_value(2ul), - multiply(newFakeQuantize->get_input_node_shared_ptr(3ul), dequantization.multiplyConstant), - multiply(newFakeQuantize->get_input_node_shared_ptr(4ul), dequantization.multiplyConstant), + multiply(newFakeQuantize->input_value(3ul), dequantization.multiplyConstant), + multiply(newFakeQuantize->input_value(4ul), dequantization.multiplyConstant), newFakeQuantize->get_levels(), newFakeQuantize->get_auto_broadcast()); @@ -956,8 +954,6 @@ std::tuple, std::shared_ptr> NetworkHelper::decompos const bool updatePrecision, const element::Type deqPrecision, const size_t outChannelsShapeIndex) { - using std::make_shared; - const auto outputLow = fq->input_value(3); const auto outputHigh = fq->input_value(4); @@ -1015,8 +1011,8 @@ std::tuple, std::shared_ptr> NetworkHelper::decompos nullptr; std::shared_ptr scale = std::make_shared(element::f32, outputLow.get_shape(), scales); - auto newMin = make_shared(outputLow.get_element_type(), outputLow.get_shape(), minValues); - auto newMax = make_shared(outputLow.get_element_type(), outputLow.get_shape(), maxValues); + auto newMin = std::make_shared(outputLow.get_element_type(), outputLow.get_shape(), minValues); + auto newMax = std::make_shared(outputLow.get_element_type(), outputLow.get_shape(), maxValues); if (isScalarLike(newMin)) { newMin = toScalar(newMin); @@ -1072,7 +1068,7 @@ std::tuple, std::shared_ptr> NetworkHelper::decompos std::shared_ptr newFqConstant = ov::as_type_ptr(newFQ); if (ov::is_type(newFQ)) { - convert = foldConvert(newFQ, precision); + convert = foldConvert(newFQ->output(0), precision); } else if (ov::is_type(newFQ)) { newFQ = setOutDataPrecision(ov::as_type_ptr(newFQ), precision); convert = newFQ; @@ -1192,11 +1188,9 @@ FakeQuantizeDequantization NetworkHelper::createDequantizationFromFakeQuantize( const bool hasZeroPoint, const bool updatePrecision, const element::Type deqPrecision) { - using std::make_shared; - const ngraph::element::Type_t fqPrecision = fq->get_output_element_type(0); - auto newMin = make_shared(fqPrecision, Shape{}, min); - auto newMax = make_shared(fqPrecision, Shape{}, max); + auto newMin = std::make_shared(fqPrecision, Shape{}, min); + auto newMax = std::make_shared(fqPrecision, Shape{}, max); auto outputLow = fq->input_value(3); auto outputHigh = fq->input_value(4); @@ -1205,12 +1199,12 @@ FakeQuantizeDequantization NetworkHelper::createDequantizationFromFakeQuantize( const std::shared_ptr scale = ov::as_type_ptr(foldConvert(fold( fold(outputHigh, outputLow), - fold(newMax, newMin)), deqPrecision)); + fold(newMax->output(0), newMin->output(0))), deqPrecision)); assert(scale != nullptr); std::shared_ptr shift = hasZeroPoint ? ov::as_type_ptr(foldConvert(fold( - fold(fold(newMin, outputHigh), fold(newMax, outputLow)), + fold(fold(newMin->output(0), outputHigh), fold(newMax->output(0), outputLow)), fold(outputHigh, outputLow)), deqPrecision)) : nullptr; assert((!hasZeroPoint) || (hasZeroPoint && shift != nullptr)); @@ -1240,7 +1234,7 @@ FakeQuantizeDequantization NetworkHelper::createDequantizationFromFakeQuantize( std::shared_ptr subtract; if (shift != nullptr) { - subtract = make_shared>(parent, shift); + subtract = std::make_shared>(parent, shift); subtract->set_output_type(0, deqPrecision, subtract->get_output_partial_shape(0)); parent = subtract; } else { @@ -1416,16 +1410,16 @@ FakeQuantizeDequantization NetworkHelper::normalizeDequantization(FakeQuantizeDe return dequantization; } if (dequantization.multiply != nullptr && ov::as_type_ptr(dequantization.multiply->get_input_node_shared_ptr(0))) { - std::shared_ptr leftParent = dequantization.multiply->get_input_node_shared_ptr(0); - std::shared_ptr rightParent = dequantization.multiply->get_input_node_shared_ptr(1); + const auto leftParent = dequantization.multiply->input_value(0); + const auto rightParent = dequantization.multiply->input_value(1); std::shared_ptr normalized_multiply = ov::as_type_ptr( dequantization.multiply->clone_with_new_inputs({rightParent, leftParent})); replace_node(dequantization.multiply, normalized_multiply); dequantization.multiply = normalized_multiply; } if (dequantization.subtract != nullptr && ov::as_type_ptr(dequantization.subtract->get_input_node_shared_ptr(0))) { - std::shared_ptr leftParent = dequantization.subtract->get_input_node_shared_ptr(0); - std::shared_ptr rightParent = dequantization.subtract->get_input_node_shared_ptr(1); + const auto leftParent = dequantization.subtract->input_value(0); + const auto rightParent = dequantization.subtract->input_value(1); std::shared_ptr normalized_subtract = ov::as_type_ptr( dequantization.subtract->clone_with_new_inputs({rightParent, leftParent})); replace_node(dequantization.subtract, normalized_subtract); @@ -1452,7 +1446,7 @@ std::shared_ptr NetworkHelper::normalizeDequantizationShape(co std::iota(unsqueezeConstantShape.begin(), unsqueezeConstantShape.end(), 0ul); const auto newConstant = fold( - constant, + constant->output(0), op::Constant::create(element::i32, Shape{ unsqueezeConstantShape.size() }, unsqueezeConstantShape)); return ov::as_type_ptr(newConstant); @@ -1471,13 +1465,13 @@ std::shared_ptr NetworkHelper::normalizeDequantizationShape(co FakeQuantizeDequantizationValues NetworkHelper::createEmptyValues(const FakeQuantizeDequantization& dequantization, const element::Type precision) { const std::shared_ptr multiplyConstant = dequantization.multiply ? dequantization.multiplyConstant->get_element_type() != precision ? - foldConvert(dequantization.multiplyConstant, precision) : + foldConvert(dequantization.multiplyConstant->output(0), precision) : dequantization.multiplyConstant : std::make_shared(precision, Shape({}), std::vector({ 1.f })); const std::shared_ptr subtractConstant = dequantization.subtract ? dequantization.subtractConstant->get_element_type() != precision ? - foldConvert(dequantization.subtractConstant, precision) : + foldConvert(dequantization.subtractConstant->output(0), precision) : dequantization.subtractConstant : std::make_shared(precision, Shape({}), std::vector({ 0.f })); @@ -1538,7 +1532,7 @@ std::shared_ptr NetworkHelper::optimizeSubtract(std::shared_ptr>(data, roundedShift); + replacement = std::make_shared>(data, roundedShift->output(0)); NetworkHelper::copyInfo(subtract, replacement); NetworkHelper::setOutDataPrecisionForTypeRelaxed(replacement, convertOutputType); replace_node(subtract, replacement); @@ -1546,7 +1540,7 @@ std::shared_ptr NetworkHelper::optimizeSubtract(std::shared_ptr(subtractParent) && ov::is_type(subtractParent->get_input_node_shared_ptr(0))) { - auto replacement = std::make_shared>(data, subtractParent->get_input_node_shared_ptr(0)); + auto replacement = std::make_shared>(data, subtractParent->input_value(0)); NetworkHelper::copyInfo(subtract, replacement); NetworkHelper::setOutDataPrecisionForTypeRelaxed(replacement, convertOutputType); replace_node(subtract, replacement); @@ -1569,11 +1563,9 @@ NetworkHelper::InsertDequantizationResult NetworkHelper::moveDequantizationAfter (NetworkHelper::getDequantization(operation).multiplyConstant == nullptr) || (NetworkHelper::getDequantization(operation).multiplyConstant.get() == dequantization.multiplyConstant.get())); - std::vector> inputs(operation->get_input_size()); - for (size_t i = 0; i < operation->get_input_size(); ++i) { - inputs[i] = operation->get_input_node_shared_ptr(i); - } + assert(operation->get_output_size() == 1); + OutputVector inputs = operation->input_values(); const size_t dequantizationIndex = getChildInputIndex(dequantization.multiply, operation); inputs[dequantizationIndex] = moveSubtract ? dequantization.data : @@ -1623,7 +1615,7 @@ NetworkHelper::InsertDequantizationResult NetworkHelper::moveDequantizationAfter ngraph::op::TemporaryReplaceOutputType( dequantization.subtractConstant->output(0).get_element_type() == parentPrecision ? dequantization.subtractConstant : - foldConvert(dequantization.subtractConstant, parentPrecision), element::f32).get()); + foldConvert(dequantization.subtractConstant->output(0), parentPrecision), element::f32).get()); ngraph::copy_runtime_info({ newOperation, parent }, parent); } else { parent = std::make_shared(parent, dequantization.subtractConvert); diff --git a/inference-engine/src/low_precision_transformations/src/pull_reshape_through_dequantization.cpp b/inference-engine/src/low_precision_transformations/src/pull_reshape_through_dequantization.cpp index 68617278844..42afb73e21b 100644 --- a/inference-engine/src/low_precision_transformations/src/pull_reshape_through_dequantization.cpp +++ b/inference-engine/src/low_precision_transformations/src/pull_reshape_through_dequantization.cpp @@ -30,15 +30,15 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& reshap assert(ov::is_type(elementwiseValues)); const std::shared_ptr newReshape = ov::as_type_ptr(reshape->clone_with_new_inputs({ - elementwise->get_input_node_shared_ptr(0ul), + elementwise->input_value(0), reshapeValues })); std::shared_ptr newElementwiseValues; - const Shape elementwiseValuesShape = elementwiseValues->output(0).get_shape(); + const Shape elementwiseValuesShape = elementwiseValues->get_output_shape(0); if (!elementwiseValuesShape.empty() && (elementwiseValuesShape.size() != 1ul)) { // update shape constant value to avoid eltwise constan value broadcasting - const Shape elementwiseShape = elementwise->output(0).get_shape(); + const Shape elementwiseShape = elementwise->get_output_shape(0); const std::vector reshapeValuesVector = ov::as_type_ptr(reshapeValues)->cast_vector(); const std::vector newReshapeValuesVector = ngraph::pass::low_precision::NetworkHelper::updateReshapeValues( @@ -47,13 +47,13 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& reshap reshapeValuesVector); const auto newReshapeValues = std::make_shared( - reshapeValues->output(0).get_element_type(), + reshapeValues->get_output_element_type(0), Shape{ newReshapeValuesVector.size() }, newReshapeValuesVector); newElementwiseValues = ngraph::pass::low_precision::fold_reshape( - elementwiseValues->output(0), - newReshapeValues->output(0), + elementwiseValues, + newReshapeValues, ov::as_type_ptr(reshape)->get_special_zero()); assert(ov::is_type(newElementwiseValues)); } else { @@ -71,7 +71,7 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& reshap } std::shared_ptr moveThroughConvert(const std::shared_ptr& reshape, const std::shared_ptr& convert) { - const auto newReshape = reshape->clone_with_new_inputs({ convert->get_input_node_shared_ptr(0), reshape->get_input_node_shared_ptr(1) }); + const auto newReshape = reshape->clone_with_new_inputs({ convert->input_value(0), reshape->input_value(1) }); const auto newConvert = convert->clone_with_new_inputs({ newReshape }); replace_node(reshape, newConvert); copy_runtime_info({ convert, reshape }, { newReshape, newConvert }); @@ -81,7 +81,7 @@ std::shared_ptr moveThroughConvert(const std::shared_ptr& reshape, c void fuseConstant(const std::shared_ptr& reshape, const std::shared_ptr& constant) { ngraph::OutputVector result(1); - reshape->constant_fold(result, { constant->output(0), reshape->get_input_node_ptr(1)->output(0) }); + reshape->constant_fold(result, { constant, reshape->input_value(1) }); const auto newConstant = result[0].get_node_shared_ptr(); replace_node(reshape, newConstant); copy_runtime_info({ constant, reshape }, newConstant); diff --git a/inference-engine/src/low_precision_transformations/src/pull_transpose_through_dequantization.cpp b/inference-engine/src/low_precision_transformations/src/pull_transpose_through_dequantization.cpp index 3ee344884dc..2af61df6734 100644 --- a/inference-engine/src/low_precision_transformations/src/pull_transpose_through_dequantization.cpp +++ b/inference-engine/src/low_precision_transformations/src/pull_transpose_through_dequantization.cpp @@ -30,8 +30,8 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& transp elementwiseValuesConvert->get_input_node_shared_ptr(0ul); assert(ov::is_type(elementwiseValues)); - const auto transposeValuesShape = transposeValues->output(0).get_shape(); - const auto elementwiseValuesShape = elementwiseValues->output(0).get_shape(); + const auto transposeValuesShape = transposeValues->get_output_shape(0); + const auto elementwiseValuesShape = elementwiseValues->get_output_shape(0); if (elementwiseValuesShape.size() != shape_size(transposeValuesShape)) { if (shape_size(elementwiseValuesShape) != 1ul) { return nullptr; @@ -51,8 +51,8 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& transp transposeValues })); const auto newElementwiseValues = ngraph::pass::low_precision::fold( - elementwiseValues->output(0), - transposeValues->output(0)); + elementwiseValues, + transposeValues); assert(ov::is_type(newElementwiseValues)); const auto newElementwise = elementwise->clone_with_new_inputs({ @@ -68,7 +68,7 @@ std::shared_ptr moveThroughElementwise(const std::shared_ptr& transp } std::shared_ptr moveThroughConvert(const std::shared_ptr& transpose, const std::shared_ptr& convert) { - const auto newTranspose = transpose->clone_with_new_inputs({convert->get_input_node_shared_ptr(0), transpose->get_input_node_ptr(1)->output(0) }); + const auto newTranspose = transpose->clone_with_new_inputs({convert->input_value(0), transpose->input_value(1) }); const auto newConvert = convert->clone_with_new_inputs({ newTranspose }); replace_node(transpose, newConvert); copy_runtime_info({ convert, transpose }, { newTranspose, newConvert }); @@ -78,8 +78,8 @@ std::shared_ptr moveThroughConvert(const std::shared_ptr& transpose, void fuseConstant(const std::shared_ptr& transpose, const std::shared_ptr& constant) { const auto newConstant = ngraph::pass::low_precision::fold( - constant->output(0), - transpose->get_input_node_ptr(1)->output(0)); + constant, + transpose->input_value(1)); replace_node(transpose, newConstant); copy_runtime_info({ constant, transpose }, newConstant); diff --git a/inference-engine/src/low_precision_transformations/src/reshape.cpp b/inference-engine/src/low_precision_transformations/src/reshape.cpp index ee8e02e1045..aeba26b7e49 100644 --- a/inference-engine/src/low_precision_transformations/src/reshape.cpp +++ b/inference-engine/src/low_precision_transformations/src/reshape.cpp @@ -63,7 +63,7 @@ void reshapeDequantizationConstant(const std::shared_ptr& resha } } - const auto reshapeOutputPShape = reshape->output(0).get_partial_shape(); + const auto reshapeOutputPShape = reshape->get_output_partial_shape(0); const auto reshapeOutputRank = reshapeOutputPShape.rank(); assert(reshapeOutputRank.is_static()); assert(reshapeOutputRank.get_length() >= 2); diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp index 95a6168db9c..cb8b650bac8 100644 --- a/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp +++ b/inference-engine/src/low_precision_transformations/src/rt_info/intervals_alignment_attribute.cpp @@ -52,7 +52,7 @@ std::shared_ptr>> Va FakeQuantizeDequantization dequantization; { - const auto targetInputs = node->output(0).get_target_inputs(); + const auto targetInputs = node->get_output_target_inputs(0); if (targetInputs.size() == 1ul) { dequantization = NetworkHelper::getDequantizationBelow(node, true); } @@ -75,7 +75,7 @@ std::shared_ptr>> Va auto multiplyResult = dequantization.multiplyConstant == nullptr ? node->get_input_node_ptr(3)->shared_from_this() : fold( - foldConvert(node->get_input_node_ptr(3)->shared_from_this(), params.deqPrecision), + foldConvert(node->input_value(3), params.deqPrecision), dequantization.multiplyConstant); auto multiplyResultConstant = ov::as_type_ptr(multiplyResult); @@ -87,7 +87,7 @@ std::shared_ptr>> Va auto multiplyResult = dequantization.multiplyConstant == nullptr ? node->get_input_node_ptr(4)->shared_from_this() : fold( - foldConvert(node->get_input_node_ptr(4)->shared_from_this(), params.deqPrecision), + foldConvert(node->input_value(4), params.deqPrecision), dequantization.multiplyConstant); auto multiplyResultConstant = ov::as_type_ptr(multiplyResult); diff --git a/inference-engine/src/low_precision_transformations/src/rt_info/shared_value_attribute.cpp b/inference-engine/src/low_precision_transformations/src/rt_info/shared_value_attribute.cpp deleted file mode 100644 index 95cc5fa72ea..00000000000 --- a/inference-engine/src/low_precision_transformations/src/rt_info/shared_value_attribute.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "low_precision/rt_info/shared_value_attribute.hpp" - -#include -#include -#include -#include -#include - -#include -#include "low_precision/network_helper.hpp" - -using namespace ngraph; diff --git a/inference-engine/src/low_precision_transformations/src/squeeze.cpp b/inference-engine/src/low_precision_transformations/src/squeeze.cpp index 42d8e7e5932..b6290e10793 100644 --- a/inference-engine/src/low_precision_transformations/src/squeeze.cpp +++ b/inference-engine/src/low_precision_transformations/src/squeeze.cpp @@ -47,7 +47,7 @@ bool SqueezeTransformation::transform(TransformationContext& context, ngraph::pa return NetworkHelper::toScalar(dequantizationOpConstant); } if (constantShape.size() == inputRankValue) { - return ov::as_type_ptr(fold(dequantizationOpConstant, squeeze->get_input_node_shared_ptr(1))); + return ov::as_type_ptr(fold(dequantizationOpConstant, squeeze->input_value(1))); } return dequantizationOpConstant; diff --git a/inference-engine/src/low_precision_transformations/src/strided_slice.cpp b/inference-engine/src/low_precision_transformations/src/strided_slice.cpp index 12744e330ce..a8c709cd31e 100644 --- a/inference-engine/src/low_precision_transformations/src/strided_slice.cpp +++ b/inference-engine/src/low_precision_transformations/src/strided_slice.cpp @@ -62,9 +62,9 @@ std::shared_ptr stridedSliceDeqConstant( const auto result = fold( constant, - stridedSlice->get_input_node_shared_ptr(1), - stridedSlice->get_input_node_shared_ptr(2), - stridedSlice->get_input_node_shared_ptr(3), + stridedSlice->input_value(1), + stridedSlice->input_value(2), + stridedSlice->input_value(3), beginMask, endMask, stridedSlice->get_new_axis_mask(), diff --git a/inference-engine/src/low_precision_transformations/src/subtract.cpp b/inference-engine/src/low_precision_transformations/src/subtract.cpp index 46e2245bcb3..2b1a8a777b1 100644 --- a/inference-engine/src/low_precision_transformations/src/subtract.cpp +++ b/inference-engine/src/low_precision_transformations/src/subtract.cpp @@ -55,10 +55,10 @@ bool SubtractTransformation::transform(TransformationContext& context, ngraph::p // X * SC - SH = X * SC - SH' * SC // SH' = SH / SC std::shared_ptr newSubtract = ov::as_type_ptr(subtract->copy_with_new_inputs({ - dequantization.multiply->get_input_node_shared_ptr(0), + dequantization.multiply->input_value(0), ngraph::pass::low_precision::fold( - subtract->get_input_node_shared_ptr(1), - dequantization.multiply->get_input_node_shared_ptr(1)) + subtract->input_value(1), + dequantization.multiply->input_value(1)) })); std::shared_ptr newMultiply = dequantization.multiply->copy_with_new_inputs({ @@ -72,8 +72,8 @@ bool SubtractTransformation::transform(TransformationContext& context, ngraph::p if (dequantization.subtract != nullptr) { std::shared_ptr newSubtract = ov::as_type_ptr(subtract->copy_with_new_inputs({ - dequantization.subtract->get_input_node_shared_ptr(0), - fold(subtract->get_input_node_shared_ptr(1), dequantization.subtractConstant) + dequantization.subtract->input_value(0), + fold(subtract->input_value(1), dequantization.subtractConstant) })); replace_node(subtract, newSubtract); @@ -86,8 +86,8 @@ bool SubtractTransformation::transform(TransformationContext& context, ngraph::p subtract->set_output_type(0, originalPrecision, subtract->get_output_partial_shape(0)); replace_node(subtract, std::make_shared>( - subtract->get_input_node_shared_ptr(0), - subtract->get_input_node_shared_ptr(1))); + subtract->input_value(0), + subtract->input_value(1))); } return true; } diff --git a/inference-engine/src/low_precision_transformations/src/transparent_base_transformation.cpp b/inference-engine/src/low_precision_transformations/src/transparent_base_transformation.cpp index c89ca0e9144..23d9922c454 100644 --- a/inference-engine/src/low_precision_transformations/src/transparent_base_transformation.cpp +++ b/inference-engine/src/low_precision_transformations/src/transparent_base_transformation.cpp @@ -4,9 +4,7 @@ #include "low_precision/transparent_base_transformation.hpp" -#include #include -#include #include #include "low_precision/network_helper.hpp" @@ -16,27 +14,20 @@ using namespace ngraph::pass; using namespace ngraph::pass::low_precision; bool TransparentBaseTransformation::transform(TransformationContext& context, ngraph::pattern::Matcher &m) { - auto operation = m.get_match_root(); - const std::shared_ptr dequantization = operation->input_value(0).get_node_shared_ptr(); - // const std::shared_ptr dequantizationParent = dequantization->input_value(0).get_node_shared_ptr(); + std::shared_ptr op = m.get_match_root(); + if (!canBeTransformed(context, op)) { + return false; + } - // auto newOperation = operation->copy_with_new_inputs({ dequantizationParent }); - // const auto newDequantization = dequantization->copy_with_new_inputs({ - // newOperation, - // dequantization->input_value(1), - // dequantization->input_value(2) }); - - // const std::string friendlyName = operation->get_friendly_name(); - //// TODO: new operation name has to be unique - // newOperation->set_friendly_name(friendlyName + "_original"); - // newDequantization->set_friendly_name(friendlyName); - - // replace_node(operation, newDequantization); - - // NetworkHelper::moveDequantization(operation, dequantization); + op = NetworkHelper::separateInStandaloneBranch(op); + moveDequantizationAfter(context, op, NetworkHelper::getDequantization(op), true); return true; } bool TransparentBaseTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr layer) const { return true; } + +bool TransparentBaseTransformation::isPrecisionPreserved(std::shared_ptr layer) const noexcept { + return true; +} diff --git a/inference-engine/src/low_precision_transformations/src/unsqueeze.cpp b/inference-engine/src/low_precision_transformations/src/unsqueeze.cpp index 011bb4d46f0..a515085f017 100644 --- a/inference-engine/src/low_precision_transformations/src/unsqueeze.cpp +++ b/inference-engine/src/low_precision_transformations/src/unsqueeze.cpp @@ -48,7 +48,7 @@ bool UnsqueezeTransformation::transform(TransformationContext& context, ngraph:: } if (constantShape.size() == inputRankValue) { - return ov::as_type_ptr(fold(dequantizationOpConstant, unsqueeze->get_input_node_shared_ptr(1))); + return ov::as_type_ptr(fold(dequantizationOpConstant, unsqueeze->input_value(1))); } return dequantizationOpConstant; From 1d3df63d64c7c7edd8afdf855f4d61fd71dfd280 Mon Sep 17 00:00:00 2001 From: Vladimir Gavrilov Date: Mon, 27 Sep 2021 12:49:18 +0300 Subject: [PATCH 3/3] Implement reference nGraph implementation for operation ExperimentalDetectronROIFeatureExtractor (#6484) * Written reference implementation of the operation ExperimentalDetectronROIFeatureExtractor. * Small fixes. * Started to write tests for evaluation of the operation ExperimentalDetectronROIfeatureExtractor. * Written test for evaluation of the nGraph operation ExperimentalDetectronROIFeatureExtractor. * Some changes. * Added debug prints to evaluates.map. * Added more debug prints. * Added another debug prints. * Added more debug prints. * Added more debug prints. * Added more debug prints. * Inserted additional static_casts. * Added more static_casts. * Commented some debug prints. * Some reversion. * Deleted some debug prints. * Deleted some debug prints. * Deleted more debug prints. * Added some casts and debug prints. * Some changes. * Small changes. * Some changes. * Added png files. * Small changes. * Code style fixes. * Code style fixes. * Rewritten some auxiliary functions. * Corrected the body of the function experimental_detectron_roi_feature_extractor(). * Some code style fixes. * Code style fixes. * Small code style fixes. * Commented one debug print. * Small changes. * Added some debug print. * Small changes. * Added more debug prints. * Small fixes. * Added more debug prints. * Commented some code. * Indexing operation [] was replaced by .at() method in the function pre_calc_for_bilinear_interpolate(). * Deleted unneeded variables w1, w2, w3, w4. * Deleted variable xx. * Added GCC pragma before the function pre_calc_for_bilinear_interpolate(). * Fixes in macros. * Fixed pragma before the function pre_calc_for_bilinear_interpolate(). * Deleted some debug prints. * Deleted more debug prints and fixed some code style issues. * Deleted redundant assert. * Deleted redundant assert in the function split_points(). * Started to move tests for nGraph reference implementation of ExperimentalDetectronROIFeatureExtractor to template plugin. * Enabled test INTERPRETER.onnx_model_experimental_detectron_roi_feature_extractor. * Deleted backend tests for the reference nGraph implementation of the operation ExperimentalDetectronROIFeatureExtractor. * Deleted commented code. * Fixed typo. * Some fixes. * Some fixes. * Some fixes. * Some fixes. * Some fixes. * Renamed the function that calculates ROIAlign. * Deleted redundant usings. * Now input shapes are parameters of test. * Small fix. * Now element type is also test parameter. * Deleted some commented code. * Added test for float16 case. * Small fix. * Added test for bfloat16 case. * Deleted redundant parameters of tests. * Deleted commented code. * Deleted redundant structure. * Small fix. * Some reverting. --- ...mental_detectron_roi_feature_extractor.cpp | 230 +++++++++++ ...mental_detectron_roi_feature_extractor.hpp | 36 ++ ...mental_detectron_roi_feature_extractor.cpp | 387 ++++++++++++++++++ .../runtime/interpreter/evaluates_map.cpp | 75 ++++ .../runtime/interpreter/opset_int_tbl.hpp | 1 + .../runtime/interpreter/unit_test.manifest | 2 +- 6 files changed, 730 insertions(+), 1 deletion(-) create mode 100644 docs/template_plugin/tests/functional/op_reference/experimental_detectron_roi_feature_extractor.cpp create mode 100644 ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_roi_feature_extractor.hpp create mode 100644 ngraph/core/reference/src/runtime/reference/experimental_detectron_roi_feature_extractor.cpp diff --git a/docs/template_plugin/tests/functional/op_reference/experimental_detectron_roi_feature_extractor.cpp b/docs/template_plugin/tests/functional/op_reference/experimental_detectron_roi_feature_extractor.cpp new file mode 100644 index 00000000000..43fc4c9a59d --- /dev/null +++ b/docs/template_plugin/tests/functional/op_reference/experimental_detectron_roi_feature_extractor.cpp @@ -0,0 +1,230 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include +#include +#include +#include + +#include "base_reference_test.hpp" + +using namespace ngraph; +using namespace InferenceEngine; +using namespace reference_tests; + +struct ExperimentalROIParams { + ExperimentalROIParams(const std::vector& experimental_detectron_roi_feature_inputs, + const std::vector& expected_results, + const std::string& test_case_name) + : inputs{experimental_detectron_roi_feature_inputs}, + expected_results{expected_results}, + test_case_name{test_case_name} {} + + std::vector inputs; + std::vector expected_results; + std::string test_case_name; +}; + +class ReferenceExperimentalROILayerTest : public testing::TestWithParam, public CommonReferenceTest { +public: + void SetUp() override { + auto params = GetParam(); + function = create_function(params.inputs); + inputData.reserve(params.inputs.size()); + refOutData.reserve(params.expected_results.size()); + for (const auto& input_tensor : params.inputs) { + inputData.push_back(input_tensor.data); + } + for (const auto& expected_tensor : params.expected_results) { + refOutData.push_back(expected_tensor.data); + } + } + + static std::string getTestCaseName(const testing::TestParamInfo& obj) { + auto param = obj.param; + return param.test_case_name; + } + +private: + std::shared_ptr create_function(const std::vector& inputs) { + op::v6::ExperimentalDetectronROIFeatureExtractor::Attributes attrs; + attrs.aligned = false; + attrs.output_size = 3; + attrs.sampling_ratio = 2; + attrs.pyramid_scales = {4}; + + const size_t num_of_inputs = inputs.size(); + NodeVector node_vector(num_of_inputs); + ParameterVector parameter_vector(num_of_inputs); + for (size_t i = 0; i < num_of_inputs; ++i) { + const auto& current_input = inputs[i]; + auto current_parameter = std::make_shared(current_input.type, current_input.shape); + node_vector[i] = current_parameter; + parameter_vector[i] = current_parameter; + } + + auto roi = std::make_shared(node_vector, attrs); + auto fun = std::make_shared(OutputVector{roi->output(0), roi->output(1)}, parameter_vector); + return fun; + } +}; + +TEST_P(ReferenceExperimentalROILayerTest, ExperimentalROIWithHardcodedRefs) { + Exec(); +} + +INSTANTIATE_TEST_SUITE_P( + smoke_ExperimentalROI_With_Hardcoded_Refs, + ReferenceExperimentalROILayerTest, + ::testing::Values( + ExperimentalROIParams( + std::vector{Tensor(Shape{2, 4}, + ngraph::element::f32, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}), + Tensor(Shape{1, 2, 2, 3}, + ngraph::element::f32, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0})}, + std::vector{Tensor(Shape{2, 2, 3, 3}, + ngraph::element::f32, + std::vector{1.416667, + 1.75, + 2.083333, + 2.416667, + 2.75, + 3.083333, + 3.166667, + 3.5, + 3.833333, + 7.416667, + 7.75, + 8.083333, + 8.416667, + 8.75, + 9.083334, + 9.166666, + 9.5, + 9.833334, + 4.166667, + 4.5, + 4.833333, + 4.166667, + 4.5, + 4.833333, + 2.083333, + 2.25, + 2.416667, + 10.16667, + 10.5, + 10.83333, + 10.16667, + 10.5, + 10.83333, + 5.083333, + 5.25, + 5.416667}), + Tensor(Shape{2, 4}, + ngraph::element::f32, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0})}, + "experimental_detectron_roi_feature_eval_f32"), + ExperimentalROIParams( + std::vector{Tensor(Shape{2, 4}, + ngraph::element::f16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}), + Tensor(Shape{1, 2, 2, 3}, + ngraph::element::f16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0})}, + std::vector{Tensor(Shape{2, 2, 3, 3}, + ngraph::element::f16, + std::vector{1.416667, + 1.75, + 2.083333, + 2.416667, + 2.75, + 3.083333, + 3.166667, + 3.5, + 3.833333, + 7.416667, + 7.75, + 8.083333, + 8.416667, + 8.75, + 9.083334, + 9.166666, + 9.5, + 9.833334, + 4.166667, + 4.5, + 4.833333, + 4.166667, + 4.5, + 4.833333, + 2.083333, + 2.25, + 2.416667, + 10.16667, + 10.5, + 10.83333, + 10.16667, + 10.5, + 10.83333, + 5.083333, + 5.25, + 5.416667}), + Tensor(Shape{2, 4}, + ngraph::element::f16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0})}, + "experimental_detectron_roi_feature_eval_f16"), + ExperimentalROIParams( + std::vector{Tensor(Shape{2, 4}, + ngraph::element::bf16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}), + Tensor(Shape{1, 2, 2, 3}, + ngraph::element::bf16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0})}, + std::vector{Tensor(Shape{2, 2, 3, 3}, + ngraph::element::bf16, + std::vector{1.416667, + 1.75, + 2.083333, + 2.416667, + 2.75, + 3.083333, + 3.166667, + 3.5, + 3.833333, + 7.416667, + 7.75, + 8.083333, + 8.416667, + 8.75, + 9.083334, + 9.166666, + 9.5, + 9.833334, + 4.166667, + 4.5, + 4.833333, + 4.166667, + 4.5, + 4.833333, + 2.083333, + 2.25, + 2.416667, + 10.16667, + 10.5, + 10.83333, + 10.16667, + 10.5, + 10.83333, + 5.083333, + 5.25, + 5.416667}), + Tensor(Shape{2, 4}, + ngraph::element::bf16, + std::vector{0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0})}, + "experimental_detectron_roi_feature_eval_bf16"))); diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_roi_feature_extractor.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_roi_feature_extractor.hpp new file mode 100644 index 00000000000..94ca8dfaa66 --- /dev/null +++ b/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_roi_feature_extractor.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "ngraph/node.hpp" +#include "ngraph/op/util/op_types.hpp" +#include "ngraph/ops.hpp" +#include "ngraph/shape_util.hpp" + +namespace ngraph { +namespace runtime { +namespace reference { +void experimental_detectron_roi_feature_extractor( + const std::vector>& inputs, + const std::vector& input_shapes, + const op::v6::ExperimentalDetectronROIFeatureExtractor::Attributes& attrs, + float* output_rois_features, + float* output_rois); + +void experimental_detectron_roi_feature_extractor_postprocessing(void* prois_features, + void* prois, + const ngraph::element::Type output_type, + const std::vector& output_roi_features, + const std::vector& output_rois, + const Shape& output_roi_features_shape, + const Shape& output_rois_shape); +} // namespace reference +} // namespace runtime +} // namespace ngraph diff --git a/ngraph/core/reference/src/runtime/reference/experimental_detectron_roi_feature_extractor.cpp b/ngraph/core/reference/src/runtime/reference/experimental_detectron_roi_feature_extractor.cpp new file mode 100644 index 00000000000..dac833012b9 --- /dev/null +++ b/ngraph/core/reference/src/runtime/reference/experimental_detectron_roi_feature_extractor.cpp @@ -0,0 +1,387 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "ngraph/runtime/reference/experimental_detectron_roi_feature_extractor.hpp" + +#include +#include +#include +#include +#include + +#include "ngraph/op/experimental_detectron_roi_feature.hpp" +#include "ngraph/shape.hpp" + +#if defined(__GNUC__) && !defined(__clang__) +# if defined(__linux__) && defined(__i386__) && (__GNUC__ == 7 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0) +# define NEED_FIX 1 +# else +# define NEED_FIX 0 +# endif +#else +# define NEED_FIX 0 +#endif + +namespace { +constexpr int64_t input_rois_port = 0; +constexpr int64_t input_features_start_port = 1; + +void redistribute_rois(const std::vector& rois, std::vector& level_ids, const int64_t levels_num) { + const float canonical_scale = 224.0f; + const int64_t canonical_level = 2; + const size_t num_rois = level_ids.size(); + + for (size_t i = 0; i < num_rois; ++i) { + const float x0 = rois[4 * i + 0]; + const float y0 = rois[4 * i + 1]; + const float x1 = rois[4 * i + 2]; + const float y1 = rois[4 * i + 3]; + + int64_t target_level = levels_num; + float area = (x1 - x0) * (y1 - y0); + if (area > 0) { + area = std::sqrt(area) / canonical_scale; + area = std::log2(area + 1e-6f); + target_level = static_cast(std::floor(area + canonical_level)); + target_level = std::max(static_cast(0), std::min(levels_num - 1, target_level)); + } + + level_ids[i] = target_level; + } +} + +void reord(const std::vector& src_data, + const std::vector& ranks, + const int64_t step, + float* dst_data, + std::vector& dst_mapping) { + int64_t n = static_cast(ranks.size()); + + std::iota(dst_mapping.begin(), dst_mapping.end(), 0); + std::sort(dst_mapping.begin(), dst_mapping.end(), [&ranks](int64_t i1, int64_t i2) { + return ranks[i1] < ranks[i2]; + }); + for (int64_t i = 0; i < n; ++i) { + const int64_t j = dst_mapping[i]; + memcpy(dst_data + i * step, src_data.data() + j * step, sizeof(float) * step); + } +} + +void split_points(const std::vector& ids, std::vector& rois_per_level, const int64_t levels_num) { + rois_per_level.clear(); + rois_per_level.resize(levels_num, 0); + for (size_t i = 0; i < ids.size(); ++i) { + rois_per_level[ids[i]]++; + } + for (int64_t i = 1; i < levels_num; ++i) { + rois_per_level[i] += rois_per_level[i - 1]; + } + rois_per_level.insert(rois_per_level.begin(), 0); +} + +// implementation taken from Caffe2 +template +struct PreCalc { + int64_t pos1; + int64_t pos2; + int64_t pos3; + int64_t pos4; + T w1; + T w2; + T w3; + T w4; +}; + +// The function pre_calc_for_bilinear_interpolate() gives incorrect results for -O3 optimization level, when IE +// is compiled using GCC 7.5.0 on Ubuntu 18.04 32-bit. But results are correct, for example, if we use Clang 10.0 +// on Ubuntu 18.04 32-bit with -O3 optimization level. Next, the function pre_calc_for_bilinear_interpolate() +// gives incorrect results after compiling by GCC 7.5.0 or Clang 10 in Ubuntu 18.04 32-bit, if the optimization +// level is -O1 or -O2. Finally, the function gives correct result in Ubuntu 18.04 32-bit, if the optimization +// level is -O0. +#if NEED_FIX +# pragma GCC push_options +# pragma GCC optimize("-O0") +#endif +template +void pre_calc_for_bilinear_interpolate(const int64_t height, + const int64_t width, + const int64_t pooled_height, + const int64_t pooled_width, + const int64_t iy_upper, + const int64_t ix_upper, + T roi_start_h, + T roi_start_w, + T bin_size_h, + T bin_size_w, + int64_t roi_bin_grid_h, + int64_t roi_bin_grid_w, + std::vector>& pre_calc) { + int64_t pre_calc_index = 0; + for (int64_t ph = 0; ph < pooled_height; ph++) { + for (int64_t pw = 0; pw < pooled_width; pw++) { + for (int64_t iy = 0; iy < iy_upper; iy++) { + for (int64_t ix = 0; ix < ix_upper; ix++) { + T y = roi_start_h + static_cast(ph) * bin_size_h + + (static_cast(iy) + static_cast(0.5f)) * bin_size_h / static_cast(roi_bin_grid_h); + T x = roi_start_w + static_cast(pw) * bin_size_w + + (static_cast(ix) + static_cast(0.5f)) * bin_size_w / static_cast(roi_bin_grid_w); + + // deal with: inverse elements are out of feature map boundary + if (y < static_cast(-1.0f) || y > static_cast(height) || x < static_cast(-1.0f) || + x > static_cast(width)) { + // empty + pre_calc_index += 1; + continue; + } + + y = std::max(y, static_cast(0.0f)); + x = std::max(x, static_cast(0.0f)); + + int64_t y_low = static_cast(y); + int64_t x_low = static_cast(x); + int64_t y_high = 0; + int64_t x_high = 0; + + if (y_low >= height - 1) { + y_high = y_low = height - 1; + y = static_cast(y_low); + } else { + y_high = y_low + 1; + } + + if (x_low >= width - 1) { + x_high = x_low = width - 1; + x = static_cast(x_low); + } else { + x_high = x_low + 1; + } + + T ly = y - y_low; + T lx = x - x_low; + T hy = static_cast(1.0) - ly; + T hx = static_cast(1.0) - lx; + + // save weights and indeces + PreCalc pc; + pc.pos1 = y_low * width + x_low; + pc.pos2 = y_low * width + x_high; + pc.pos3 = y_high * width + x_low; + pc.pos4 = y_high * width + x_high; + pc.w1 = hy * hx; + pc.w2 = hy * lx; + pc.w3 = ly * hx; + pc.w4 = ly * lx; + pre_calc.at(pre_calc_index) = pc; + + pre_calc_index += 1; + } + } + } + } +} +#if NEED_FIX +# pragma GCC pop_options +#endif + +template +void ROIAlignForward(const int64_t nthreads, + const T* bottom_data, + const T& spatial_scale, + const int64_t channels, + const int64_t height, + const int64_t width, + const int64_t pooled_height, + const int64_t pooled_width, + const int64_t sampling_ratio, + const T* bottom_rois, + const bool aligned, + T* top_data) { + int64_t roi_cols = 4; + + int64_t n_rois = nthreads / channels / pooled_width / pooled_height; + // (n, c, ph, pw) is an element in the pooled output + for (int64_t n = 0; n < n_rois; ++n) { + int64_t index_n = n * channels * pooled_width * pooled_height; + + // roi could have 4 or 5 columns + const T* offset_bottom_rois = bottom_rois + n * roi_cols; + int64_t roi_batch_ind = 0; + if (roi_cols == 5) { + roi_batch_ind = static_cast(offset_bottom_rois[0]); + offset_bottom_rois++; + } + + T offset = aligned ? static_cast(0.5) : static_cast(0.0); + // Do not use rounding; this implementation detail is critical + T roi_start_w = offset_bottom_rois[0] * spatial_scale - offset; + T roi_start_h = offset_bottom_rois[1] * spatial_scale - offset; + T roi_end_w = offset_bottom_rois[2] * spatial_scale - offset; + T roi_end_h = offset_bottom_rois[3] * spatial_scale - offset; + + // Force malformed ROIs to be 1x1 + T roi_width = std::max(roi_end_w - roi_start_w, static_cast(1.0)); + T roi_height = std::max(roi_end_h - roi_start_h, static_cast(1.0)); + T bin_size_h = static_cast(roi_height) / static_cast(pooled_height); + T bin_size_w = static_cast(roi_width) / static_cast(pooled_width); + + // We use roi_bin_grid to sample the grid and mimic integral + int64_t roi_bin_grid_h = + (sampling_ratio > 0) ? sampling_ratio : static_cast(std::ceil(roi_height / pooled_height)); + int64_t roi_bin_grid_w = + (sampling_ratio > 0) ? sampling_ratio : static_cast(std::ceil(roi_width / pooled_width)); + + // We do average (integral) pooling inside a bin + const T count = static_cast(roi_bin_grid_h * roi_bin_grid_w); + + // we want to precalculate indices and weights shared by all channels, + // this is the key point of optimization + std::vector> pre_calc(roi_bin_grid_h * roi_bin_grid_w * pooled_width * pooled_height); + + pre_calc_for_bilinear_interpolate(height, + width, + pooled_height, + pooled_width, + roi_bin_grid_h, + roi_bin_grid_w, + roi_start_h, + roi_start_w, + bin_size_h, + bin_size_w, + roi_bin_grid_h, + roi_bin_grid_w, + pre_calc); + + for (int64_t c = 0; c < channels; c++) { + int64_t index_n_c = index_n + c * pooled_width * pooled_height; + const T* offset_bottom_data = bottom_data + (roi_batch_ind * channels + c) * height * width; + int64_t pre_calc_index = 0; + + for (int64_t ph = 0; ph < pooled_height; ph++) { + for (int64_t pw = 0; pw < pooled_width; pw++) { + int64_t index = index_n_c + ph * pooled_width + pw; + T output_val = 0.; + for (int64_t iy = 0; iy < roi_bin_grid_h; iy++) { + for (int64_t ix = 0; ix < roi_bin_grid_w; ix++) { + PreCalc pc = pre_calc[pre_calc_index]; + output_val += pc.w1 * offset_bottom_data[pc.pos1] + pc.w2 * offset_bottom_data[pc.pos2] + + pc.w3 * offset_bottom_data[pc.pos3] + pc.w4 * offset_bottom_data[pc.pos4]; + + pre_calc_index += 1; + } + } + output_val /= count; + + top_data[index] = output_val; + } // for pw + } // for ph + } // for c + } +} +} // namespace + +namespace ngraph { +namespace runtime { +namespace reference { +void experimental_detectron_roi_feature_extractor( + const std::vector>& inputs, + const std::vector& input_shapes, + const op::v6::ExperimentalDetectronROIFeatureExtractor::Attributes& attrs, + float* output_rois_features, + float* output_rois) { + int64_t output_dim = attrs.output_size; + auto pyramid_scales = attrs.pyramid_scales; + int64_t sampling_ratio = attrs.sampling_ratio; + bool aligned = attrs.aligned; + int64_t pooled_height = output_dim; + int64_t pooled_width = output_dim; + + const int64_t levels_num = static_cast(inputs.size() - input_features_start_port); + const int64_t num_rois = static_cast(input_shapes[input_rois_port][0]); + const int64_t channels_num = static_cast(input_shapes[input_features_start_port][1]); + const int64_t feaxels_per_roi = pooled_height * pooled_width * channels_num; + + const float* input_rois = inputs[input_rois_port].data(); + + std::vector level_ids(num_rois, 0); + redistribute_rois(inputs[input_rois_port], level_ids, levels_num); + + std::vector reordered_rois(4 * num_rois, 0); + std::vector original_rois_mapping(num_rois, 0); + reord(inputs[input_rois_port], level_ids, 4, reordered_rois.data(), original_rois_mapping); + + std::vector rois_per_level; + split_points(level_ids, rois_per_level, levels_num + 1); + + std::vector output_rois_features_temp(feaxels_per_roi * num_rois, 0); + for (int64_t i = 0; i < levels_num; ++i) { + const int64_t level_rois_offset = rois_per_level[i]; + const int64_t level_rois_num = rois_per_level[i + 1] - level_rois_offset; + if (level_rois_num > 0) { + const float* featuremap = inputs[input_features_start_port + i].data(); + const int64_t featuremap_height = static_cast(input_shapes[input_features_start_port + i][2]); + const int64_t featuremap_width = static_cast(input_shapes[input_features_start_port + i][3]); + ROIAlignForward(feaxels_per_roi * level_rois_num, + featuremap, + 1.0f / pyramid_scales[i], + channels_num, + featuremap_height, + featuremap_width, + pooled_height, + pooled_width, + sampling_ratio, + &reordered_rois[4 * level_rois_offset], + aligned, + &output_rois_features_temp[feaxels_per_roi * level_rois_offset]); + } + } + + std::vector dummy_mapping(num_rois, 0); + reord(output_rois_features_temp, original_rois_mapping, feaxels_per_roi, output_rois_features, dummy_mapping); + + memcpy(output_rois, input_rois, 4 * num_rois * sizeof(float)); +} + +void experimental_detectron_roi_feature_extractor_postprocessing(void* prois_features, + void* prois, + const ngraph::element::Type output_type, + const std::vector& output_rois_features, + const std::vector& output_rois, + const Shape& output_rois_features_shape, + const Shape& output_rois_shape) { + size_t output_rois_features_size = shape_size(output_rois_features_shape); + size_t output_rois_size = shape_size(output_rois_shape); + + switch (output_type) { + case element::Type_t::bf16: { + bfloat16* output_rois_features_ptr = reinterpret_cast(prois_features); + bfloat16* output_rois_ptr = reinterpret_cast(prois); + for (size_t i = 0; i < output_rois_features_size; ++i) { + output_rois_features_ptr[i] = bfloat16(output_rois_features[i]); + } + for (size_t i = 0; i < output_rois_size; ++i) { + output_rois_ptr[i] = bfloat16(output_rois[i]); + } + } break; + case element::Type_t::f16: { + float16* output_rois_features_ptr = reinterpret_cast(prois_features); + float16* output_rois_ptr = reinterpret_cast(prois); + for (size_t i = 0; i < output_rois_features_size; ++i) { + output_rois_features_ptr[i] = float16(output_rois_features[i]); + } + for (size_t i = 0; i < output_rois_size; ++i) { + output_rois_ptr[i] = float16(output_rois[i]); + } + } break; + case element::Type_t::f32: { + float* output_rois_features_ptr = reinterpret_cast(prois_features); + float* output_rois_ptr = reinterpret_cast(prois); + memcpy(output_rois_features_ptr, output_rois_features.data(), output_rois_features_size * sizeof(float)); + memcpy(output_rois_ptr, output_rois.data(), output_rois_size * sizeof(float)); + } break; + default:; + } +} +} // namespace reference +} // namespace runtime +} // namespace ngraph diff --git a/ngraph/test/runtime/interpreter/evaluates_map.cpp b/ngraph/test/runtime/interpreter/evaluates_map.cpp index fc781d68374..e31964fb6ef 100644 --- a/ngraph/test/runtime/interpreter/evaluates_map.cpp +++ b/ngraph/test/runtime/interpreter/evaluates_map.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1222,6 +1223,80 @@ bool evaluate(const shared_ptr& op return true; } +namespace experimental_roi_feature { +struct InfoForEDROIFeature { + Shape output_rois_features_shape; + Shape output_rois_shape; +}; + +InfoForEDROIFeature get_info_for_ed_roi_feature(const std::vector input_shapes, + const op::v6::ExperimentalDetectronROIFeatureExtractor::Attributes& attrs) { + InfoForEDROIFeature result; + + size_t output_size = static_cast(attrs.output_size); + auto out_shape = Shape{0, 0, output_size, output_size}; + auto out_rois_shape = Shape{0, 4}; + + auto rois_shape = input_shapes[0]; + + out_shape[0] = rois_shape[0]; + out_rois_shape[0] = rois_shape[0]; + + out_shape[1] = input_shapes[1][1]; + + result.output_rois_features_shape = out_shape; + result.output_rois_shape = out_rois_shape; + + return result; +} +} // namespace experimental_roi_feature + +template +bool evaluate(const shared_ptr& op, + const HostTensorVector& outputs, + const HostTensorVector& inputs) +{ + const auto attrs = op->get_attrs(); + + std::vector> input_data; + std::vector input_shapes; + for (const auto& input : inputs) { + const auto current_shape = input->get_shape(); + input_data.push_back(get_floats(input, current_shape)); + input_shapes.push_back(current_shape); + } + + const auto info = experimental_roi_feature::get_info_for_ed_roi_feature(input_shapes, attrs); + const auto& output_rois_features_shape = info.output_rois_features_shape; + const auto& output_rois_shape = info.output_rois_shape; + + const auto output_type = op->get_input_element_type(0); + + outputs[0]->set_element_type(output_type); + outputs[0]->set_shape(output_rois_features_shape); + outputs[1]->set_element_type(output_type); + outputs[1]->set_shape(output_rois_shape); + + std::vector output_rois_features(shape_size(output_rois_features_shape)); + std::vector output_rois(shape_size(output_rois_shape)); + + runtime::reference::experimental_detectron_roi_feature_extractor(input_data, + input_shapes, + attrs, + output_rois_features.data(), + output_rois.data()); + + runtime::reference::experimental_detectron_roi_feature_extractor_postprocessing(outputs[0]->get_data_ptr(), + outputs[1]->get_data_ptr(), + output_type, + output_rois_features, + output_rois, + output_rois_features_shape, + output_rois_shape); + + return true; +} + namespace fft_v7 { struct InfoForFFT7 { std::vector input_data; diff --git a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp index b24b8676961..e30e35ed13c 100644 --- a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp +++ b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp @@ -88,6 +88,7 @@ NGRAPH_OP(CTCGreedyDecoderSeqLen, op::v6) NGRAPH_OP(ExperimentalDetectronDetectionOutput, op::v6) NGRAPH_OP(ExperimentalDetectronGenerateProposalsSingleImage, op::v6) NGRAPH_OP(ExperimentalDetectronPriorGridGenerator, op::v6) +NGRAPH_OP(ExperimentalDetectronROIFeatureExtractor, op::v6) NGRAPH_OP(ExperimentalDetectronTopKROIs, op::v6) NGRAPH_OP(GatherElements, op::v6) NGRAPH_OP(MVN, ngraph::op::v6) diff --git a/ngraph/test/runtime/interpreter/unit_test.manifest b/ngraph/test/runtime/interpreter/unit_test.manifest index 880872f4491..637269119df 100644 --- a/ngraph/test/runtime/interpreter/unit_test.manifest +++ b/ngraph/test/runtime/interpreter/unit_test.manifest @@ -129,7 +129,7 @@ quantize_clamp_int32 minimum_u16 # Interpreter backend doesn't implement evaluate method for OP ExperimentalDetectronROIFeatureExtractor -INTERPRETER.onnx_model_experimental_detectron_roi_feature_extractor +# INTERPRETER.onnx_model_experimental_detectron_roi_feature_extractor # No evaluator for DeformableConv2D onnx_model_deformable_conv_2d