From b20f76967ae6ba279e3f2f5dea170149b64effb3 Mon Sep 17 00:00:00 2001 From: Andrew Bakalin Date: Wed, 11 Nov 2020 13:52:42 +0300 Subject: [PATCH] [IE][VPU][Tests]: Fix NMS DTS outputs naming + tests (#3040) * Fix dynamic output case in interpreterFunction. For dynamic output cases, we can't call get_shape on the result because it's shape is dynamic, instead, we should take the real output shape from output HostTensor * Fix outputs naming as it's done in other DTS transformation for operations with multiple outputs (Split, TopK, etc). Ticket - #-42421 --- ...dynamic_to_static_shape_non_max_suppression.cpp | 6 +- .../shared_tests_instances/skip_tests_config.cpp | 2 + .../subgraph_tests/dsr_non_max_suppression.cpp | 109 +++++++++++++-------- .../ngraph_functions/src/utils/ngraph_helpers.cpp | 21 ++-- 4 files changed, 84 insertions(+), 54 deletions(-) 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 1a36939..4825eb8 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 @@ -27,14 +27,14 @@ void dynamicToStaticNonMaxSuppression(std::shared_ptr node) { 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()); + dsrIndices->set_friendly_name(nms->output(0).get_node_shared_ptr()->get_friendly_name() + ".0"); + dsrScores->set_friendly_name(nms->output(1).get_node_shared_ptr()->get_friendly_name() + ".1"); 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()); + gatherValidOutputs->set_friendly_name(nms->output(2).get_node_shared_ptr()->get_friendly_name() + ".2"); nms->output(0).replace(dsrIndices); nms->output(1).replace(dsrScores); diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/skip_tests_config.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/skip_tests_config.cpp index f649686..f1d64f0 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/skip_tests_config.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/skip_tests_config.cpp @@ -27,5 +27,7 @@ std::vector disabledTestPatterns() { R"(.*TopKLayerTest.*mode=min.*sort=index.*)", // TODO: Issue: 40961 R"(.*(ConstantResultSubgraphTest).*)", + // TODO: Issue: 42828 + R"(.*DSR_NonMaxSuppression.*NBoxes=(5|20|200).*)", }; } 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 36a6292..4235bfe 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 @@ -2,19 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 // -#include -#include +#include "dsr_tests_common.hpp" + #include #include namespace { +using namespace LayerTestsUtils::vpu; + 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; + size_t numBatches, numBoxes, upperBoundNumBoxes, numClasses, maxOutputBoxesPerClass; + float iouThreshold, scoreThreshold, softNmsSigma; }; using Parameters = std::tuple< @@ -25,36 +27,60 @@ using Parameters = std::tuple< >; class DSR_NonMaxSuppression : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon { + public DSR_TestsCommon { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj) { + DataType floatType, integerType; + NonMaxSuppressionTestCase nmsSetup; + LayerTestsUtils::TargetDevice targetDevice; + std::tie(floatType, integerType, nmsSetup, targetDevice) = obj.param; + + std::ostringstream result; + result << "FT=" << floatType << "_"; + result << "IT=" << integerType << "_"; + result << "NBatches=" << nmsSetup.numBatches << "_"; + result << "NBoxes=" << nmsSetup.numBoxes << "_"; + result << "UBNBoxes=" << nmsSetup.upperBoundNumBoxes << "_"; + result << "NC=" << nmsSetup.numClasses << "_"; + result << "MaxB=" << nmsSetup.maxOutputBoxesPerClass << "_"; + result << "IOU=" << nmsSetup.iouThreshold << "_"; + result << "ScoreT=" << nmsSetup.scoreThreshold << "_"; + result << "Sigma=" << nmsSetup.softNmsSigma << "_"; + + return result.str(); + } + protected: - void SetUp() override { + std::shared_ptr createTestedOp() 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); targetDevice = std::get<3>(parameters); - const auto boxes = std::make_shared( - float_type, ngraph::PartialShape{nms_setup.num_batches, nms_setup.num_boxes, 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 = std::make_shared( - integer_type, ngraph::Shape{}, std::vector{nms_setup.max_output_boxes_per_class}); - const auto iou_threshold = std::make_shared( - float_type, ngraph::Shape{}, std::vector{nms_setup.iou_threshold}); - const auto score_threshold = std::make_shared( - float_type, ngraph::Shape{}, std::vector{nms_setup.score_threshold}); + const auto boxes = createInputSubgraphWithDSR(floatType, DataShapeWithUpperBound{ {nmsSetup.numBatches, nmsSetup.numBoxes, 4}, + {nmsSetup.numBatches, nmsSetup.upperBoundNumBoxes, 4}}); + const auto scores = createInputSubgraphWithDSR(floatType, DataShapeWithUpperBound{ {nmsSetup.numBatches, nmsSetup.numClasses, nmsSetup.numBoxes}, + {nmsSetup.numBatches, nmsSetup.numClasses, nmsSetup.upperBoundNumBoxes}}); + const auto maxOutputBoxesPerClass = ngraph::opset5::Constant::create(integerType, ngraph::Shape{}, {nmsSetup.maxOutputBoxesPerClass}); + const auto iouThreshold = ngraph::opset5::Constant::create(floatType, ngraph::Shape{}, {nmsSetup.iouThreshold}); + const auto scoreThreshold = ngraph::opset5::Constant::create(floatType, ngraph::Shape{}, {nmsSetup.scoreThreshold}); + const auto softNmsSigma = ngraph::opset5::Constant::create(floatType, ngraph::Shape{}, {nmsSetup.softNmsSigma}); - const auto dims = std::make_shared(ngraph::element::i64, ngraph::Shape{3}); - const auto dsr = std::make_shared(scores, dims); + return std::make_shared( + boxes, scores, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, softNmsSigma, + ngraph::op::v5::NonMaxSuppression::BoxEncodingType::CENTER, false); + } - const auto node = std::make_shared( - boxes, dsr, max_output_boxes_per_class, iou_threshold, score_threshold); + void SetUp() override { + SetRefMode(LayerTestsUtils::RefMode::INTERPRETER); + configuration[InferenceEngine::MYRIAD_DETECT_NETWORK_BATCH] = CONFIG_VALUE(NO); + const auto testedOp = createTestedOp(); - const auto result = std::make_shared(node); - function = std::make_shared(ngraph::ResultVector{result}, - ngraph::ParameterVector{boxes, scores, dims}, "DSR-dynamic::NMS"); + function = std::make_shared( + ngraph::OutputVector{testedOp->output(0), testedOp->output(2)}, + m_parameterVector); } }; @@ -62,22 +88,21 @@ TEST_P(DSR_NonMaxSuppression, CompareWithReference) { Run(); } -// #-30919 -INSTANTIATE_TEST_CASE_P(DISABLED_smoke_DynamicNonMaxSupression, DSR_NonMaxSuppression, +INSTANTIATE_TEST_CASE_P(smoke_DynamicNonMaxSupression, DSR_NonMaxSuppression, ::testing::Combine( - ::testing::Values( - ngraph::element::f16, - ngraph::element::f32), - ::testing::Values( - ngraph::element::i32, - 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.}), - ::testing::Values(CommonTestUtils::DEVICE_MYRIAD))); + ::testing::Values( + ngraph::element::f16, + ngraph::element::f32), + ::testing::Values( + ngraph::element::i32, + ngraph::element::i64), + ::testing::Values( + // numBatches, numBoxes, upperBoundNumBoxes, numClasses, maxOutputBoxesPerClass, iouThreshold, scoreThreshold, softNmsSigma + NonMaxSuppressionTestCase{1, 5, 10, 5, 10, 0., 0.}, + NonMaxSuppressionTestCase{2, 20, 100, 5, 10, 0., 0.}, + NonMaxSuppressionTestCase{3, 3, 10, 5, 2, 0.5, 0.}, + NonMaxSuppressionTestCase{1, 200, 1000, 1, 2000, 0.5, 0.}), + ::testing::Values(CommonTestUtils::DEVICE_MYRIAD)), + DSR_NonMaxSuppression::getTestCaseName); } // namespace 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 591697d..89ae8e0 100644 --- a/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp +++ b/inference-engine/tests/ngraph_functions/src/utils/ngraph_helpers.cpp @@ -108,22 +108,25 @@ std::vector> interpreterFunction(const std::shared_ptr auto outputTensors = std::vector>{}; const auto &results = function->get_results(); - for (size_t i = 0; i ()); } auto handle = backend->compile(function); handle->call_with_validate(outputTensors, inputTensors); auto outputs = std::vector>(results.size()); - size_t in = 0; - for (const auto &result : results) { - const auto &resultIndex = function->get_result_index(result); - auto &output = outputs[resultIndex]; - output.resize(shape_size(result->get_shape()) * result->get_element_type().size()); + for (size_t resultIndex = 0; resultIndex < results.size(); resultIndex++) { + auto& output = outputs[resultIndex]; + const auto& outputTensor = outputTensors[resultIndex]; + output.resize(shape_size(outputTensor->get_shape()) * outputTensor->get_element_type().size()); outputTensors[resultIndex]->read(output.data(), output.size()); - if (!convertType.empty() && convertType[in] != element::Type_t::undefined && result->get_element_type() != element::Type(convertType[in])) - output = convertOutputPrecision(output, result->get_element_type(), convertType[in], shape_size(result->get_shape())); - in++; + if (!convertType.empty() && convertType[resultIndex] != element::Type_t::undefined && + outputTensor->get_element_type() != element::Type(convertType[resultIndex])) + output = convertOutputPrecision( + output, + outputTensor->get_element_type(), + convertType[resultIndex], + shape_size(outputTensors[resultIndex]->get_shape())); } return outputs; -- 2.7.4