From cab7a77cbabf692c61f92128b95e342b87937c4d Mon Sep 17 00:00:00 2001 From: Andrew Bakalin Date: Fri, 23 Oct 2020 17:04:36 +0300 Subject: [PATCH] [IE][VPU][GT][DTS]: Update MyriadPlugin to work with dynamic NMS-5 (#2698) * [VPU][GT][NGraph] Get rid of DynamicNMS and transformation * [VPU][NGraph] Update DTS for NMS * [VPU][NGraph] Update StaticShapeNMS to be inherrited from NMS-5 * [VPU][GT] Update StaticShapeNMS stage to work with updated NGraph op * [VPU][Tests] Update tests * [VPU][GT] Fix StaticShapeNMS to be inherited from NonMaxSuppressionIE3 * [VPU][GT] Remove unused NonMaxSuppression --- .../dynamic_non_max_suppression.hpp | 61 ---- .../static_shape_non_maximum_suppression.hpp | 26 +- .../convert_nms_4_to_nms_dynamic.hpp | 21 -- .../dynamic_non_max_suppression.cpp | 89 ------ .../static_shape_non_maximum_suppression.cpp | 72 ++--- .../convert_nms_4_to_nms_dynamic.cpp | 55 ---- .../dynamic_to_static_shape.cpp | 73 +++-- ...ic_to_static_shape_non_max_suppression.cpp | 49 ++-- .../include/vpu/frontend/frontend.hpp | 1 - .../include/vpu/model/stage.hpp | 1 - .../include/vpu/stages/nms.hpp | 34 --- .../src/frontend/frontend.cpp | 3 - .../vpu/graph_transformer/src/stages/nms.cpp | 97 ------- .../src/stages/static_shape_nms.cpp | 85 ++++-- ...ic_to_static_shape_non_max_suppression.cpp | 87 +++--- .../eliminate_shapeof_after_dsr.cpp | 6 +- .../single_layer_tests/static_shape_nms.cpp | 21 +- .../dsr_non_max_suppression.cpp | 4 +- .../src/utils/ngraph_helpers.cpp | 42 +-- .../common/layers/myriad_layers_nms_test.cpp | 260 ----------------- .../common/layers/myriad_layers_nms_test.hpp | 264 ------------------ 21 files changed, 253 insertions(+), 1098 deletions(-) delete mode 100644 inference-engine/src/vpu/common/include/vpu/ngraph/operations/dynamic_non_max_suppression.hpp delete mode 100644 inference-engine/src/vpu/common/include/vpu/ngraph/transformations/convert_nms_4_to_nms_dynamic.hpp delete mode 100644 inference-engine/src/vpu/common/src/ngraph/operations/dynamic_non_max_suppression.cpp delete mode 100644 inference-engine/src/vpu/common/src/ngraph/transformations/convert_nms_4_to_nms_dynamic.cpp delete mode 100644 inference-engine/src/vpu/graph_transformer/include/vpu/stages/nms.hpp delete mode 100644 inference-engine/src/vpu/graph_transformer/src/stages/nms.cpp delete mode 100644 inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.cpp delete mode 100644 inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.hpp diff --git a/inference-engine/src/vpu/common/include/vpu/ngraph/operations/dynamic_non_max_suppression.hpp b/inference-engine/src/vpu/common/include/vpu/ngraph/operations/dynamic_non_max_suppression.hpp deleted file mode 100644 index 153747344ec..00000000000 --- a/inference-engine/src/vpu/common/include/vpu/ngraph/operations/dynamic_non_max_suppression.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "ngraph/op/non_max_suppression.hpp" - -namespace ngraph { namespace vpu { namespace op { - -class DynamicNonMaxSuppression : public ngraph::op::v4::NonMaxSuppression { -public: - static constexpr NodeTypeInfo type_info{"DynamicNonMaxSuppression", 0}; - const NodeTypeInfo& get_type_info() const override { return type_info; } - DynamicNonMaxSuppression() = default; - - /// \brief Constructs a DynamicNonMaxSuppression operation. - /// - /// \param boxes Node producing the box coordinates - /// \param scores Node producing the box scores - /// \param max_output_boxes_per_class Node producing maximum number of boxes to be - /// selected per class - /// \param iou_threshold Node producing intersection over union threshold - /// \param score_threshold Node producing minimum score threshold - /// \param box_encoding Specifies the format of boxes data encoding - /// \param sort_result_descending Specifies whether it is necessary to sort selected - /// boxes across batches - /// \param output_type Specifies the output tensor type - DynamicNonMaxSuppression(const Output& boxes, - const Output& scores, - const Output& max_output_boxes_per_class, - const Output& iou_threshold, - const Output& score_threshold, - const BoxEncodingType box_encoding = BoxEncodingType::CORNER, - const bool sort_result_descending = true, - const ngraph::element::Type& output_type = ngraph::element::i64); - - /// \brief Constructs a DynamicNonMaxSuppression operation with default values for the last - /// 3 inputs - /// - /// \param boxes Node producing the box coordinates - /// \param scores Node producing the box coordinates - /// \param box_encoding Specifies the format of boxes data encoding - /// \param sort_result_descending Specifies whether it is necessary to sort selected - /// boxes across batches - /// \param output_type Specifies the output tensor type - DynamicNonMaxSuppression(const Output& boxes, - const Output& scores, - const BoxEncodingType box_encoding = BoxEncodingType::CORNER, - const bool sort_result_descending = true, - const ngraph::element::Type& output_type = ngraph::element::i64); - - void validate_and_infer_types() override; - - std::shared_ptr - clone_with_new_inputs(const OutputVector& new_args) const override; -}; - -} // namespace op -} // namespace vpu -} // namespace ngraph diff --git a/inference-engine/src/vpu/common/include/vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp b/inference-engine/src/vpu/common/include/vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp index b2f2c98ad7f..acc0b898cf2 100644 --- a/inference-engine/src/vpu/common/include/vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp +++ b/inference-engine/src/vpu/common/include/vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp @@ -5,33 +5,27 @@ #pragma once #include -#include +#include #include #include namespace ngraph { namespace vpu { namespace op { -class StaticShapeNonMaxSuppression : public ngraph::op::v4::NonMaxSuppression { +class StaticShapeNonMaxSuppression : public ngraph::op::NonMaxSuppressionIE3 { public: static constexpr NodeTypeInfo type_info{"StaticShapeNonMaxSuppression", 0}; const NodeTypeInfo& get_type_info() const override { return type_info; } - StaticShapeNonMaxSuppression() = default; StaticShapeNonMaxSuppression(const Output& boxes, - const Output& scores, - const Output& max_output_boxes_per_class, - const Output& iou_threshold, - const Output& score_threshold, - const BoxEncodingType box_encoding = BoxEncodingType::CORNER, - const bool sort_result_descending = true, - const ngraph::element::Type& output_type = ngraph::element::i64); - - StaticShapeNonMaxSuppression(const Output& boxes, - const Output& scores, - const BoxEncodingType box_encoding = BoxEncodingType::CORNER, - const bool sort_result_descending = true, - const ngraph::element::Type& output_type = ngraph::element::i64); + const Output& scores, + const Output& maxOutputBoxesPerClass, + const Output& iouThreshold, + const Output& scoreThreshold, + const Output& softNmsSigma, + int centerPointBox = 0, + bool sortResultDescending = true, + const ngraph::element::Type& outputType = ngraph::element::i64); void validate_and_infer_types() override; std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; diff --git a/inference-engine/src/vpu/common/include/vpu/ngraph/transformations/convert_nms_4_to_nms_dynamic.hpp b/inference-engine/src/vpu/common/include/vpu/ngraph/transformations/convert_nms_4_to_nms_dynamic.hpp deleted file mode 100644 index 05b942719d0..00000000000 --- a/inference-engine/src/vpu/common/include/vpu/ngraph/transformations/convert_nms_4_to_nms_dynamic.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2018-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -namespace vpu { - -class UpgradeNMS4ToNMSDynamic : public ngraph::pass::GraphRewrite { -public: - UpgradeNMS4ToNMSDynamic() : GraphRewrite() { - upgrade_nms4_to_nms_dynamic(); - } - -private: - void upgrade_nms4_to_nms_dynamic(); -}; - -} // namespace vpu diff --git a/inference-engine/src/vpu/common/src/ngraph/operations/dynamic_non_max_suppression.cpp b/inference-engine/src/vpu/common/src/ngraph/operations/dynamic_non_max_suppression.cpp deleted file mode 100644 index e733bc8758a..00000000000 --- a/inference-engine/src/vpu/common/src/ngraph/operations/dynamic_non_max_suppression.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "vpu/ngraph/operations/dynamic_non_max_suppression.hpp" - -#include "vpu/utils/error.hpp" - -#include "ngraph/opsets/opset3.hpp" -#include "ngraph/evaluator.hpp" - -namespace ngraph { namespace vpu { namespace op { - -constexpr NodeTypeInfo DynamicNonMaxSuppression::type_info; - -DynamicNonMaxSuppression::DynamicNonMaxSuppression( - const Output& boxes, - const Output& scores, - const Output& max_output_boxes_per_class, - const Output& iou_threshold, - const Output& score_threshold, - const BoxEncodingType box_encoding, - const bool sort_result_descending, - const element::Type& output_type) - : ngraph::op::v4::NonMaxSuppression(boxes, - scores, - max_output_boxes_per_class, - iou_threshold, - score_threshold, - box_encoding, - sort_result_descending, - output_type) { - constructor_validate_and_infer_types(); -} - -DynamicNonMaxSuppression::DynamicNonMaxSuppression( - const Output& boxes, - const Output& scores, - const BoxEncodingType box_encoding, - const bool sort_result_descending, - const element::Type& output_type) - : ngraph::op::v4::NonMaxSuppression(boxes, - scores, - ngraph::op::Constant::create(element::i64, Shape{}, {0}), - ngraph::op::Constant::create(element::f32, Shape{}, {.0f}), - ngraph::op::Constant::create(element::f32, Shape{}, {.0f}), - box_encoding, - sort_result_descending, - output_type) { - constructor_validate_and_infer_types(); -} - -std::shared_ptr DynamicNonMaxSuppression::clone_with_new_inputs(const OutputVector& new_args) const { - check_new_args_count(this, new_args); - NODE_VALIDATION_CHECK(this, - new_args.size() >= 2 && new_args.size() <= 5, - "Number of inputs must be 2, 3, 4 or 5"); - - const auto& arg2 = new_args.size() > 2 - ? new_args.at(2) - : ngraph::op::Constant::create(element::i32, Shape{}, {0}); - const auto& arg3 = new_args.size() > 3 - ? new_args.at(3) - : ngraph::op::Constant::create(element::f32, Shape{}, {.0f}); - const auto& arg4 = new_args.size() > 4 - ? new_args.at(4) - : ngraph::op::Constant::create(element::f32, Shape{}, {.0f}); - - return std::make_shared(new_args.at(0), - new_args.at(1), - arg2, - arg3, - arg4, - m_box_encoding, - m_sort_result_descending, - m_output_type); -} - -void DynamicNonMaxSuppression::validate_and_infer_types() { - ngraph::op::v4::NonMaxSuppression::validate_and_infer_types(); - - // NonMaxSuppression produces triplets - // that have the following format: [batch_index, class_index, box_index] - set_output_type(0, m_output_type, PartialShape{Dimension::dynamic(), 3}); -} - -} // namespace op -} // namespace vpu -} // namespace ngraph diff --git a/inference-engine/src/vpu/common/src/ngraph/operations/static_shape_non_maximum_suppression.cpp b/inference-engine/src/vpu/common/src/ngraph/operations/static_shape_non_maximum_suppression.cpp index d21de5a3ba1..94e1a964ca6 100644 --- a/inference-engine/src/vpu/common/src/ngraph/operations/static_shape_non_maximum_suppression.cpp +++ b/inference-engine/src/vpu/common/src/ngraph/operations/static_shape_non_maximum_suppression.cpp @@ -3,6 +3,7 @@ // #include +#include #include "vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp" #include "ngraph/runtime/host_tensor.hpp" @@ -14,65 +15,40 @@ constexpr NodeTypeInfo StaticShapeNonMaxSuppression::type_info; StaticShapeNonMaxSuppression::StaticShapeNonMaxSuppression( const Output& boxes, const Output& scores, - const Output& max_output_boxes_per_class, - const Output& iou_threshold, - const Output& score_threshold, - const StaticShapeNonMaxSuppression::BoxEncodingType box_encoding, - const bool sort_result_descending, - const element::Type& output_type) - : ngraph::op::v4::NonMaxSuppression( - boxes, scores, max_output_boxes_per_class, iou_threshold, score_threshold, - box_encoding, sort_result_descending, output_type) { - constructor_validate_and_infer_types(); -} - -StaticShapeNonMaxSuppression::StaticShapeNonMaxSuppression( - const Output& boxes, - const Output& scores, - const StaticShapeNonMaxSuppression::BoxEncodingType box_encoding, - const bool sort_result_descending, - const element::Type& output_type) - : ngraph::op::v4::NonMaxSuppression(boxes, - scores, - ngraph::opset3::Constant::create(element::i64, Shape{}, {0}), - ngraph::opset3::Constant::create(element::f32, Shape{}, {.0f}), - ngraph::opset3::Constant::create(element::f32, Shape{}, {.0f}), - box_encoding, sort_result_descending, output_type) { + const Output& maxOutputBoxesPerClass, + const Output& iouThreshold, + const Output& scoreThreshold, + const Output& softNmsSigma, + int centerPointBox, + const bool sortResultDescending, + const element::Type& outputType) + : ngraph::op::NonMaxSuppressionIE3( + boxes, scores, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, + softNmsSigma, centerPointBox, sortResultDescending, outputType) { constructor_validate_and_infer_types(); } std::shared_ptr StaticShapeNonMaxSuppression::clone_with_new_inputs(const OutputVector& new_args) const { check_new_args_count(this, new_args); - NODE_VALIDATION_CHECK(this, - new_args.size() >= 2 && new_args.size() <= 5, - "Number of inputs must be 2, 3, 4 or 5"); - - const auto& arg2 = new_args.size() > 2 ? new_args.at(2) : ngraph::opset3::Constant::create(element::i32, Shape{}, {0}); - const auto& arg3 = new_args.size() > 3 ? new_args.at(3) : ngraph::opset3::Constant::create(element::f32, Shape{}, {.0f}); - const auto& arg4 = new_args.size() > 4 ? new_args.at(4) : ngraph::opset3::Constant::create(element::f32, Shape{}, {.0f}); - - return std::make_shared( - new_args.at(0), - new_args.at(1), - arg2, - arg3, - arg4, - m_box_encoding, - m_sort_result_descending, - m_output_type); + return std::make_shared(new_args.at(0), new_args.at(1), new_args.at(2), new_args.at(3), + new_args.at(4), new_args.at(5), m_center_point_box, m_sort_result_descending, + m_output_type); } void StaticShapeNonMaxSuppression::validate_and_infer_types() { - ngraph::op::v4::NonMaxSuppression::validate_and_infer_types(); + ngraph::op::NonMaxSuppressionIE3::validate_and_infer_types(); - const auto out_shape = this->get_output_partial_shape(0); - NODE_VALIDATION_CHECK(this, out_shape.is_static(), - "StaticShapeNonMaxSuppression output shape is not fully defined: ", out_shape); + auto outIndicesShape = get_output_partial_shape(0); + auto outScoresShape = get_output_partial_shape(1); - set_output_size(2); - set_output_type(0, m_output_type, out_shape); - set_output_type(1, m_output_type, Shape{2}); + NODE_VALIDATION_CHECK(this, outIndicesShape.is_static(), + "StaticShapeNonMaxSuppression output shape is not fully defined: ", outIndicesShape); + NODE_VALIDATION_CHECK(this, outScoresShape.is_static(), + "StaticShapeNonMaxSuppression output shape is not fully defined: ", outScoresShape); + + // Replace valid outputs with the shape of selected_indices and selected_scores outputs + set_output_type(2, m_output_type, Shape{2}); } } // namespace op diff --git a/inference-engine/src/vpu/common/src/ngraph/transformations/convert_nms_4_to_nms_dynamic.cpp b/inference-engine/src/vpu/common/src/ngraph/transformations/convert_nms_4_to_nms_dynamic.cpp deleted file mode 100644 index 7edef5922ca..00000000000 --- a/inference-engine/src/vpu/common/src/ngraph/transformations/convert_nms_4_to_nms_dynamic.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2018-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "vpu/ngraph/transformations/convert_nms_4_to_nms_dynamic.hpp" - -#include -#include -#include -#include -#include - -#include -#include - -void vpu::UpgradeNMS4ToNMSDynamic::upgrade_nms4_to_nms_dynamic() { - auto boxes = std::make_shared(ngraph::element::f32, ngraph::Shape{1, 1000, 4}); - auto scores = std::make_shared(ngraph::element::f32, ngraph::Shape{1, 1, 1000}); - auto max_output_boxes_per_class = ngraph::opset4::Constant::create(ngraph::element::i64, ngraph::Shape{}, {10}); - auto iou_threshold = ngraph::opset4::Constant::create(ngraph::element::f32, ngraph::Shape{}, {0.75}); - auto score_threshold = ngraph::opset4::Constant::create(ngraph::element::f32, ngraph::Shape{}, {0.7}); - auto nms = std::make_shared(boxes, scores, max_output_boxes_per_class, - iou_threshold, score_threshold); - - ngraph::graph_rewrite_callback callback = [](ngraph::pattern::Matcher &m) { - auto nms_4 = std::dynamic_pointer_cast(m.get_match_root()); - if (!nms_4) { - return false; - } - - const auto box_encoding = nms_4->get_box_encoding(); - const auto new_args = nms_4->input_values(); - const auto& arg2 = new_args.size() > 2 ? new_args.at(2) : ngraph::opset4::Constant::create(ngraph::element::i32, ngraph::Shape{}, {0}); - const auto& arg3 = new_args.size() > 3 ? new_args.at(3) : ngraph::opset4::Constant::create(ngraph::element::f32, ngraph::Shape{}, {.0f}); - const auto& arg4 = new_args.size() > 4 ? new_args.at(4) : ngraph::opset4::Constant::create(ngraph::element::f32, ngraph::Shape{}, {.0f}); - - const auto nms_dynamic = std::make_shared( - new_args.at(0), - new_args.at(1), - arg2, - arg3, - arg4, - box_encoding, - nms_4->get_sort_result_descending(), - nms_4->get_output_type()); - - nms_dynamic->set_friendly_name(nms_4->get_friendly_name()); - ngraph::copy_runtime_info(nms_4, nms_dynamic); - ngraph::replace_node(nms_4, nms_dynamic); - return true; - }; - - auto m = std::make_shared(nms, "UpgradeNMS4ToDynamic"); - this->add_matcher(m, callback, ngraph::pass::PassProperty::CHANGE_DYNAMIC_STATE); -} diff --git a/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape.cpp b/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape.cpp index 9dbdc4a960d..9059e978f85 100644 --- a/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape.cpp +++ b/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape.cpp @@ -28,7 +28,6 @@ #include "ngraph/opsets/opset3.hpp" #include "ngraph/opsets/opset5.hpp" -#include "vpu/ngraph/operations/dynamic_non_max_suppression.hpp" namespace vpu { @@ -71,42 +70,42 @@ bool propagateUpperBoundFromExistingDSR(std::shared_ptr& funct const Transformations& getDefaultTransformations() { static const Transformations transformations = { - {ngraph::opset3::Add::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Multiply::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Subtract::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::VariadicSplit::type_info, dynamicToStaticShapeVariadicSplit}, - {ngraph::opset3::Divide::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Equal::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Greater::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Power::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Maximum::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Minimum::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::opset3::Less::type_info, dynamicToStaticShapeBinaryEltwise}, - {ngraph::vpu::op::DynamicNonMaxSuppression::type_info, dynamicToStaticNonMaxSuppression}, - {ngraph::opset3::NonZero::type_info, dynamicToStaticShapeNonZero}, - {ngraph::opset3::TopK::type_info, dynamicToStaticShapeTopK}, - {ngraph::opset3::Transpose::type_info, dynamicToStaticShapeTranspose}, - {ngraph::opset3::Concat::type_info, dynamicToStaticShapeConcat}, - {ngraph::opset3::Convert::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Clamp::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Floor::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Log::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Relu::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::ScatterUpdate::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Sigmoid::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Softmax::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Exp::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::Sqrt::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::LogicalNot::type_info, dynamicToStaticUnaryElementwise}, - {ngraph::opset3::StridedSlice::type_info, dynamicToStaticShapeStridedSlice}, - {ngraph::opset3::Squeeze::type_info, dynamicToStaticShapeSqueeze}, - {ngraph::opset3::Gather::type_info, dynamicToStaticShapeGather}, - {ngraph::opset3::Unsqueeze::type_info, dynamicToStaticShapeUnsqueeze}, - {ngraph::opset3::ROIAlign::type_info, dynamicToStaticShapeROIAlign}, - {ngraph::opset3::Reshape::type_info, dynamicToStaticShapeReshape}, - {ngraph::opset3::Broadcast::type_info, dynamicToStaticShapeBroadcast}, - {ngraph::opset3::MatMul::type_info, dynamicToStaticShapeMatMul}, - {ngraph::opset5::Split::type_info, dynamicToStaticShapeSplit}, + {ngraph::opset3::Add::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Multiply::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Subtract::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::VariadicSplit::type_info, dynamicToStaticShapeVariadicSplit}, + {ngraph::opset3::Divide::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Equal::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Greater::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Power::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Maximum::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Minimum::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset3::Less::type_info, dynamicToStaticShapeBinaryEltwise}, + {ngraph::opset5::NonMaxSuppression::type_info, dynamicToStaticNonMaxSuppression}, + {ngraph::opset3::NonZero::type_info, dynamicToStaticShapeNonZero}, + {ngraph::opset3::TopK::type_info, dynamicToStaticShapeTopK}, + {ngraph::opset3::Transpose::type_info, dynamicToStaticShapeTranspose}, + {ngraph::opset3::Concat::type_info, dynamicToStaticShapeConcat}, + {ngraph::opset3::Convert::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Clamp::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Floor::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Log::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Relu::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::ScatterUpdate::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Sigmoid::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Softmax::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Exp::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::Sqrt::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::LogicalNot::type_info, dynamicToStaticUnaryElementwise}, + {ngraph::opset3::StridedSlice::type_info, dynamicToStaticShapeStridedSlice}, + {ngraph::opset3::Squeeze::type_info, dynamicToStaticShapeSqueeze}, + {ngraph::opset3::Gather::type_info, dynamicToStaticShapeGather}, + {ngraph::opset3::Unsqueeze::type_info, dynamicToStaticShapeUnsqueeze}, + {ngraph::opset3::ROIAlign::type_info, dynamicToStaticShapeROIAlign}, + {ngraph::opset3::Reshape::type_info, dynamicToStaticShapeReshape}, + {ngraph::opset3::Broadcast::type_info, dynamicToStaticShapeBroadcast}, + {ngraph::opset3::MatMul::type_info, dynamicToStaticShapeMatMul}, + {ngraph::opset5::Split::type_info, dynamicToStaticShapeSplit}, // reduction {ngraph::opset3::ReduceLogicalAnd::type_info, dynamicToStaticShapeReduce}, diff --git a/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp b/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp index a1285ef0f73..02145ca889a 100644 --- a/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp +++ b/inference-engine/src/vpu/common/src/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp @@ -4,39 +4,50 @@ #include "vpu/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.hpp" +#include #include "vpu/ngraph/operations/dynamic_shape_resolver.hpp" -#include "vpu/ngraph/operations/dynamic_non_max_suppression.hpp" #include "vpu/ngraph/utilities.hpp" -#include +#include #include "ngraph/graph_util.hpp" -#include "ngraph/opsets/opset3.hpp" +#include "ngraph/opsets/opset5.hpp" #include -#include namespace vpu { void dynamicToStaticNonMaxSuppression(std::shared_ptr node) { - auto nms_dynamic = std::dynamic_pointer_cast(node); - VPU_THROW_UNLESS(nms_dynamic, "dynamicToStaticNonMaxSuppression transformation for {} of type {} expects {} as node for replacement", - node->get_friendly_name(), node->get_type_info(), ngraph::vpu::op::DynamicNonMaxSuppression::type_info); + auto nms = std::dynamic_pointer_cast(node); + VPU_THROW_UNLESS(nms, "dynamicToStaticNonMaxSuppression transformation for {} of type {} expects {} as node for replacement", + node->get_friendly_name(), node->get_type_info(), ngraph::opset5::NonMaxSuppression::type_info); auto staticShapeNMS = std::make_shared( - nms_dynamic->input_value(0), - nms_dynamic->input_value(1), - nms_dynamic->input_value(2), - nms_dynamic->input_value(3), - nms_dynamic->input_value(4), - nms_dynamic->get_box_encoding(), - nms_dynamic->get_sort_result_descending(), - nms_dynamic->get_output_type()); + nms->input_value(0), + nms->input_value(1), + nms->input_value(2), + nms->input_value(3), + nms->input_value(4), + nms->input_value(5), + nms->get_box_encoding() == ngraph::opset5::NonMaxSuppression::BoxEncodingType::CENTER ? 1 : 0, + nms->get_sort_result_descending(), + nms->get_output_type()); - auto dynamicShapeResolver = std::make_shared( - staticShapeNMS->output(0), staticShapeNMS->output(1)); - dynamicShapeResolver->set_friendly_name(nms_dynamic->get_friendly_name()); + auto dsrIndices = std::make_shared( + staticShapeNMS->output(0), staticShapeNMS->output(2)); + auto dsrScores = std::make_shared( + staticShapeNMS->output(1), staticShapeNMS->output(2)); + dsrIndices->set_friendly_name(nms->output(0).get_node_shared_ptr()->get_friendly_name()); + dsrScores->set_friendly_name(nms->output(1).get_node_shared_ptr()->get_friendly_name()); - ngraph::replace_node(std::move(nms_dynamic), std::move(dynamicShapeResolver)); + const auto gatherValidOutputs = std::make_shared( + staticShapeNMS->output(2), + ngraph::opset5::Constant::create(staticShapeNMS->output(2).get_element_type(), ngraph::Shape{1}, {0}), + ngraph::opset5::Constant::create(staticShapeNMS->output(2).get_element_type(), ngraph::Shape{1}, {0})); + gatherValidOutputs->set_friendly_name(nms->output(2).get_node_shared_ptr()->get_friendly_name()); + + nms->output(0).replace(dsrIndices); + nms->output(1).replace(dsrScores); + nms->output(2).replace(gatherValidOutputs); } } // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/frontend/frontend.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/frontend/frontend.hpp index 3667c2c921d..3cddc334e25 100644 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/frontend/frontend.hpp +++ b/inference-engine/src/vpu/graph_transformer/include/vpu/frontend/frontend.hpp @@ -136,7 +136,6 @@ public: void parseTopK(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; void parseSelect(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; void parseExpDetectionOutput(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; - void parseNonMaxSuppression(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; void parseROIFeatureExtractor(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; void parseConvert(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; void parseErf(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const; diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/model/stage.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/model/stage.hpp index 05955247b08..e6378acdd0d 100644 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/model/stage.hpp +++ b/inference-engine/src/vpu/graph_transformer/include/vpu/model/stage.hpp @@ -144,7 +144,6 @@ VPU_DECLARE_ENUM(StageType, ScatterUpdate = 103, ReduceMin = 105, ExpDetectionOutput = 106, // ExperimentalDetectronDetectionOutput - NonMaxSuppression = 107, ROIFeatureExtractor = 108, SCRelu = 109, Erf = 110, diff --git a/inference-engine/src/vpu/graph_transformer/include/vpu/stages/nms.hpp b/inference-engine/src/vpu/graph_transformer/include/vpu/stages/nms.hpp deleted file mode 100644 index e76410a6023..00000000000 --- a/inference-engine/src/vpu/graph_transformer/include/vpu/stages/nms.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -namespace vpu { - -class NonMaxSuppression : public StageNode { -protected: - StagePtr cloneImpl() const override; - - void propagateDataOrderImpl(StageDataInfo& orderInfo) override; - - void getDataStridesRequirementsImpl(StageDataInfo& stridesInfo) override; - - void finalizeDataLayoutImpl() override; - - void getBatchSupportInfoImpl(StageDataInfo& batchInfo) override; - - StageSHAVEsRequirements getSHAVEsRequirementsImpl() const override; - - void initialCheckImpl() const override; - - void finalCheckImpl() const override; - - void serializeParamsImpl(BlobSerializer& serializer) const override; - - void serializeDataImpl(BlobSerializer& serializer) const override; -}; - -} // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp b/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp index 32a6c40c726..f24125a5269 100644 --- a/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/frontend/frontend.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include "vpu/ngraph/transformations/dynamic_to_static_shape.hpp" #include "vpu/ngraph/transformations/eliminate_shapeof_after_dsr.hpp" #include @@ -105,7 +104,6 @@ FrontEnd::FrontEnd(StageBuilder::Ptr stageBuilder, const ie::ICore* core) {"Select", LAYER_PARSER(parseSelect)}, {"Erf", LAYER_PARSER(parseErf)}, {"ExperimentalDetectronDetectionOutput", LAYER_PARSER(parseExpDetectionOutput)}, - {"NonMaxSuppression", LAYER_PARSER(parseNonMaxSuppression)}, {"ExperimentalDetectronROIFeatureExtractor", LAYER_PARSER(parseROIFeatureExtractor)}, {"Convert", LAYER_PARSER(parseConvert)}, {"ReduceMax", LAYER_PARSER(parseReduce)}, @@ -173,7 +171,6 @@ ie::ICNNNetwork::Ptr FrontEnd::convertNetwork(ie::ICNNNetwork& network) { manager.register_pass<::ngraph::pass::InitNodeInfo>(); // WA: ConvertPriorBox must be executed before the 1st ConstantFolding pass manager.register_pass<::ngraph::pass::ConvertPriorBox>(); - manager.register_pass(); manager.register_pass(); manager.register_pass(); manager.register_pass(); diff --git a/inference-engine/src/vpu/graph_transformer/src/stages/nms.cpp b/inference-engine/src/vpu/graph_transformer/src/stages/nms.cpp deleted file mode 100644 index 698126371fa..00000000000 --- a/inference-engine/src/vpu/graph_transformer/src/stages/nms.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2018-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include -#include -#include - -namespace vpu { - -StagePtr NonMaxSuppression::cloneImpl() const { - return std::make_shared(*this); -} - -void NonMaxSuppression::propagateDataOrderImpl(StageDataInfo& orderInfo) { -} - -void NonMaxSuppression::getDataStridesRequirementsImpl(StageDataInfo& stridesInfo) { -} - -void NonMaxSuppression::finalizeDataLayoutImpl() { -} - -void NonMaxSuppression::getBatchSupportInfoImpl(StageDataInfo& batchInfo) { -} - -StageSHAVEsRequirements NonMaxSuppression::getSHAVEsRequirementsImpl() const { - // Current NMS implementation doesn't allow calculation of `> boxesThreshold` boxes using one SHAVE - constexpr int boxesThreshold = 3650; - - const auto& inDesc = input(0)->desc(); - const auto& maxBoxesNum = inDesc.dim(Dim::H); - - if (maxBoxesNum > boxesThreshold) { - return StageSHAVEsRequirements::NeedMax; - } else { - return StageSHAVEsRequirements::OnlyOne; - } -} - -void NonMaxSuppression::initialCheckImpl() const { - assertInputsOutputsTypes(this, - {{DataType::FP16}, - {DataType::FP16}, - {DataType::S32}, - {DataType::FP16}, - {DataType::FP16}}, - {{DataType::S32}}); -} - -void NonMaxSuppression::finalCheckImpl() const { -} - -void NonMaxSuppression::serializeParamsImpl(BlobSerializer& serializer) const { - bool center_point_box = attrs().get("center_point_box"); - - serializer.append(static_cast(center_point_box)); -} - -void NonMaxSuppression::serializeDataImpl(BlobSerializer& serializer) const { - IE_ASSERT(inputEdges().size() >= 2 && inputEdges().size() <= 5); - IE_ASSERT(outputEdges().size() == 1); - - auto input1 = inputEdges()[0]->input(); - auto input2 = inputEdges()[1]->input(); - auto input3 = inputEdges()[2]->input(); - auto input4 = inputEdges()[3]->input(); - auto input5 = inputEdges()[4]->input(); - auto output = outputEdges()[0]->output(); - - input1->serializeBuffer(serializer); - input2->serializeBuffer(serializer); - output->serializeBuffer(serializer); - input3->serializeBuffer(serializer); - input4->serializeBuffer(serializer); - input5->serializeBuffer(serializer); -} - -void FrontEnd::parseNonMaxSuppression(const Model& model, const ie::CNNLayerPtr& _layer, const DataVector& inputs, const DataVector& outputs) const { - auto layer = std::dynamic_pointer_cast(_layer); - IE_ASSERT(layer != nullptr); - - IE_ASSERT(inputs.size() >= 2 && inputs.size() <= 5); - IE_ASSERT(outputs.size() == 1); - - DataVector tempInputs = inputs; - for (size_t fake = inputs.size(); fake < 5; fake++) { - tempInputs.push_back(model->addFakeData()); - } - - auto stage = model->addNewStage(layer->name, StageType::NonMaxSuppression, layer, tempInputs, outputs); - stage->attrs().set("center_point_box", layer->center_point_box); -} - -} // namespace vpu diff --git a/inference-engine/src/vpu/graph_transformer/src/stages/static_shape_nms.cpp b/inference-engine/src/vpu/graph_transformer/src/stages/static_shape_nms.cpp index dda8008663f..f5cf1e4f6b5 100644 --- a/inference-engine/src/vpu/graph_transformer/src/stages/static_shape_nms.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/stages/static_shape_nms.cpp @@ -2,10 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // -#include #include -#include +#include #include #include @@ -14,12 +13,34 @@ namespace vpu { namespace { -class StaticShapeNMS final : public NonMaxSuppression { +class StaticShapeNMS final : public StageNode { private: StagePtr cloneImpl() const override { return std::make_shared(*this); } + void propagateDataOrderImpl(StageDataInfo& orderInfo) override { + } + + void getDataStridesRequirementsImpl(StageDataInfo& stridesInfo) override { + } + + void finalizeDataLayoutImpl() override { + } + + void getBatchSupportInfoImpl(StageDataInfo& batchInfo) override { + } + + StageSHAVEsRequirements getSHAVEsRequirementsImpl() const override { + // Current NMS implementation doesn't allow calculation of `> boxesThreshold` boxes using one SHAVE + constexpr int boxesThreshold = 3650; + + const auto& inDesc = input(0)->desc(); + const auto& maxBoxesNum = inDesc.dim(Dim::H); + + return maxBoxesNum <= boxesThreshold ? StageSHAVEsRequirements::OnlyOne : StageSHAVEsRequirements::NeedMax; + } + void initialCheckImpl() const override { assertInputsOutputsTypes(this, {{DataType::FP16}, @@ -31,6 +52,12 @@ private: {DataType::S32}}); } + void serializeParamsImpl(BlobSerializer& serializer) const override { + const auto center_point_box = attrs().get("center_point_box"); + + serializer.append(static_cast(center_point_box)); + } + void serializeDataImpl(BlobSerializer& serializer) const override { auto input1 = inputEdges()[0]->input(); auto input2 = inputEdges()[1]->input(); @@ -53,29 +80,45 @@ private: } // namespace void FrontEnd::parseStaticShapeNMS(const Model& model, const ie::CNNLayerPtr& layer, const DataVector& inputs, const DataVector& outputs) const { - VPU_THROW_UNLESS(inputs.size() >= 2 && inputs.size() <= 5, - "StaticShapeNMS parsing failed, expected number of input is in range [2, 5], but {} provided", - inputs.size()); - VPU_THROW_UNLESS(outputs.size() == 2, - "StaticShapeNMS parsing failed, expected number of outputs: 2, but {} provided", - outputs.size()); + VPU_THROW_UNLESS(inputs.size() == 6, + "StaticShapeNMS with name {} parsing failed, expected number of inputs: 6, but {} provided", + layer->name, inputs.size()); + VPU_THROW_UNLESS(outputs.size() == 3, + "StaticShapeNMS with name {} parsing failed, expected number of outputs: 4, but {} provided", + layer->name, outputs.size()); + + const auto softNMSSigmaData = inputs[5]; + VPU_THROW_UNLESS(softNMSSigmaData->usage() == DataUsage::Const, + "StaticShapeNMS with name {} parsing failed: softNMSSigma should have usage {} while it actually has {}", + layer->type, DataUsage::Const, softNMSSigmaData->usage()); + VPU_THROW_UNLESS(softNMSSigmaData->desc().totalDimSize() == 1, + "StaticShapeNMS with name {} parsing failed: softNMSSigma input should contain 1 value, while it has {} values", + layer->type, softNMSSigmaData->desc().totalDimSize()); + const auto softNMSSigma = InferenceEngine::PrecisionUtils::f16tof32(softNMSSigmaData->content()->get()[0]); + VPU_THROW_UNLESS(softNMSSigma == 0, + "StaticShapeNMS with name {} parsing failed: the only supported value for softNMSSigma is 0, while it actually equal to {}", + layer->name, softNMSSigma); + + auto usedInputs = inputs; + // Erase unused softNMSSigma input + usedInputs.pop_back(); + + const auto& outIndices = outputs[0]; + const auto& outScores = outputs[1]; + const auto& outShape = outputs[2]; + + VPU_THROW_UNLESS(outScores == nullptr, + "StaticShapeNMS with name {} parsing failed: selected_scores output is not supported {}", + layer->name); const auto sortResultDescending = layer->GetParamAsBool("sort_result_descending"); - const auto boxEncoding = layer->GetParamAsString("box_encoding"); + const auto centerPointBox = layer->GetParamAsBool("center_point_box"); VPU_THROW_UNLESS(sortResultDescending == false, - "StaticShapeNMS: parameter sortResultDescending=true is not supported on VPU"); - VPU_THROW_UNLESS(boxEncoding == "corner" || boxEncoding == "center", - "StaticShapeNMS: boxEncoding currently supports only two values: \"corner\" and \"center\" " - "while {} was provided", boxEncoding); + "StaticShapeNMS with name {}: parameter sortResultDescending=true is not supported on VPU", layer->name); - DataVector tempInputs = inputs; - for (auto fake = inputs.size(); fake < 5; fake++) { - tempInputs.push_back(model->addFakeData()); - } - - auto stage = model->addNewStage(layer->name, StageType::StaticShapeNMS, layer, tempInputs, outputs); - stage->attrs().set("center_point_box", boxEncoding == "center"); + auto stage = model->addNewStage(layer->name, StageType::StaticShapeNMS, layer, usedInputs, DataVector{outIndices, outShape}); + stage->attrs().set("center_point_box", centerPointBox); } } // namespace vpu diff --git a/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp b/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp index bf111608b69..fcfaae1655e 100644 --- a/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp +++ b/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/dynamic_to_static_shape_non_max_suppression.cpp @@ -5,13 +5,16 @@ #include #include #include +#include +#include +#include #include -#include #include #include #include #include + #include #include #include @@ -22,50 +25,48 @@ using DataType = ngraph::element::Type_t; using DataDims = ngraph::Shape; struct NonMaxSuppressionTestCase { - int64_t num_batches, num_boxes, num_classes, max_output_boxes_per_class; - float iou_threshold, score_threshold; + int64_t numBatches, numBoxes, numClasses, maxOutputBoxesPerClass; + float iouThreshold, scoreThreshold, softNMSSigma; }; - class DynamicToStaticShapeNonMaxSuppression : public CommonTestUtils::TestsCommon, public testing::WithParamInterface> { public: void SetUp() override { const auto& parameters = GetParam(); - const auto& float_type = std::get<0>(parameters); - const auto& integer_type = std::get<1>(parameters); - const auto& nms_setup = std::get<2>(parameters); + const auto& floatType = std::get<0>(parameters); + const auto& integerType = std::get<1>(parameters); + const auto& nmsSetup = std::get<2>(parameters); - ngraph::helpers::CompareFunctions(*transform(float_type, integer_type, nms_setup), - *reference(float_type, integer_type, nms_setup)); + ngraph::helpers::CompareFunctions(*transform(floatType, integerType, nmsSetup), + *reference(floatType, integerType, nmsSetup)); } protected: std::shared_ptr transform( - const ngraph::element::Type_t& float_type, - const ngraph::element::Type_t& integer_type, - const NonMaxSuppressionTestCase& nms_setup) const { + const ngraph::element::Type_t& floatType, + const ngraph::element::Type_t& integerType, + const NonMaxSuppressionTestCase& nmsSetup) const { const auto boxes = std::make_shared( - float_type, ngraph::PartialShape{nms_setup.num_batches, nms_setup.num_boxes, 4}); + floatType, ngraph::PartialShape{nmsSetup.numBatches, nmsSetup.numBoxes, 4}); const auto scores = std::make_shared( - float_type, ngraph::PartialShape{nms_setup.num_batches, nms_setup.num_classes, nms_setup.num_boxes}); - const auto max_output_boxes_per_class = ngraph::opset3::Constant::create(integer_type, {}, std::vector{nms_setup.max_output_boxes_per_class}); - const auto iou_threshold = ngraph::opset3::Constant::create(float_type, ngraph::Shape{}, std::vector{nms_setup.iou_threshold}); - const auto score_threshold = ngraph::opset3::Constant::create(float_type, ngraph::Shape{}, std::vector{nms_setup.score_threshold}); + floatType, ngraph::PartialShape{nmsSetup.numBatches, nmsSetup.numClasses, nmsSetup.numBoxes}); + const auto maxOutputBoxesPerClass = ngraph::opset3::Constant::create(integerType, {}, std::vector{nmsSetup.maxOutputBoxesPerClass}); + const auto iouThreshold = ngraph::opset3::Constant::create(floatType, ngraph::Shape{}, std::vector{nmsSetup.iouThreshold}); + const auto scoreThreshold = ngraph::opset3::Constant::create(floatType, ngraph::Shape{}, std::vector{nmsSetup.scoreThreshold}); + const auto softNMSSigma = ngraph::opset3::Constant::create(floatType, ngraph::Shape{}, std::vector{nmsSetup.softNMSSigma}); const auto dims = std::make_shared(ngraph::element::i64, ngraph::Shape{3}); const auto dsr = std::make_shared(scores, dims); - const auto node = std::make_shared( - boxes, dsr, max_output_boxes_per_class, iou_threshold, score_threshold); + const auto node = std::make_shared( + boxes, dsr, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, softNMSSigma); - auto outputShape = node->get_output_partial_shape(0); const auto function = std::make_shared( - ngraph::NodeVector{node}, + ngraph::OutputVector{node->outputs()}, ngraph::ParameterVector{boxes, scores, dims}, "Actual"); - node->set_output_type(0, dsr->get_input_element_type(0), ngraph::PartialShape::dynamic(outputShape.rank())); const auto transformations = vpu::Transformations{{node->type_info, vpu::dynamicToStaticNonMaxSuppression}}; vpu::DynamicToStaticShape(transformations).run_on_function(function); @@ -73,27 +74,35 @@ protected: } std::shared_ptr reference( - const ngraph::element::Type_t& float_type, - const ngraph::element::Type_t& integer_type, - const NonMaxSuppressionTestCase& nms_setup) const { + const ngraph::element::Type_t& floatType, + const ngraph::element::Type_t& integerType, + const NonMaxSuppressionTestCase& nmsSetup) const { const auto boxes = std::make_shared( - float_type, ngraph::PartialShape{nms_setup.num_batches, nms_setup.num_boxes, 4}); + floatType, ngraph::PartialShape{nmsSetup.numBatches, nmsSetup.numBoxes, 4}); const auto scores = std::make_shared( - float_type, ngraph::PartialShape{nms_setup.num_batches, nms_setup.num_classes, nms_setup.num_boxes}); - const auto max_output_boxes_per_class = ngraph::opset3::Constant::create(integer_type, {}, std::vector{nms_setup.max_output_boxes_per_class}); - const auto iou_threshold = ngraph::opset3::Constant::create(float_type, {}, std::vector{nms_setup.iou_threshold}); - const auto score_threshold = ngraph::opset3::Constant::create(float_type, {}, std::vector{nms_setup.score_threshold}); + floatType, ngraph::PartialShape{nmsSetup.numBatches, nmsSetup.numClasses, nmsSetup.numBoxes}); + const auto maxOutputBoxesPerClass = ngraph::opset3::Constant::create(integerType, {}, std::vector{nmsSetup.maxOutputBoxesPerClass}); + const auto iouThreshold = ngraph::opset3::Constant::create(floatType, {}, std::vector{nmsSetup.iouThreshold}); + const auto scoreThreshold = ngraph::opset3::Constant::create(floatType, {}, std::vector{nmsSetup.scoreThreshold}); + const auto softNMSSigma = ngraph::opset3::Constant::create(floatType, ngraph::Shape{}, std::vector{nmsSetup.softNMSSigma}); const auto dims = std::make_shared(ngraph::element::i64, ngraph::Shape{3}); - const auto dsr = std::make_shared(scores, dims); + const auto dsrInput = std::make_shared(scores, dims); const auto node = std::make_shared( - boxes, dsr, max_output_boxes_per_class, iou_threshold, score_threshold); + boxes, dsrInput, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, softNMSSigma); + + const auto validOutputs = std::make_shared( + node->output(2), + ngraph::opset5::Constant::create(dims->get_element_type(), ngraph::Shape{1}, {0}), + ngraph::opset5::Constant::create(dims->get_element_type(), ngraph::Shape{1}, {0})); + + const auto dsrIndices = std::make_shared(node->output(0), node->output(2)); + const auto dsrScores = std::make_shared(node->output(1), node->output(2)); - const auto dsr1 = std::make_shared(node->output(0), node->output(1)); return std::make_shared( - ngraph::NodeVector{dsr1}, + ngraph::NodeVector{dsrIndices, dsrScores, validOutputs}, ngraph::ParameterVector{boxes, scores, dims}, "Expected"); } @@ -111,10 +120,10 @@ INSTANTIATE_TEST_CASE_P(smoke_NGraph, DynamicToStaticShapeNonMaxSuppression, tes ngraph::element::i64, ngraph::element::u8), testing::Values( - // num_batches, num_boxes, num_classes, max_output_boxes_per_class, iou_threshold, score_threshold - NonMaxSuppressionTestCase{1, 10, 5, 10, 0., 0.}, - NonMaxSuppressionTestCase{2, 100, 5, 10, 0., 0.}, - NonMaxSuppressionTestCase{3, 10, 5, 2, 0.5, 0.}, - NonMaxSuppressionTestCase{1, 1000, 1, 2000, 0.5, 0.}))); + // numBatches, numBoxes, numClasses, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, softNMSSigma + NonMaxSuppressionTestCase{1, 10, 5, 10, 0., 0., 0.}, + NonMaxSuppressionTestCase{2, 100, 5, 10, 0., 0., 0.}, + NonMaxSuppressionTestCase{3, 10, 5, 2, 0.5, 0., 0.}, + NonMaxSuppressionTestCase{1, 1000, 1, 2000, 0.5, 0., 0.}))); } // namespace diff --git a/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/eliminate_shapeof_after_dsr.cpp b/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/eliminate_shapeof_after_dsr.cpp index 9db676237e6..ed2ac0e2507 100644 --- a/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/eliminate_shapeof_after_dsr.cpp +++ b/inference-engine/tests/functional/plugin/myriad/ngraph/transformations/eliminate_shapeof_after_dsr.cpp @@ -54,11 +54,12 @@ protected: std::shared_ptr reference( const TensorType& dataType, const TensorShape& dataShape) const { + const auto data = std::make_shared(dataType, dataShape); const auto shape = std::make_shared(ngraph::element::i64, ngraph::Shape{dataShape.size()}); return std::make_shared( ngraph::NodeVector{shape}, - ngraph::ParameterVector{shape}, + ngraph::ParameterVector{data, shape}, "Expected"); } }; @@ -115,13 +116,14 @@ protected: std::shared_ptr reference( const TensorType& dataType, const TensorShape& dataShape) const { + const auto data = std::make_shared(dataType, dataShape); const auto shape = std::make_shared(ngraph::element::i64, ngraph::Shape{dataShape.size()}); const auto shapeRelu = std::make_shared(shape); return std::make_shared( ngraph::NodeVector{shapeRelu}, - ngraph::ParameterVector{shape}, + ngraph::ParameterVector{data, shape}, "Expected"); } }; diff --git a/inference-engine/tests/functional/plugin/myriad/single_layer_tests/static_shape_nms.cpp b/inference-engine/tests/functional/plugin/myriad/single_layer_tests/static_shape_nms.cpp index eafb984e689..f3ba04d5460 100644 --- a/inference-engine/tests/functional/plugin/myriad/single_layer_tests/static_shape_nms.cpp +++ b/inference-engine/tests/functional/plugin/myriad/single_layer_tests/static_shape_nms.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "vpu/ngraph/operations/static_shape_non_maximum_suppression.hpp" using TensorShape = InferenceEngine::SizeVector; @@ -16,7 +17,8 @@ using StaticShapeNMSParam = std::tuple< int64_t, // Number of classes int64_t, // Maximum output boxes per class float, // IOU threshold - float>; // Score threshold + float, // Score threshold + float>; // Soft NMS sigma using StaticShapeNMSTestParam = std::tuple< StaticShapeNMSParam, // NMS params @@ -66,6 +68,7 @@ protected: const auto maxOutputBoxesPerClass = std::get<3>(NMSParams); const auto iouThreshold = std::get<4>(NMSParams); const auto scoreThreshold = std::get<5>(NMSParams); + const auto softNMSSigma = std::get<6>(NMSParams); auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inPrc); @@ -79,10 +82,12 @@ protected: ngraph::element::f32, ngraph::Shape{}, iouThreshold); const auto scoreThresholdConst = std::make_shared( ngraph::element::f32, ngraph::Shape{}, scoreThreshold); + const auto softNMSSigmaConst = std::make_shared( + ngraph::element::f32, ngraph::Shape{1}, softNMSSigma); const auto staticShapeNMS = std::make_shared( - inputBoxes, inputScores, maxOutputBoxesPerClassConst, iouThresholdConst, scoreThresholdConst, - ngraph::opset3::NonMaxSuppression::BoxEncodingType::CORNER, false, ngraph::element::i32); + inputBoxes, inputScores, maxOutputBoxesPerClassConst, iouThresholdConst, scoreThresholdConst, softNMSSigmaConst, + 0, false, ngraph::element::i32); ngraph::ResultVector results{std::make_shared(staticShapeNMS->output(0)), std::make_shared(staticShapeNMS->output(1))}; @@ -95,11 +100,11 @@ TEST_P(StaticShapeNMSLayerTest, accuracy) { } std::vector NMSParams = { - std::make_tuple(1, 10, 5, 10, 0., 0.), - std::make_tuple(2, 100, 5, 10, 0., 0.), - std::make_tuple(3, 10, 5, 2, 0.5, 0.), - std::make_tuple(1, 1000, 1, 2000, 0.5, 0.), - std::make_tuple(1, 8200, 1, 8200, 0.5, 0.), + std::make_tuple(1, 10, 5, 10, 0., 0., 0.), + std::make_tuple(2, 100, 5, 10, 0., 0., 0.), + std::make_tuple(3, 10, 5, 2, 0.5, 0., 0.), + std::make_tuple(1, 1000, 1, 2000, 0.5, 0., 0.), + std::make_tuple(1, 8200, 1, 8200, 0.5, 0., 0.), }; std::vector NMSPrecisions = { diff --git a/inference-engine/tests/functional/plugin/myriad/subgraph_tests/dsr_non_max_suppression.cpp b/inference-engine/tests/functional/plugin/myriad/subgraph_tests/dsr_non_max_suppression.cpp index b28a23c60e8..36a6292fea9 100644 --- a/inference-engine/tests/functional/plugin/myriad/subgraph_tests/dsr_non_max_suppression.cpp +++ b/inference-engine/tests/functional/plugin/myriad/subgraph_tests/dsr_non_max_suppression.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include namespace { @@ -49,7 +49,7 @@ protected: const auto dims = std::make_shared(ngraph::element::i64, ngraph::Shape{3}); const auto dsr = std::make_shared(scores, dims); - const auto node = std::make_shared( + const auto node = std::make_shared( boxes, dsr, max_output_boxes_per_class, iou_threshold, score_threshold); const auto result = std::make_shared(node); diff --git a/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp b/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp index 4ab358e8631..deddabb4c50 100644 --- a/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp +++ b/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp @@ -177,8 +177,6 @@ std::vector> getConstData(const std::shared_ptr, std::shared_ptr>; - std::string toString(const NodeTypeInfo& typeInfo) { return std::string(typeInfo.name) + " ver. " + std::to_string(typeInfo.version); } @@ -195,34 +193,38 @@ void CompareNodes(const Node& actual, const Node& expected) { const auto& numActualInputs = actual.inputs().size(); const auto& numExpectedInputs = expected.inputs().size(); NGRAPH_CHECK(numActualInputs == numExpectedInputs, "Functions compare: numbers of inputs are different: ", numActualInputs, " and ", numExpectedInputs); + + const auto& numActualOutputs = actual.outputs().size(); + const auto& numExpectedOutputs = expected.outputs().size(); + NGRAPH_CHECK(numActualOutputs == numExpectedOutputs, "Functions compare: numbers of outputs are different: ", + numActualOutputs, " and ", numExpectedOutputs); } } // namespace void CompareFunctions(const Function& actual, const Function& expected) { - const auto& actualResults = actual.get_results(); - NGRAPH_CHECK(actualResults.size() == 1, "Got ", actualResults.size(), " outputs for function, but only single output functions are supported"); - const auto& actualResult = actualResults.front(); + const auto& actualOrderedOps = actual.get_ordered_ops(); + const auto& expectedOrderedOps = expected.get_ordered_ops(); - const auto& expectedResults = expected.get_results(); - NGRAPH_CHECK(expectedResults.size() == 1, "Got ", expectedResults.size(), " outputs for function, but only single output functions are supported"); - const auto& expectedResult = expectedResults.front(); + NGRAPH_CHECK(expectedOrderedOps.size() == actualOrderedOps.size(), + "Functions compare: expected and actual ops number should be equal " + "but got ", expectedOrderedOps.size(), " and ", actualOrderedOps.size(), " respectively"); - std::queue nodes; - nodes.emplace(actualResult, expectedResult); - while (!nodes.empty()) { - const auto actualNode = nodes.front().first; - const auto expectedNode = nodes.front().second; - nodes.pop(); + for (std::size_t i = 0; i < expectedOrderedOps.size(); i++) { + const auto& expectedOp = expectedOrderedOps[i]; + const auto& actualOp = actualOrderedOps[i]; - CompareNodes(*actualNode, *expectedNode); - - for (std::size_t i = 0; i < actualNode->inputs().size(); ++i) { - const auto& actualShape = actualNode->input(i).get_partial_shape(); - const auto& expectedShape = expectedNode->input(i).get_partial_shape(); + CompareNodes(*actualOp, *expectedOp); + for (std::size_t i = 0; i < actualOp->inputs().size(); ++i) { + const auto& actualShape = actualOp->input(i).get_partial_shape(); + const auto& expectedShape = expectedOp->input(i).get_partial_shape(); CompareShapes(actualShape, expectedShape); + } - nodes.emplace(actualNode->input_value(i).get_node_shared_ptr(), expectedNode->input_value(i).get_node_shared_ptr()); + for (std::size_t i = 0; i < actualOp->outputs().size(); ++i) { + const auto& actualShape = actualOp->output(i).get_partial_shape(); + const auto& expectedShape = expectedOp->output(i).get_partial_shape(); + CompareShapes(actualShape, expectedShape); } } } diff --git a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.cpp b/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.cpp deleted file mode 100644 index a8c7fc63fb9..00000000000 --- a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.cpp +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (C) 2018-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "myriad_layers_nms_test.hpp" - -INSTANTIATE_TEST_CASE_P(accuracy, myriadLayersTestsNonMaxSuppression_smoke, - ::testing::Values( - MAKE_STRUCT(NMS_testParams, - {6, 1, 1}, // {spatial_dimension, num_classes, num_batches} - 1, - {3}, - {0.5f}, - {0.f}, - { // batches - { // spatial_dimension - {0.5f, 0.5f, 1.0f, 1.0f}, // center_point_box=0 {y1, x1, y2, x2} center_point_box=1 {y0, x0, w, h} - {0.5f, 0.6f, 1.0f, 1.0f}, - {0.5f, 0.4f, 1.0f, 1.0f}, - {0.5f, 10.5f, 1.0f, 1.0f}, - {0.5f, 10.6f, 1.0f, 1.0f}, - {0.5f, 100.5f, 1.0f, 1.0f}, - }, - }, - { // batches - { // classes - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f}, // spatial_dimension - }, - }, - { // num_selected_indices - {0, 0, 3}, // {batch_index, class_index, box_index} - {0, 0, 0}, - {0, 0, 5}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 1, 1}, - 0, - {3}, - {0.5f}, - {0.f}, - { - { - {1.0f, 1.0f, 0.0f, 0.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, 0.9f, 1.0f, -0.1f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {1.0f, 10.1f, 0.0f, 11.1f}, - {1.0f, 101.0f, 0.0f, 100.0f} - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - {0, 0, 5}, - } - ), - MAKE_STRUCT(NMS_testParams, - {10, 1, 1}, - 0, - {3}, - {0.5f}, - {0.f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.0f, 1.0f, 1.0f}, - } - }, - { - { - {0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f, 0.9f} - } - }, - { - {0, 0, 0}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 1, 1}, - 0, - {2}, - {0.5f}, - {0.f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - } - ), - MAKE_STRUCT(NMS_testParams, - {1, 1, 1}, - 0, - {3}, - {0.5f}, - {0.f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - } - }, - { - { - {0.9f} - } - }, - { - {0, 0, 0}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 1, 1}, - 0, - {3}, - {0.5f}, - {0.f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - {0, 0, 5}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 1, 1}, - 0, - {3}, - {0.5f}, - {0.4f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 1, 2}, - 0, - {2}, - {0.5f}, - {0.0f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - }, - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - }, - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - {1, 0, 3}, - {1, 0, 0}, - } - ), - MAKE_STRUCT(NMS_testParams, - {6, 2, 1}, - 0, - {2}, - {0.5f}, - {0.0f}, - { - { - {0.0f, 0.0f, 1.0f, 1.0f}, - {0.0f, 0.1f, 1.0f, 1.1f}, - {0.0f, -0.1f, 1.0f, 0.9f}, - {0.0f, 10.0f, 1.0f, 11.0f}, - {0.0f, 10.1f, 1.0f, 11.1f}, - {0.0f, 100.0f, 1.0f, 101.0f}, - } - }, - { - { - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f}, - {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f} - } - }, - { - {0, 0, 3}, - {0, 0, 0}, - {0, 1, 3}, - {0, 1, 0}, - } - ) - ) -); diff --git a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.hpp b/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.hpp deleted file mode 100644 index 6acf0e7c3d7..00000000000 --- a/inference-engine/tests_deprecated/functional/vpu/common/layers/myriad_layers_nms_test.hpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (C) 2018-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "myriad_layers_tests.hpp" -#include "tests_vpu_common.hpp" - -using namespace InferenceEngine; - -typedef std::vector NMS_Dims; -typedef std::vector>> init3DFloat; -typedef std::vector initIntScalar; -typedef std::vector initFPScalar; -typedef std::vector> refType; -struct NMS_testParams { - int dims[3]; // {spat_dim, num_classes, num_batches} - int centerPointBox; - initIntScalar MaxOutBoxesPerClass; // scalar - initFPScalar IoUThreshold; // scalar - initFPScalar ScoreThreshold; // scalar - init3DFloat boxes; - init3DFloat scores; - refType referenceOutput; -}; -static std::string getModel(const int numOfInputs, const NMS_Dims &dims, const int center_point_box) { - std::string model = R"V0G0N( - - - - - - __BATCHES__ - __SPAT_DIM__ - 4 - - - - - - - __BATCHES__ - __CLASSES__ - __SPAT_DIM__ - - - )V0G0N"; - if (numOfInputs > 2) - model += R"V0G0N( - - - - 1 - - - )V0G0N"; - if (numOfInputs > 3) - model += R"V0G0N( - - - - 1 - - - )V0G0N"; - if (numOfInputs > 4) - model += R"V0G0N( - - - - 1 - - - )V0G0N"; - model += R"V0G0N( - - - - - __BATCHES__ - __SPAT_DIM__ - 4 - - - __BATCHES__ - __CLASSES__ - __SPAT_DIM__ - )V0G0N"; - if (numOfInputs > 2) - model += R"V0G0N( - - 1 - )V0G0N"; - if (numOfInputs > 3) - model += R"V0G0N( - - 1 - )V0G0N"; - if (numOfInputs > 4) - model += R"V0G0N( - - 1 - )V0G0N"; - model += R"V0G0N( - - - - __SPAT_DIM__ - 3 - - - - - - - )V0G0N"; - if (numOfInputs > 2) - model += R"V0G0N( - )V0G0N"; - if (numOfInputs > 3) - model += R"V0G0N( - )V0G0N"; - if (numOfInputs > 4) - model += R"V0G0N( - )V0G0N"; - model += R"V0G0N( - - - )V0G0N"; - - REPLACE_WITH_STR(model, "__SPAT_DIM__", std::to_string(dims[0])); - REPLACE_WITH_STR(model, "__CLASSES__", std::to_string(dims[1])); - REPLACE_WITH_STR(model, "__BATCHES__", std::to_string(dims[2])); - REPLACE_WITH_STR(model, "__CPB__", std::to_string(center_point_box)); - - return model; -} - -static void copyScalarToBlob(const Blob::Ptr& blob, const initIntScalar& scalar) { - auto *data = blob->buffer().as(); - data[0] = scalar[0]; -} - -static void copyScalarToBlob(const Blob::Ptr& blob, const initFPScalar& scalar) { - auto *data = blob->buffer().as(); - data[0] = PrecisionUtils::f32tof16(scalar[0]); -} - -static void copy3DToBlob(const Blob::Ptr& blob, const init3DFloat& src) { - auto *data = blob->buffer().as(); - const auto dims = blob->getTensorDesc().getDims(); - for (int i = 0; i < dims[0]; i++) { - for (int j = 0; j < dims[1]; j++) { - for (int k = 0; k < dims[2]; k++) { - data[i * dims[1] * dims[2] + j * dims[2] + k] = PrecisionUtils::f32tof16(src[i][j][k]); - } - } - } -} - -static void copyReference(const Blob::Ptr& blob, const refType src) { - int32_t *data = blob->buffer().as(); - const auto dims = blob->getTensorDesc().getDims(); - - int boxNum = 0; - for (; boxNum < src.size(); boxNum++) { - data[boxNum * 3 + 0] = src[boxNum][0]; - data[boxNum * 3 + 1] = src[boxNum][1]; - data[boxNum * 3 + 2] = src[boxNum][2]; - } - for (; boxNum < dims[0]; boxNum++) { - data[boxNum * 3 + 0] = -1; - data[boxNum * 3 + 1] = -1; - data[boxNum * 3 + 2] = -1; - } -} - -typedef myriadLayerTestBaseWithParam myriadLayersTestsNonMaxSuppression_smoke; - -TEST_P(myriadLayersTestsNonMaxSuppression_smoke, NonMaxSuppression) { - const auto params = GetParam(); - const int spatDim = params.dims[0]; - const int numClasses = params.dims[1]; - const int numBatches = params.dims[2]; - const int center_point_box = params.centerPointBox; - - int numOfInputs = 2; - if (!params.ScoreThreshold.empty()) - numOfInputs = 5; - else if (!params.IoUThreshold.empty()) - numOfInputs = 4; - else if (!params.MaxOutBoxesPerClass.empty()) - numOfInputs = 3; - - const auto model = getModel(numOfInputs, {spatDim, numClasses, numBatches}, center_point_box); - ASSERT_NO_THROW(readNetwork(model)); - - const auto& network = _cnnNetwork; - _inputsInfo = network.getInputsInfo(); - _inputsInfo["boxes"]->setPrecision(Precision::FP16); - _inputsInfo["scores"]->setPrecision(Precision::FP16); - if (numOfInputs > 2) - _inputsInfo["MaxOutputBoxesPerClass"]->setPrecision(Precision::I32); - if (numOfInputs > 3) - _inputsInfo["IoUThreshold"]->setPrecision(Precision::FP16); - if (numOfInputs > 4) - _inputsInfo["ScoreThreshold"]->setPrecision(Precision::FP16); - - _outputsInfo = network.getOutputsInfo(); - _outputsInfo["NMS"]->setPrecision(Precision::I32); - - StatusCode st = OK; - ASSERT_NO_THROW(st = _vpuPluginPtr->LoadNetwork(_exeNetwork, network, _config, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - ASSERT_NE(_exeNetwork, nullptr) << _resp.msg; - - ASSERT_NO_THROW(st = _exeNetwork->CreateInferRequest(_inferRequest, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - - Blob::Ptr boxesBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("boxes", boxesBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - std::cout << CheckMyriadX() << std::endl; - copy3DToBlob(boxesBlob, params.boxes); - - Blob::Ptr scoresBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("scores", scoresBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - copy3DToBlob(scoresBlob, params.scores); - - if (numOfInputs > 2) { - Blob::Ptr MaxOutputBoxesBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("MaxOutputBoxesPerClass", MaxOutputBoxesBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - copyScalarToBlob(MaxOutputBoxesBlob, params.MaxOutBoxesPerClass); - } - - if (numOfInputs > 3) { - Blob::Ptr IoUThresholdBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("IoUThreshold", IoUThresholdBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - copyScalarToBlob(IoUThresholdBlob, params.IoUThreshold); - } - - if (numOfInputs > 4) { - Blob::Ptr ScoreThresholdBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("ScoreThreshold", ScoreThresholdBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - copyScalarToBlob(ScoreThresholdBlob, params.ScoreThreshold); - } - - ASSERT_NO_THROW(st = _inferRequest->Infer(&_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - - Blob::Ptr outputBlob; - ASSERT_NO_THROW(st = _inferRequest->GetBlob("NMS", outputBlob, &_resp)); - ASSERT_EQ(StatusCode::OK, st) << _resp.msg; - - Blob::Ptr refBlob = make_shared_blob(outputBlob->getTensorDesc()); - refBlob->allocate(); - copyReference(refBlob, params.referenceOutput); - - if (memcmp(refBlob->cbuffer(), outputBlob->cbuffer(), outputBlob->byteSize())) - FAIL() << "Wrong result with compare ONNX reference!"; -}