Migrate Sort (MatrixNms-8, MulticlassNms-8, NonMaxSuppression-5) (#8394)

* Migrate Sort (MatrixNms-8, MulticlassNms-8, NonMaxSuppression-5)

* Add right multiclass_nms.cpp

* Add struct Attributes to matrix_nms

* Add constructors to opset8::MatrixNms::Attributes

* Fix code format of opset8::MatrixNms::Attributes::Attributes
This commit is contained in:
Steve Yoo 2021-11-27 04:35:43 +09:00 committed by GitHub
parent 38aebd4463
commit 42f5034892
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1568 additions and 1973 deletions

View File

@ -0,0 +1,481 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/opsets/opset8.hpp"
#include "openvino/opsets/opset1.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct MatrixNmsParams {
MatrixNmsParams(
const opset8::MatrixNms::Attributes& attrs,
const Tensor& boxes, const Tensor& scores,
const Tensor& expectedSelectedScores, const Tensor& expectedSelectedIndices,
const Tensor& expectedValidOutputs, const std::string& testcaseName = "") :
attrs(attrs),
boxes(boxes), scores(scores),
expectedSelectedScores(expectedSelectedScores), expectedSelectedIndices(expectedSelectedIndices),
expectedValidOutputs(expectedValidOutputs), testcaseName(testcaseName) {}
opset8::MatrixNms::Attributes attrs;
Tensor boxes;
Tensor scores;
Tensor expectedSelectedScores;
Tensor expectedSelectedIndices;
Tensor expectedValidOutputs;
std::string testcaseName;
};
class ReferenceMatrixNmsTest : public testing::TestWithParam<MatrixNmsParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params);
inputData = {params.boxes.data, params.scores.data};
refOutData = {params.expectedSelectedScores.data,
params.expectedSelectedIndices.data,
params.expectedValidOutputs.data};
}
static std::string getTestCaseName(const testing::TestParamInfo<MatrixNmsParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "bType=" << param.boxes.type;
result << "_bShape=" << param.boxes.shape;
result << "_sType=" << param.scores.type;
result << "_sShape=" << param.scores.shape;
result << "_escType=" << param.expectedSelectedScores.type;
result << "_escShape=" << param.expectedSelectedScores.shape;
result << "_esiType=" << param.expectedSelectedIndices.type;
result << "_esiShape=" << param.expectedSelectedIndices.shape;
result << "_evoType=" << param.expectedValidOutputs.type;
if (param.testcaseName != "") {
result << "_evoShape=" << param.expectedValidOutputs.shape;
result << "_=" << param.testcaseName;
} else {
result << "_evoShape=" << param.expectedValidOutputs.shape;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const MatrixNmsParams& params) {
const auto boxes = std::make_shared<opset1::Parameter>(params.boxes.type, PartialShape::dynamic());
const auto scores = std::make_shared<opset1::Parameter>(params.scores.type, PartialShape::dynamic());
const auto nms = std::make_shared<opset8::MatrixNms>(boxes, scores, params.attrs);
const auto f = std::make_shared<Function>(nms->outputs(), ParameterVector{boxes, scores});
return f;
}
};
TEST_P(ReferenceMatrixNmsTest, CompareWithRefs) {
Exec();
}
template <element::Type_t ET, element::Type_t ET_TH, element::Type_t ET_IND>
std::vector<MatrixNmsParams> generateParams() {
using T = typename element_type_traits<ET>::value_type;
using T_TH = typename element_type_traits<ET_TH>::value_type;
using T_IND = typename element_type_traits<ET_IND>::value_type;
std::vector<MatrixNmsParams> params {
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
0, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {3, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00,
10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1}), // expected_selected_scores
Tensor(ET_IND, {3, 1}, std::vector<T_IND>{0, 3, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{3}), // expected_valid_outputs
"matrix_nms_output_type_i64"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
0, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {3, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00,
10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1}), // expected_selected_scores
Tensor(ET_IND, {3, 1}, std::vector<T_IND>{0, 3, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{3}), // expected_valid_outputs
"matrix_nms_output_type_i32"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
0, // background_class
opset8::MatrixNms::DecayFunction::GAUSSIAN, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {3, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00,
10.00, 1.00, 11.00, 1.00, 0.1966116, 0.0, 0.1, 1.0, 1.1}), // expected_selected_scores
Tensor(ET_IND, {3, 1}, std::vector<T_IND>{0, 3, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{3}), // expected_valid_outputs
"matrix_nms_gaussian"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
0, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {6, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1}),
// expected_selected_scores
Tensor(ET_IND, {6, 1}, std::vector<T_IND>{0, 3, 1, 6, 9, 7}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{3, 3}), // expected_valid_outputs
"matrix_nms_two_batches_two_classes"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
true, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.5f, // post_threshold
true, // normalized
},
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 9, 6, 0, 6, 3, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"matrix_nms_two_batches_two_classes_by_score_cross_batch"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::CLASSID, // sort_result_type
true, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.5f, // post_threshold
true, // normalized
},
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 9, 6, 0, 3, 6, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"matrix_nms_two_batches_two_classes_by_classid_cross_batch"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::CLASSID, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
3, // keep_top_k
0, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {6, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1}),
// expected_selected_scores
Tensor(ET_IND, {6, 1}, std::vector<T_IND>{0, 3, 1, 6, 9, 7}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{3, 3}), // expected_valid_outputs
"matrix_nms_by_keep_top_k"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {6, 6}, std::vector<T_TH>{
0.00, 0.95, 0.0, 10.0, 1.0, 11.0, 1.00, 0.95, 0.0, 0.0, 1.0, 1.0, 0.00, 0.9, 0.0, 0.0, 1.0, 1.0,
1.00, 0.8, 0.0, 10.0, 1.0, 11.0, 0.00, 0.13636364, 0.0, 0.1, 1.0, 1.1, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1}),
// expected_selected_scores
Tensor(ET_IND, {6, 1}, std::vector<T_IND>{3, 0, 0, 3, 1, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{6}), // expected_valid_outputs
"matrix_nms_background"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {3, 6}, std::vector<T_TH>{
0.00, 0.95, 0.0, 10.0, 1.0, 11.0, 0.00, 0.9, 1.0, 1.0, 0.0, 0.0, 0.00, 0.75, 0.0, 0.1, 1.0, 1.1}),
// expected_selected_scores
Tensor(ET_IND, {3, 1}, std::vector<T_IND>{3, 0, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{3}), // expected_valid_outputs
"matrix_nms_flipped_coordinates"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.8f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {2, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.9, 0.00, 0.00, 1.00, 1.00}),
// expected_selected_scores
Tensor(ET_IND, {2, 1}, std::vector<T_IND>{3, 0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{2}), // expected_valid_outputs
"matrix_nms_post_threshold"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.3f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 10, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0}), // boxes
Tensor(ET_TH, {1, 1, 10}, std::vector<T_TH>{
0.4, 0.01, 0.2, 0.09, 0.15, 0.05, 0.02, 0.03, 0.05, 0.0}), // scores
Tensor(ET_TH, {1, 6}, std::vector<T_TH>{
0.00, 0.40, 0.00, 0.00, 1.00, 1.00}), // expected_selected_scores
Tensor(ET_IND, {1, 1}, std::vector<T_IND>{0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{1}), // expected_valid_outputs
"matrix_nms_identical_boxes"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
2, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {2, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00}),
// expected_selected_scores
Tensor(ET_IND, {2, 1}, std::vector<T_IND>{3, 0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{2}), // expected_valid_outputs
"matrix_nms_nms_top_k"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
0.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 1, 4}, std::vector<T>{0.0, 0.0, 1.0, 1.0}), // boxes
Tensor(ET_TH, {1, 1, 1}, std::vector<T_TH>{0.9}), // scores
Tensor(ET_TH, {1, 6}, std::vector<T_TH>{
0.00, 0.90, 0.00, 0.00, 1.00, 1.00}), // expected_selected_scores
Tensor(ET_IND, {1, 1}, std::vector<T_IND>{0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{1}), // expected_valid_outputs
"matrix_nms_single_box"),
MatrixNmsParams(
{
opset8::MatrixNms::SortResultType::SCORE, // sort_result_type
false, // sort_result_across_batch
ET_IND, // output_type
2.0f, // score_threshold
3, // nms_top_k
-1, // keep_top_k
-1, // background_class
opset8::MatrixNms::DecayFunction::LINEAR, // decay_function
2.0f, // gaussian_sigma
0.0f, // post_threshold
true, // normalized
},
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {0, 6}, std::vector<T_TH>{}), // expected_selected_scores
Tensor(ET_IND, {0, 1}, std::vector<T_IND>{}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{0}), // expected_valid_outputs
"matrix_nms_no_output"),
};
return params;
}
std::vector<MatrixNmsParams> generateCombinedParams() {
const std::vector<std::vector<MatrixNmsParams>> generatedParams {
generateParams<element::Type_t::bf16, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f16, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f32, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::bf16, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f16, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f32, element::Type_t::f32, element::Type_t::i64>(),
};
std::vector<MatrixNmsParams> combinedParams;
for (const auto& params : generatedParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(smoke_MatrixNms_With_Hardcoded_Refs, ReferenceMatrixNmsTest,
testing::ValuesIn(generateCombinedParams()), ReferenceMatrixNmsTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,567 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/multiclass_nms.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct MulticlassNmsParams {
MulticlassNmsParams(
const int nms_top_k,
const float iou_threshold,
const float score_threshold,
const op::v8::MulticlassNms::SortResultType sort_result_type,
const int keep_top_k,
const int background_class,
const float nms_eta,
const ov::element::Type output_type,
const bool sort_result_across_batch,
const bool normalized,
const Tensor& boxes, const Tensor& scores,
const Tensor& expectedSelectedScores, const Tensor& expectedSelectedIndices,
const Tensor& expectedValidOutputs, const std::string& testcaseName = "") :
nms_top_k(nms_top_k),
iou_threshold(iou_threshold),
score_threshold(score_threshold),
sort_result_type(sort_result_type),
keep_top_k(keep_top_k),
background_class(background_class),
nms_eta(nms_eta),
output_type(output_type),
sort_result_across_batch(sort_result_across_batch),
normalized(normalized),
boxes(boxes), scores(scores),
expectedSelectedScores(expectedSelectedScores), expectedSelectedIndices(expectedSelectedIndices),
expectedValidOutputs(expectedValidOutputs), testcaseName(testcaseName) {}
int nms_top_k;
float iou_threshold;
float score_threshold;
op::v8::MulticlassNms::SortResultType sort_result_type;
int keep_top_k;
int background_class;
float nms_eta;
ov::element::Type output_type;
bool sort_result_across_batch = false;
bool normalized = true;
Tensor boxes;
Tensor scores;
Tensor expectedSelectedScores;
Tensor expectedSelectedIndices;
Tensor expectedValidOutputs;
std::string testcaseName;
};
class ReferenceMulticlassNmsTest : public testing::TestWithParam<MulticlassNmsParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params);
inputData = {params.boxes.data, params.scores.data};
refOutData = {params.expectedSelectedScores.data,
params.expectedSelectedIndices.data,
params.expectedValidOutputs.data};
}
static std::string getTestCaseName(const testing::TestParamInfo<MulticlassNmsParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "bType=" << param.boxes.type;
result << "_bShape=" << param.boxes.shape;
result << "_sType=" << param.scores.type;
result << "_sShape=" << param.scores.shape;
result << "_escType=" << param.expectedSelectedScores.type;
result << "_escShape=" << param.expectedSelectedScores.shape;
result << "_esiType=" << param.expectedSelectedIndices.type;
result << "_esiShape=" << param.expectedSelectedIndices.shape;
result << "_evoType=" << param.expectedValidOutputs.type;
if (param.testcaseName != "") {
result << "_evoShape=" << param.expectedValidOutputs.shape;
result << "_=" << param.testcaseName;
} else {
result << "_evoShape=" << param.expectedValidOutputs.shape;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const MulticlassNmsParams& params) {
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = params.nms_top_k;
attrs.iou_threshold = params.iou_threshold;
attrs.score_threshold = params.score_threshold;
attrs.sort_result_type = params.sort_result_type;
attrs.keep_top_k = params.keep_top_k;
attrs.background_class = params.background_class;
attrs.nms_eta = params.nms_eta;
attrs.output_type = params.output_type;
attrs.sort_result_across_batch = params.sort_result_across_batch;
attrs.normalized = params.normalized;
const auto boxes = std::make_shared<op::v0::Parameter>(params.boxes.type, PartialShape::dynamic());
const auto scores = std::make_shared<op::v0::Parameter>(params.scores.type, PartialShape::dynamic());
const auto nms = std::make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
const auto f = std::make_shared<Function>(nms->outputs(), ParameterVector{boxes, scores});
return f;
}
};
TEST_P(ReferenceMulticlassNmsTest, CompareWithRefs) {
Exec();
}
template <element::Type_t ET, element::Type_t ET_TH, element::Type_t ET_IND>
std::vector<MulticlassNmsParams> generateParams() {
using T = typename element_type_traits<ET>::value_type;
using T_TH = typename element_type_traits<ET_TH>::value_type;
using T_IND = typename element_type_traits<ET_IND>::value_type;
std::vector<MulticlassNmsParams> params {
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {4, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95,
0.00, 0.00, 1.00, 1.00, 0.00, 0.90, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {4, 1}, std::vector<T_IND>{3, 0, 0, 3}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{4}), // expected_valid_outputs
"multiclass_nms_by_score"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {4, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90,
0.00, 0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {4, 1}, std::vector<T_IND>{3, 0, 0, 3}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{4}), // expected_valid_outputs
"multiclass_nms_by_class_id"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {4, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90,
0.00, 0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {4, 1}, std::vector<T_IND>{3, 0, 0, 3}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{4}), // expected_valid_outputs
"multiclass_nms_output_type_i32"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}),
// expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 0, 3, 9, 6, 6, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"multiclass_nms_two_batches_two_classes_by_score"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}),
// expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 0, 3, 9, 6, 6, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"multiclass_nms_two_batches_two_classes_by_class_id"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
true, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 9, 6, 0, 6, 3, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"multiclass_nms_two_batches_two_classes_by_score_cross_batch"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
true, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {8, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {8, 1}, std::vector<T_IND>{3, 0, 9, 6, 0, 3, 6, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{4, 4}), // expected_valid_outputs
"multiclass_nms_two_batches_two_classes_by_class_id_cross_batch"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {3, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 1.00, 1.00, 0.00, 0.00, 0.00, 0.75, 0.00, 0.10, 1.00, 1.10}),
// expected_selected_scores
Tensor(ET_IND, {3, 1}, std::vector<T_IND>{3, 0, 1}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{3}), // expected_valid_outputs
"multiclass_nms_flipped_coordinates"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 10, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0}), // boxes
Tensor(ET_TH, {1, 1, 10}, std::vector<T_TH>{
0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}), // scores
Tensor(ET_TH, {1, 6}, std::vector<T_TH>{
0.00, 0.90, 0.00, 0.00, 1.00, 1.00}),
// expected_selected_scores
Tensor(ET_IND, {1, 1}, std::vector<T_IND>{0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{1}), // expected_valid_outputs
"multiclass_nms_identical_boxes"),
MulticlassNmsParams(
2, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {2, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00}),
// expected_selected_scores
Tensor(ET_IND, {2, 1}, std::vector<T_IND>{3, 0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{2}), // expected_valid_outputs
"multiclass_nms_limit_output_size"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 1, 4}, std::vector<T>{0.0, 0.0, 1.0, 1.0}), // boxes
Tensor(ET_TH, {1, 1, 1}, std::vector<T_TH>{0.9}), // scores
Tensor(ET_TH, {1, 6}, std::vector<T_TH>{
0.00, 0.90, 0.00, 0.00, 1.00, 1.00}), // expected_selected_scores
Tensor(ET_IND, {1, 1}, std::vector<T_IND>{0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{1}), // expected_valid_outputs
"multiclass_nms_single_box"),
MulticlassNmsParams(
3, // nms_top_k
0.2f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {2, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00}),
// expected_selected_scores
Tensor(ET_IND, {2, 1}, std::vector<T_IND>{3, 0}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{2}), // expected_valid_outputs
"multiclass_nms_by_IOU"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.95f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {1, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00}), // expected_selected_scores
Tensor(ET_IND, {1, 1}, std::vector<T_IND>{3}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{1}), // expected_valid_outputs
"multiclass_nms_by_IOU_and_scores"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
2.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::SCORE, // sort_result_type
-1, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {1, 1, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}), // scores
Tensor(ET_TH, {0, 6}, std::vector<T_TH>{}), // expected_selected_scores
Tensor(ET_IND, {0, 1}, std::vector<T_IND>{}), // expected_selected_indices
Tensor(ET_IND, {1}, std::vector<T_IND>{0}), // expected_valid_outputs
"multiclass_nms_no_output"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
0, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {4, 6}, std::vector<T_TH>{
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}),
// expected_selected_scores
Tensor(ET_IND, {4, 1}, std::vector<T_IND>{0, 3, 6, 9}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{2, 2}), // expected_valid_outputs
"multiclass_nms_by_background"),
MulticlassNmsParams(
3, // nms_top_k
0.5f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
3, // keep_top_k
-1, // background_class
1.0f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {6, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00}), // expected_selected_scores
Tensor(ET_IND, {6, 1}, std::vector<T_IND>{3, 0, 0, 9, 6, 6}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{3, 3}), // expected_valid_outputs
"multiclass_nms_by_keep_top_k"),
MulticlassNmsParams(
-1, // nms_top_k
1.0f, // iou_threshold
0.0f, // score_threshold
op::v8::MulticlassNms::SortResultType::CLASSID, // sort_result_type
-1, // keep_top_k
-1, // background_class
0.1f, // nms_eta
ET_IND, // output_type
false, // sort_result_across_batch
true, // normalized
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}), // boxes
Tensor(ET_TH, {2, 2, 6}, std::vector<T_TH>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3,
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}), // scores
Tensor(ET_TH, {12, 6}, std::vector<T_TH>{
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 0.00, 0.30, 0.00,
100.00, 1.00, 101.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.30, 0.00, 100.00, 1.00, 101.00, 0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 0.00, 0.30, 0.00, 100.00, 1.00, 101.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, 1.00, 0.30, 0.00, 100.00, 1.00, 101.00}),
// expected_selected_scores
Tensor(ET_IND, {12, 1}, std::vector<T_IND>{
3, 0, 5, 0, 3, 5, 9, 6, 11, 6, 9, 11}), // expected_selected_indices
Tensor(ET_IND, {2}, std::vector<T_IND>{6, 6}), // expected_valid_outputs
"multiclass_nms_by_nms_eta"),
};
return params;
}
std::vector<MulticlassNmsParams> generateCombinedParams() {
const std::vector<std::vector<MulticlassNmsParams>> generatedParams {
generateParams<element::Type_t::bf16, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f16, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f32, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::bf16, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f16, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f32, element::Type_t::f32, element::Type_t::i64>(),
};
std::vector<MulticlassNmsParams> combinedParams;
for (const auto& params : generatedParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(smoke_MulticlassNms_With_Hardcoded_Refs, ReferenceMulticlassNmsTest,
testing::ValuesIn(generateCombinedParams()), ReferenceMulticlassNmsTest::getTestCaseName);
} // namespace

View File

@ -0,0 +1,489 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "openvino/op/non_max_suppression.hpp"
#include "openvino/op/constant.hpp"
#include "base_reference_test.hpp"
using namespace reference_tests;
using namespace ov;
namespace {
struct NonMaxSuppressionParams {
NonMaxSuppressionParams(
const Tensor& boxes, const Tensor& scores,
const Tensor& maxOutputBoxesPerClass, const Tensor& iouThreshold, const Tensor& scoreThreshold,
const Tensor& softNmsSigma, const op::v5::NonMaxSuppression::BoxEncodingType boxEncoding,
const Tensor& expectedSelectedIndices, const Tensor& expectedSelectedScores,
const Tensor& expectedValidOutputs, const std::string& testcaseName = "") :
boxes(boxes), scores(scores),
maxOutputBoxesPerClass(maxOutputBoxesPerClass), iouThreshold(iouThreshold), scoreThreshold(scoreThreshold),
softNmsSigma(softNmsSigma), boxEncoding(boxEncoding),
expectedSelectedIndices(expectedSelectedIndices), expectedSelectedScores(expectedSelectedScores),
expectedValidOutputs(expectedValidOutputs), testcaseName(testcaseName) {}
Tensor boxes;
Tensor scores;
Tensor maxOutputBoxesPerClass;
Tensor iouThreshold;
Tensor scoreThreshold;
Tensor softNmsSigma;
op::v5::NonMaxSuppression::BoxEncodingType boxEncoding;
Tensor expectedSelectedIndices;
Tensor expectedSelectedScores;
Tensor expectedValidOutputs;
std::string testcaseName;
};
class ReferenceNonMaxSuppressionTest : public testing::TestWithParam<NonMaxSuppressionParams>, public CommonReferenceTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params);
inputData = {params.boxes.data, params.scores.data};
refOutData = {params.expectedSelectedIndices.data,
params.expectedSelectedScores.data,
params.expectedValidOutputs.data};
}
static std::string getTestCaseName(const testing::TestParamInfo<NonMaxSuppressionParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "bType=" << param.boxes.type;
result << "_bShape=" << param.boxes.shape;
result << "_sType=" << param.scores.type;
result << "_sShape=" << param.scores.shape;
result << "_escType=" << param.expectedSelectedScores.type;
result << "_escShape=" << param.expectedSelectedScores.shape;
result << "_esiType=" << param.expectedSelectedIndices.type;
result << "_esiShape=" << param.expectedSelectedIndices.shape;
result << "_evoType=" << param.expectedValidOutputs.type;
if (param.testcaseName != "") {
result << "_evoShape=" << param.expectedValidOutputs.shape;
result << "_=" << param.testcaseName;
} else {
result << "_evoShape=" << param.expectedValidOutputs.shape;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const NonMaxSuppressionParams& params) {
const auto boxes = std::make_shared<op::v0::Parameter>(params.boxes.type, params.boxes.shape);
const auto scores = std::make_shared<op::v0::Parameter>(params.scores.type, params.scores.shape);
const auto max_output_boxes_per_class = std::make_shared<op::v0::Constant>(
params.maxOutputBoxesPerClass.type, params.maxOutputBoxesPerClass.shape, params.maxOutputBoxesPerClass.data.data());
const auto iou_threshold = std::make_shared<op::v0::Constant>(
params.iouThreshold.type, params.iouThreshold.shape, params.iouThreshold.data.data());
const auto score_threshold = std::make_shared<op::v0::Constant>(
params.scoreThreshold.type, params.scoreThreshold.shape, params.scoreThreshold.data.data());
const auto soft_nms_sigma = std::make_shared<op::v0::Constant>(
params.softNmsSigma.type, params.softNmsSigma.shape, params.softNmsSigma.data.data());
const auto nms = std::make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
params.boxEncoding,
false);
const auto f = std::make_shared<Function>(nms->outputs(), ParameterVector{boxes, scores});
return f;
}
};
class ReferenceNonMaxSuppressionTestWithoutConstants : public ReferenceNonMaxSuppressionTest {
public:
void SetUp() override {
auto params = GetParam();
function = CreateFunction(params);
inputData = {params.boxes.data, params.scores.data, params.maxOutputBoxesPerClass.data,
params.iouThreshold.data, params.scoreThreshold.data, params.softNmsSigma.data};
refOutData = {params.expectedSelectedIndices.data,
params.expectedSelectedScores.data,
params.expectedValidOutputs.data};
}
static std::string getTestCaseName(const testing::TestParamInfo<NonMaxSuppressionParams>& obj) {
auto param = obj.param;
std::ostringstream result;
result << "bType=" << param.boxes.type;
result << "_bShape=" << param.boxes.shape;
result << "_sType=" << param.scores.type;
result << "_sShape=" << param.scores.shape;
result << "_escType=" << param.expectedSelectedScores.type;
result << "_escShape=" << param.expectedSelectedScores.shape;
result << "_esiType=" << param.expectedSelectedIndices.type;
result << "_esiShape=" << param.expectedSelectedIndices.shape;
result << "_evoType=" << param.expectedValidOutputs.type;
if (param.testcaseName != "") {
result << "_evoShape=" << param.expectedValidOutputs.shape;
result << "_=" << param.testcaseName;
} else {
result << "_evoShape=" << param.expectedValidOutputs.shape;
}
return result.str();
}
private:
static std::shared_ptr<Function> CreateFunction(const NonMaxSuppressionParams& params) {
const auto boxes = std::make_shared<op::v0::Parameter>(params.boxes.type, params.boxes.shape);
const auto scores = std::make_shared<op::v0::Parameter>(params.scores.type, params.scores.shape);
const auto max_output_boxes_per_class = std::make_shared<op::v0::Parameter>(
params.maxOutputBoxesPerClass.type, params.maxOutputBoxesPerClass.shape);
const auto iou_threshold = std::make_shared<op::v0::Parameter>(
params.iouThreshold.type, params.iouThreshold.shape);
const auto score_threshold = std::make_shared<op::v0::Parameter>(
params.scoreThreshold.type, params.scoreThreshold.shape);
const auto soft_nms_sigma = std::make_shared<op::v0::Parameter>(
params.softNmsSigma.type, params.softNmsSigma.shape);
const auto nms = std::make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
params.boxEncoding,
false);
const auto f = std::make_shared<Function>(nms->outputs(),
ParameterVector{boxes, scores, max_output_boxes_per_class,
iou_threshold, score_threshold, soft_nms_sigma});
return f;
}
};
TEST_P(ReferenceNonMaxSuppressionTest, CompareWithRefs) {
Exec();
}
TEST_P(ReferenceNonMaxSuppressionTestWithoutConstants, CompareWithRefs) {
Exec();
}
template <element::Type_t ET, element::Type_t ET_BOX, element::Type_t ET_TH, element::Type_t ET_IND>
std::vector<NonMaxSuppressionParams> generateParams() {
using T = typename element_type_traits<ET>::value_type;
using T_BOX = typename element_type_traits<ET_BOX>::value_type;
using T_TH = typename element_type_traits<ET_TH>::value_type;
using T_IND = typename element_type_traits<ET_IND>::value_type;
std::vector<NonMaxSuppressionParams> params {
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0,
0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CENTER,
// selected_indices
Tensor(ET_IND, {3, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0, 0, 0, 5}),
// selected_scores
Tensor(ET_TH, {3, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{3}),
"nonmaxsuppression_center_point_box_format"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {3, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0, 0, 0, 5}),
// selected_scores
Tensor(ET_TH, {3, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{3}),
"nonmaxsuppression_flipped_coordinates"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 10, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0}),
// scores
Tensor(ET, {1, 1, 10}, std::vector<T>{
0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {1, 3}, std::vector<T_IND>{0, 0, 0}),
// selected_scores
Tensor(ET_TH, {1, 3}, std::vector<T_TH>{0.0, 0.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{1}),
"nonmaxsuppression_identical_boxes"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{2}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {2, 3}, std::vector<T_IND>{0, 0, 3, 0, 0, 0}),
// selected_scores
Tensor(ET_TH, {2, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{2}),
"nonmaxsuppression_limit_output_size"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 1, 4}, std::vector<T>{0.0, 0.0, 1.0, 1.0}),
// scores
Tensor(ET, {1, 1, 1}, std::vector<T>{0.9}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {1, 3}, std::vector<T_IND>{0, 0, 0}),
// selected_scores
Tensor(ET_TH, {1, 3}, std::vector<T_TH>{0.0, 0.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{1}),
"nonmaxsuppression_single_box"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {3, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0, 0, 0, 5}),
// selected_scores
Tensor(ET_TH, {3, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{3}),
"nonmaxsuppression_suppress_by_IOU"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{3}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.4f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {2, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0}),
// selected_scores
Tensor(ET_TH, {2, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{2}),
"nonmaxsuppression_suppress_by_IOU_and_scores"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {2, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}),
// scores
Tensor(ET, {2, 1, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{2}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {4, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0, 1, 0, 3, 1, 0, 0}),
// selected_scores
Tensor(ET_TH, {4, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 1.0, 0.0, 0.95, 1.0, 0.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{4}),
"nonmaxsuppression_two_batches"),
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}),
// scores
Tensor(ET, {1, 2, 6}, std::vector<T>{
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3}),
// max_output_boxes_per_class
Tensor(ET_BOX, {}, std::vector<T_BOX>{2}),
// iou_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.5f}),
// score_threshold
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// soft_nms_sigma
Tensor(ET_TH, {}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {4, 3}, std::vector<T_IND>{
0, 0, 3, 0, 0, 0, 0, 1, 3, 0, 1, 0}),
// selected_scores
Tensor(ET_TH, {4, 3}, std::vector<T_TH>{
0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 1.0, 0.95, 0.0, 1.0, 0.9}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{4}),
"nonmaxsuppression_two_classes"),
};
return params;
}
std::vector<NonMaxSuppressionParams> generateCombinedParams() {
const std::vector<std::vector<NonMaxSuppressionParams>> generatedParams {
generateParams<element::Type_t::bf16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::f32, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParams<element::Type_t::bf16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
generateParams<element::Type_t::f32, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
};
std::vector<NonMaxSuppressionParams> combinedParams;
for (const auto& params : generatedParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
template <element::Type_t ET, element::Type_t ET_BOX, element::Type_t ET_TH, element::Type_t ET_IND>
std::vector<NonMaxSuppressionParams> generateParamsWithoutConstants() {
using T = typename element_type_traits<ET>::value_type;
using T_BOX = typename element_type_traits<ET_BOX>::value_type;
using T_TH = typename element_type_traits<ET_TH>::value_type;
using T_IND = typename element_type_traits<ET_IND>::value_type;
std::vector<NonMaxSuppressionParams> params {
NonMaxSuppressionParams(
// boxes
Tensor(ET, {1, 6, 4}, std::vector<T>{
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}),
// scores
Tensor(ET, {1, 1, 6}, std::vector<T>{
0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f}),
// max_output_boxes_per_class
Tensor(ET_BOX, {1}, std::vector<T_BOX>{1}),
// iou_threshold
Tensor(ET_TH, {1}, std::vector<T_TH>{0.4f}),
// score_threshold
Tensor(ET_TH, {1}, std::vector<T_TH>{0.2f}),
// soft_nms_sigma
Tensor(ET_TH, {1}, std::vector<T_TH>{0.0f}),
// box_encoding
op::v5::NonMaxSuppression::BoxEncodingType::CORNER,
// selected_indices
Tensor(ET_IND, {1, 3}, std::vector<T_IND>{0, 0, 3}),
// selected_scores
Tensor(ET_TH, {1, 3}, std::vector<T_TH>{0.0f, 0.0f, 0.95f}),
// valid_outputs
Tensor(ET_IND, {1}, std::vector<T_IND>{1}),
"nonmaxsuppression_suppress_by_IOU_and_scores_without_constants"),
};
return params;
}
std::vector<NonMaxSuppressionParams> generateCombinedParamsWithoutConstants() {
const std::vector<std::vector<NonMaxSuppressionParams>> generatedParams {
generateParamsWithoutConstants<element::Type_t::bf16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParamsWithoutConstants<element::Type_t::f16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParamsWithoutConstants<element::Type_t::f32, element::Type_t::i32, element::Type_t::f32, element::Type_t::i32>(),
generateParamsWithoutConstants<element::Type_t::bf16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
generateParamsWithoutConstants<element::Type_t::f16, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
generateParamsWithoutConstants<element::Type_t::f32, element::Type_t::i32, element::Type_t::f32, element::Type_t::i64>(),
};
std::vector<NonMaxSuppressionParams> combinedParams;
for (const auto& params : generatedParams) {
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
}
return combinedParams;
}
INSTANTIATE_TEST_SUITE_P(smoke_NonMaxSuppression_With_Hardcoded_Refs, ReferenceNonMaxSuppressionTest,
testing::ValuesIn(generateCombinedParams()), ReferenceNonMaxSuppressionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_NonMaxSuppression_With_Hardcoded_Refs, ReferenceNonMaxSuppressionTestWithoutConstants,
testing::ValuesIn(generateCombinedParamsWithoutConstants()), ReferenceNonMaxSuppressionTest::getTestCaseName);
} // namespace

View File

@ -100,6 +100,12 @@ std::vector<std::string> disabledTestPatterns() {
R"(.*ReferenceTopKTest.*aType=f64.*)",
// CVS-63947
R"(.*ReferenceConcatTest.*concat_zero_.*)",
// CVS-64119
R"(.*ReferenceMatrixNmsTest.*esiType=i64.*evoType=i64.*)",
// CVS-64121
R"(.*ReferenceMulticlassNmsTest.*esiType=i64.*evoType=i64.*)",
// CVS-64096
R"(.*ReferenceNonMaxSuppressionTest.*esiType=i32.*evoType=i32.*)",
};
#ifdef _WIN32

View File

@ -45,6 +45,31 @@ public:
float post_threshold = 0.0f;
// specifies whether boxes are normalized or not
bool normalized = true;
Attributes() {}
Attributes(op::v8::MatrixNms::SortResultType sort_result_type,
bool sort_result_across_batch,
ov::element::Type output_type,
float score_threshold,
int nms_top_k,
int keep_top_k,
int background_class,
op::v8::MatrixNms::DecayFunction decay_function,
float gaussian_sigma,
float post_threshold,
bool normalized)
: sort_result_type(sort_result_type),
sort_result_across_batch(sort_result_across_batch),
output_type(output_type),
score_threshold(score_threshold),
nms_top_k(nms_top_k),
keep_top_k(keep_top_k),
background_class(background_class),
decay_function(decay_function),
gaussian_sigma(gaussian_sigma),
post_threshold(post_threshold),
normalized(normalized) {}
};
MatrixNms();

View File

@ -492,12 +492,9 @@ set(MULTI_TEST_SRC
backend/experimental_detectron_prior_grid.in.cpp
backend/function_name.in.cpp
backend/interpolate.in.cpp
backend/matrix_nms.in.cpp
backend/multiclass_nms.in.cpp
backend/multiple_backends.in.cpp
backend/multiple_result.in.cpp
backend/node_name.in.cpp
backend/non_max_suppression.in.cpp
backend/region_yolo.in.cpp
backend/sqrt.in.cpp
backend/unhandled_op.in.cpp

View File

@ -1,597 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
// clang-format off
#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#endif
#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#endif
// clang-format on
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "engines_util/test_engines.hpp"
#include "engines_util/test_case.hpp"
#include "util/test_control.hpp"
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_output_type_i64) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = 0;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0, 3, 1};
std::vector<float> expected_selected_scores =
{1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({3, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({3, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_output_type_i32) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = 0;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
attrs.output_type = ngraph::element::i32;
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int32_t> expected_selected_indices = {0, 3, 1};
std::vector<float> expected_selected_scores =
{1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1};
std::vector<int32_t> expected_valid_outputs = {3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({3, 6}, expected_selected_scores);
test_case.add_expected_output<int32_t>({3, 1}, expected_selected_indices);
test_case.add_expected_output<int32_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_gaussian) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = 0;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::GAUSSIAN;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0, 3, 1};
std::vector<float> expected_selected_scores =
{1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.1966116, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({3, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({3, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_two_batches_two_classes) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; // 1
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}; // 1
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = 0;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0, 3, 1, 6, 9, 7};
std::vector<float> expected_selected_scores = {
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {3, 3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({6, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({6, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_two_batches_two_classes_by_score_cross_batch) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; // 1
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}; // 1
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.5;
attrs.sort_result_across_batch = true;
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 9, 6, 0, 6, 3, 9};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 9
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 6
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 9
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_two_batches_two_classes_by_classid_cross_batch) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; // 1
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}; // 1
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.5;
attrs.sort_result_across_batch = true;
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 9, 6, 0, 3, 6, 9};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 3
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 9
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 0
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 9
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_by_keep_top_k) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0}; // 1
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3}; // 1
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::CLASSID;
attrs.keep_top_k = 3;
attrs.background_class = 0;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0, 3, 1, 6, 9, 7};
std::vector<float> expected_selected_scores = {
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.8, 0.00, 10.00, 1.00, 11.00, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {3, 3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({6, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({6, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_background) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 3, 1, 1};
std::vector<float> expected_selected_scores = {
0.00, 0.95, 0.0, 10.0, 1.0, 11.0, 1.00, 0.95, 0.0, 0.0, 1.0, 1.0, 0.00, 0.9, 0.0, 0.0, 1.0, 1.0,
1.00, 0.8, 0.0, 10.0, 1.0, 11.0, 0.00, 0.13636364, 0.0, 0.1, 1.0, 1.1, 1.00, 0.13636364, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {6};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({6, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({6, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_flipped_coordinates) {
std::vector<float> boxes_data = {1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 1, M 6
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 1};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.0, 10.0, 1.0, 11.0, 0.00, 0.9, 1.0, 1.0, 0.0, 0.0, 0.00, 0.75, 0.0, 0.1, 1.0, 1.1};
std::vector<int64_t> expected_valid_outputs = {3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({3, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({3, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_post_threshold) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.00;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.8;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.9, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {2};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({2, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({2, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_identical_boxes) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.4, 0.01, 0.2, 0.09, 0.15, 0.05, 0.02, 0.03, 0.05, 0.0};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 10, 4}; // N 1, C 1, M 10
const auto scores_shape = Shape{1, 1, 10};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.3;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0};
std::vector<float> expected_selected_scores = {0.00, 0.40, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {1};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({1, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({1, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_nms_top_k) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 2;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {2};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({2, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({2, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_single_box) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.9};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 1, 4};
const auto scores_shape = Shape{1, 1, 1};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0};
std::vector<float> expected_selected_scores = {0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {1};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({1, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({1, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, matrix_nms_no_output) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MatrixNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.score_threshold = 2.0f;
attrs.sort_result_type = op::v8::MatrixNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
attrs.decay_function = op::v8::MatrixNms::DecayFunction::LINEAR;
attrs.gaussian_sigma = 2.0f;
attrs.post_threshold = 0.0f;
auto nms = make_shared<op::v8::MatrixNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {};
std::vector<float> expected_selected_scores = {};
std::vector<int64_t> expected_valid_outputs = {0};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({0, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({0, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}

View File

@ -1,735 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
// clang-format off
#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#endif
#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#endif
// clang-format on
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "engines_util/test_engines.hpp"
#include "engines_util/test_case.hpp"
#include "util/test_control.hpp"
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_score) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 3};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95,
0.00, 0.00, 1.00, 1.00, 0.00, 0.90, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00};
std::vector<int64_t> expected_valid_outputs = {4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({4, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({4, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_class_id) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 3};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90,
0.00, 0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00};
std::vector<int64_t> expected_valid_outputs = {4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({4, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({4, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_output_type_i32) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
attrs.output_type = element::i32;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 2, M 6
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int32_t> expected_selected_indices = {3, 0, 0, 3};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90,
0.00, 0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00,
1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00};
std::vector<int32_t> expected_valid_outputs = {4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({4, 6}, expected_selected_scores);
test_case.add_expected_output<int32_t>({4, 1}, expected_selected_indices);
test_case.add_expected_output<int32_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_two_batches_two_classes_by_score) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 3, 9, 6, 6, 9};
std::vector<float> expected_selected_scores = {
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 1
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_two_batches_two_classes_by_class_id) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 3, 9, 6, 6, 9};
std::vector<float> expected_selected_scores = {
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00,
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 1
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_two_batches_two_classes_by_score_cross_batch) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
attrs.sort_result_across_batch = true;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 9, 6, 0, 6, 3, 9};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 9
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 6
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 9
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_two_batches_two_classes_by_class_id_cross_batch) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
attrs.sort_result_across_batch = true;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 9, 6, 0, 3, 6, 9};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 3
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, // 9
0.00, 0.90, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 0
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 3
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 6
1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 9
std::vector<int64_t> expected_valid_outputs = {4, 4};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({8, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({8, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_flipped_coordinates) {
std::vector<float> boxes_data = {1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4}; // N 1, C 1, M 6
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 1};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 1.00, 1.00, 0.00, 0.00, 0.00, 0.75, 0.00, 0.10, 1.00, 1.10};
std::vector<int64_t> expected_valid_outputs = {3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({3, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({3, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_identical_boxes) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 10, 4}; // N 1, C 1, M 10
const auto scores_shape = Shape{1, 1, 10};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0};
std::vector<float> expected_selected_scores = {0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {1};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({1, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({1, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_limit_output_size) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 2;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {2};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({2, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({2, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_single_box) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.9};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 1, 4};
const auto scores_shape = Shape{1, 1, 1};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0};
std::vector<float> expected_selected_scores = {0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {1};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({1, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({1, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_IOU) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.2f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0};
std::vector<float> expected_selected_scores =
{0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00};
std::vector<int64_t> expected_valid_outputs = {2};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({2, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({2, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_IOU_and_scores) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.95f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00};
std::vector<int64_t> expected_valid_outputs = {1};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({1, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({1, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_no_output) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 2.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::SCORE;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {};
std::vector<float> expected_selected_scores = {};
std::vector<int64_t> expected_valid_outputs = {0};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({0, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({0, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({1}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_background) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = 0;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {0, 3, 6, 9};
std::vector<float> expected_selected_scores = {
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00, // 0
1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00}; // 1
std::vector<int64_t> expected_valid_outputs = {2, 2};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({4, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({4, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_keep_top_k) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = 3;
attrs.iou_threshold = 0.5f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = 3;
attrs.background_class = -1;
attrs.nms_eta = 1.0f;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 0, 9, 6, 6};
std::vector<float> expected_selected_scores = {0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00, // 0
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00}; // 1
std::vector<int64_t> expected_valid_outputs = {3, 3};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({6, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({6, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}
NGRAPH_TEST(${BACKEND_NAME}, multiclass_nms_by_nms_eta) {
std::vector<float> boxes_data = {
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0, // 0
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0 // 1
};
std::vector<float> scores_data = {
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3, // 0
0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.95, 0.75, 0.6, 0.80, 0.5, 0.3 // 1
};
op::v8::MulticlassNms::Attributes attrs;
attrs.nms_top_k = -1;
attrs.iou_threshold = 1.0f;
attrs.score_threshold = 0.0f;
attrs.sort_result_type = op::v8::MulticlassNms::SortResultType::CLASSID;
attrs.keep_top_k = -1;
attrs.background_class = -1;
attrs.nms_eta = 0.1f;
const auto boxes_shape = Shape{2, 6, 4}; // N 2, C 2, M 6
const auto scores_shape = Shape{2, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto nms = make_shared<op::v8::MulticlassNms>(boxes, scores, attrs);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
std::vector<int64_t> expected_selected_indices = {3, 0, 5, 0, 3, 5, 9, 6, 11, 6, 9, 11};
std::vector<float> expected_selected_scores = {
0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00, 0.00, 1.00, 1.00, 0.00, 0.30, 0.00,
100.00, 1.00, 101.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00, 1.00, 0.80, 0.00, 10.00, 1.00, 11.00,
1.00, 0.30, 0.00, 100.00, 1.00, 101.00, 0.00, 0.95, 0.00, 10.00, 1.00, 11.00, 0.00, 0.90, 0.00,
0.00, 1.00, 1.00, 0.00, 0.30, 0.00, 100.00, 1.00, 101.00, 1.00, 0.95, 0.00, 0.00, 1.00, 1.00,
1.00, 0.80, 0.00, 10.00, 1.00, 11.00, 1.00, 0.30, 0.00, 100.00, 1.00, 101.00};
std::vector<int64_t> expected_valid_outputs = {6, 6};
auto test_case = test::TestCase<TestEngine, test::TestCaseType::DYNAMIC>(f);
test_case.add_multiple_inputs<float>({boxes_data, scores_data});
test_case.add_expected_output<float>({12, 6}, expected_selected_scores);
test_case.add_expected_output<int64_t>({12, 1}, expected_selected_indices);
test_case.add_expected_output<int64_t>({2}, expected_valid_outputs);
test_case.run();
}

View File

@ -1,638 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
// clang-format off
#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
#endif
#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
#endif
// clang-format on
#include "gtest/gtest.h"
#include "runtime/backend.hpp"
#include "ngraph/runtime/tensor.hpp"
#include "ngraph/ngraph.hpp"
#include "util/all_close.hpp"
#include "util/all_close_f.hpp"
#include "util/ndarray.hpp"
#include "util/test_control.hpp"
#include "engines_util/execute_tools.hpp"
NGRAPH_SUPPRESS_DEPRECATED_START
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_center_point_box_format) {
std::vector<float> boxes_data = {0.5, 0.5, 1.0, 1.0, 0.5, 0.6, 1.0, 1.0, 0.5, 0.4, 1.0, 1.0,
0.5, 10.5, 1.0, 1.0, 0.5, 10.6, 1.0, 1.0, 0.5, 100.5, 1.0, 1.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CENTER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{3, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{3, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0, 0, 0, 5};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3};
std::vector<int64_t> expected_valid_outputs = {3};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_flipped_coordinates) {
std::vector<float> boxes_data = {1.0, 1.0, 0.0, 0.0, 0.0, 0.1, 1.0, 1.1, 0.0, 0.9, 1.0, -0.1,
0.0, 10.0, 1.0, 11.0, 1.0, 10.1, 0.0, 11.1, 1.0, 101.0, 0.0, 100.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{3, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{3, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0, 0, 0, 5};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3};
std::vector<int64_t> expected_valid_outputs = {3};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_identical_boxes) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 10, 4};
const auto scores_shape = Shape{1, 1, 10};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{1, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{1, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {1};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_limit_output_size) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 2;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{2, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{2, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {2};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_single_box) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0};
std::vector<float> scores_data = {0.9};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 1, 4};
const auto scores_shape = Shape{1, 1, 1};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{1, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{1, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {1};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_suppress_by_IOU) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{3, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{3, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0, 0, 0, 5};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3};
std::vector<int64_t> expected_valid_outputs = {3};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_suppress_by_IOU_and_scores) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 3;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.4f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{2, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{2, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {2};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_two_batches) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0,
0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 2;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{2, 6, 4};
const auto scores_shape = Shape{2, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{4, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{4, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0, 1, 0, 3, 1, 0, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 1.0, 0.0, 0.95, 1.0, 0.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {4};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_two_classes) {
std::vector<float> boxes_data = {0.0, 0.0, 1.0, 1.0, 0.0, 0.1, 1.0, 1.1, 0.0, -0.1, 1.0, 0.9,
0.0, 10.0, 1.0, 11.0, 0.0, 10.1, 1.0, 11.1, 0.0, 100.0, 1.0, 101.0};
std::vector<float> scores_data = {0.9, 0.75, 0.6, 0.95, 0.5, 0.3, 0.9, 0.75, 0.6, 0.95, 0.5, 0.3};
const int64_t max_output_boxes_per_class_data = 2;
const float iou_threshold_data = 0.5f;
const float score_threshold_data = 0.0f;
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 2, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
auto max_output_boxes_per_class =
op::Constant::create<int64_t>(element::i64, Shape{}, {max_output_boxes_per_class_data});
auto iou_threshold = op::Constant::create<float>(element::f32, Shape{}, {iou_threshold_data});
auto score_threshold = op::Constant::create<float>(element::f32, Shape{}, {score_threshold_data});
auto soft_nms_sigma = op::Constant::create<float>(element::f32, Shape{}, {0.0f});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_threshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(nms, ParameterVector{boxes, scores});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{4, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{4, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs}, {backend_boxes, backend_scores});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3, 0, 0, 0, 0, 1, 3, 0, 1, 0};
std::vector<float> expected_selected_scores = {0.0, 0.0, 0.95, 0.0, 0.0, 0.9, 0.0, 1.0, 0.95, 0.0, 1.0, 0.9};
std::vector<int64_t> expected_valid_outputs = {4};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}
NGRAPH_TEST(${BACKEND_NAME}, nonmaxsuppression_suppress_by_IOU_and_scores_without_constants) {
std::vector<float> boxes_data = {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};
std::vector<float> scores_data = {0.9f, 0.75f, 0.6f, 0.95f, 0.5f, 0.3f};
std::vector<int64_t> max_output_boxes_per_class_data = {1};
std::vector<float> iou_threshold_data = {0.4f};
std::vector<float> score_threshold_data = {0.2f};
const auto box_encoding = op::v5::NonMaxSuppression::BoxEncodingType::CORNER;
const auto boxes_shape = Shape{1, 6, 4};
const auto scores_shape = Shape{1, 1, 6};
const auto boxes = make_shared<op::Parameter>(element::f32, boxes_shape);
const auto scores = make_shared<op::Parameter>(element::f32, scores_shape);
const auto max_output_boxes_per_class = make_shared<op::Parameter>(element::i64, Shape{1});
const auto score_treshold = make_shared<op::Parameter>(element::f32, Shape{1});
const auto iou_threshold = make_shared<op::Parameter>(element::f32, Shape{1});
const auto soft_nms_sigma = make_shared<op::Parameter>(element::f32, Shape{1});
auto nms = make_shared<op::v5::NonMaxSuppression>(boxes,
scores,
max_output_boxes_per_class,
iou_threshold,
score_treshold,
soft_nms_sigma,
box_encoding,
false);
auto f = make_shared<Function>(
nms,
ParameterVector{boxes, scores, max_output_boxes_per_class, iou_threshold, score_treshold, soft_nms_sigma});
auto backend = runtime::Backend::create("${BACKEND_NAME}");
auto selected_indeces = backend->create_tensor(element::i64, Shape{1, 3});
auto selected_scores = backend->create_tensor(element::f32, Shape{1, 3});
auto valid_outputs = backend->create_tensor(element::i64, Shape{1});
auto backend_boxes = backend->create_tensor(element::f32, boxes_shape);
auto backend_scores = backend->create_tensor(element::f32, scores_shape);
auto backend_max_output_boxes_per_class = backend->create_tensor(element::i64, {1});
auto backend_iou_threshold = backend->create_tensor(element::f32, {1});
auto backend_score_threshold = backend->create_tensor(element::f32, {1});
auto backend_soft_nms_sigma = backend->create_tensor(element::f32, {1});
copy_data(backend_boxes, boxes_data);
copy_data(backend_scores, scores_data);
copy_data(backend_max_output_boxes_per_class, max_output_boxes_per_class_data);
copy_data(backend_iou_threshold, iou_threshold_data);
copy_data(backend_score_threshold, score_threshold_data);
copy_data(backend_soft_nms_sigma, std::vector<float>(0.0));
auto handle = backend->compile(f);
handle->call({selected_indeces, selected_scores, valid_outputs},
{backend_boxes,
backend_scores,
backend_max_output_boxes_per_class,
backend_iou_threshold,
backend_score_threshold,
backend_soft_nms_sigma});
auto selected_indeces_value = read_vector<int64_t>(selected_indeces);
auto selected_scores_value = read_vector<float>(selected_scores);
auto valid_outputs_value = read_vector<int64_t>(valid_outputs);
std::vector<int64_t> expected_selected_indices = {0, 0, 3};
std::vector<float> expected_selected_scores = {0.0f, 0.0f, 0.95f};
std::vector<int64_t> expected_valid_outputs = {1};
EXPECT_EQ(expected_selected_indices, selected_indeces_value);
EXPECT_EQ(expected_selected_scores, selected_scores_value);
EXPECT_EQ(expected_valid_outputs, valid_outputs_value);
}