[ShapeInference] DetectionOutput shape inference review (#15645)
* Add setter for attributes * Add more type_prop tests * Extend shape infer tests for default ctor * Remove redundant set_output_size and update shapes init --------- Co-authored-by: Pawel Raasz <pawel.raasz@intel.com>
This commit is contained in:
co-authored by
Pawel Raasz
parent
86b50044cd
commit
94b64fed79
@@ -54,6 +54,9 @@ public:
|
||||
const Attributes& get_attrs() const {
|
||||
return m_attrs;
|
||||
}
|
||||
void set_attrs(const Attributes& attrs) {
|
||||
m_attrs = attrs;
|
||||
}
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
private:
|
||||
@@ -104,6 +107,9 @@ public:
|
||||
const Attributes& get_attrs() const {
|
||||
return m_attrs;
|
||||
}
|
||||
void set_attrs(const Attributes& attrs) {
|
||||
m_attrs = attrs;
|
||||
}
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "ngraph/op/detection_output.hpp"
|
||||
|
||||
#include <detection_output_shape_inference.hpp>
|
||||
|
||||
#include "detection_output_shape_inference.hpp"
|
||||
#include "itt.hpp"
|
||||
#include "openvino/core/validation_util.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -35,14 +35,10 @@ void ov::op::v0::DetectionOutput::validate_and_infer_types() {
|
||||
OV_OP_SCOPE(v0_DetectionOutput_validate_and_infer_types);
|
||||
NODE_VALIDATION_CHECK(this, m_attrs.num_classes > 0, "Number of classes must be greater than zero");
|
||||
validate_base(m_attrs);
|
||||
std::vector<ov::PartialShape> input_shapes;
|
||||
for (size_t input_idx = 0; input_idx < get_input_size(); input_idx++)
|
||||
input_shapes.push_back(get_input_partial_shape(input_idx));
|
||||
std::vector<ov::PartialShape> output_shapes = {ov::PartialShape{}};
|
||||
|
||||
const auto input_shapes = get_node_input_partial_shapes(*this);
|
||||
auto output_shapes = std::vector<ov::PartialShape>(1);
|
||||
shape_infer(this, input_shapes, output_shapes);
|
||||
|
||||
set_output_size(1);
|
||||
set_output_type(0, get_input_element_type(0), output_shapes[0]);
|
||||
}
|
||||
|
||||
@@ -97,14 +93,10 @@ ov::op::v8::DetectionOutput::DetectionOutput(const Output<Node>& box_logits,
|
||||
void ov::op::v8::DetectionOutput::validate_and_infer_types() {
|
||||
OV_OP_SCOPE(v8_DetectionOutput_validate_and_infer_types);
|
||||
validate_base(m_attrs);
|
||||
std::vector<ov::PartialShape> input_shapes;
|
||||
for (size_t input_idx = 0; input_idx < get_input_size(); input_idx++)
|
||||
input_shapes.push_back(get_input_partial_shape(input_idx));
|
||||
std::vector<ov::PartialShape> output_shapes = {ov::PartialShape{}};
|
||||
|
||||
const auto input_shapes = get_node_input_partial_shapes(*this);
|
||||
auto output_shapes = std::vector<ov::PartialShape>(1);
|
||||
shape_infer(this, input_shapes, output_shapes);
|
||||
|
||||
set_output_size(1);
|
||||
set_output_type(0, get_input_element_type(0), output_shapes[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,22 +6,36 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "dimension_tracker.hpp"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "openvino/util/common_util.hpp"
|
||||
#include "util/type_prop.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
using namespace testing;
|
||||
|
||||
// ------------------------------ V0 ------------------------------
|
||||
std::shared_ptr<op::DetectionOutput> create_detection_output(const PartialShape& box_logits_shape,
|
||||
const PartialShape& class_preds_shape,
|
||||
const PartialShape& proposals_shape,
|
||||
const PartialShape& aux_class_preds_shape,
|
||||
const PartialShape& aux_box_preds_shape,
|
||||
std::shared_ptr<op::DetectionOutput> create_detection_output(PartialShape box_logits_shape,
|
||||
PartialShape class_preds_shape,
|
||||
PartialShape proposals_shape,
|
||||
PartialShape aux_class_preds_shape,
|
||||
PartialShape aux_box_preds_shape,
|
||||
const op::DetectionOutputAttrs& attrs,
|
||||
element::Type input_type,
|
||||
element::Type proposals_type) {
|
||||
element::Type proposals_type,
|
||||
bool set_labels = false) {
|
||||
if (set_labels) {
|
||||
// The labels are set for all of the shapes,
|
||||
// but the output dimension is always a product of multiplication, so labels are not preserved
|
||||
set_shape_labels(box_logits_shape, 10);
|
||||
set_shape_labels(class_preds_shape, 20);
|
||||
set_shape_labels(proposals_shape, 30);
|
||||
set_shape_labels(aux_class_preds_shape, 40);
|
||||
set_shape_labels(aux_box_preds_shape, 50);
|
||||
}
|
||||
|
||||
auto box_logits = make_shared<op::Parameter>(input_type, box_logits_shape);
|
||||
auto class_preds = make_shared<op::Parameter>(input_type, class_preds_shape);
|
||||
auto proposals = make_shared<op::Parameter>(proposals_type, proposals_shape);
|
||||
@@ -30,7 +44,41 @@ std::shared_ptr<op::DetectionOutput> create_detection_output(const PartialShape&
|
||||
return make_shared<op::DetectionOutput>(box_logits, class_preds, proposals, aux_class_preds, aux_box_preds, attrs);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output) {
|
||||
TEST(type_prop_layers, detection_output_v0_default_ctor) {
|
||||
auto op = make_shared<op::v8::DetectionOutput>();
|
||||
|
||||
auto input_type = element::f32;
|
||||
auto box_logits = make_shared<op::Parameter>(input_type, PartialShape{4, 20});
|
||||
auto class_preds = make_shared<op::Parameter>(input_type, PartialShape{4, 10});
|
||||
auto proposals = make_shared<op::Parameter>(input_type, PartialShape{4, 2, 20});
|
||||
auto ad_class_preds = make_shared<op::Parameter>(input_type, PartialShape{4, 10});
|
||||
auto ad_box_preds = make_shared<op::Parameter>(input_type, PartialShape{4, 20});
|
||||
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = 7;
|
||||
attrs.num_classes = 2;
|
||||
attrs.normalized = true;
|
||||
|
||||
op->set_attrs(attrs);
|
||||
op->set_arguments(OutputVector{box_logits, class_preds, proposals, ad_class_preds, ad_box_preds});
|
||||
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, 56, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
|
||||
op->set_attrs(attrs);
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, 40, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_basic) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
@@ -43,11 +91,76 @@ TEST(type_prop_layers, detection_output) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_f16) {
|
||||
TEST(type_prop_layers, detection_output_interval_labeled_keep_top_k) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {60};
|
||||
attrs.num_classes = 3;
|
||||
attrs.normalized = true;
|
||||
auto op = create_detection_output(PartialShape{{2, 4}, {1, 20}},
|
||||
PartialShape{{2, 4}, {1, 10}},
|
||||
PartialShape{-1, 2, 20},
|
||||
PartialShape{-1, 10},
|
||||
PartialShape{-1, 20},
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32,
|
||||
true); // set labels
|
||||
|
||||
// [1, 1, N * keep_top_k[0], 7]
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, {120, 240}, 7}));
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_interval_labeled_top_k) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = 80;
|
||||
attrs.num_classes = 3;
|
||||
attrs.normalized = true;
|
||||
auto op = create_detection_output(PartialShape{{2, 4}, {1, 20}},
|
||||
PartialShape{{2, 4}, {1, 10}},
|
||||
PartialShape{-1, 2, 20},
|
||||
PartialShape{-1, 10},
|
||||
PartialShape{-1, 20},
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32,
|
||||
true); // set labels
|
||||
|
||||
// [1, 1, N * top_k * num_classes, 7]
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, {480, 960}, 7}));
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_interval_labeled_negative_both_topk) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
attrs.num_classes = 3;
|
||||
attrs.normalized = true;
|
||||
auto op = create_detection_output(PartialShape{{2, 4}, {1, 20}},
|
||||
PartialShape{{2, 4}, {1, 10}},
|
||||
PartialShape{-1, 2, 20},
|
||||
PartialShape{-1, 10},
|
||||
PartialShape{-1, 20},
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32,
|
||||
true); // set labels
|
||||
|
||||
// [1, 1, N * num_classes * num_prior_boxes, 7] // num_prior_boxex = 5
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, {30, 60}, 7}));
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_v0_f16) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
@@ -60,8 +173,8 @@ TEST(type_prop_layers, detection_output_f16) {
|
||||
attrs,
|
||||
element::f16,
|
||||
element::f16);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f16);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f16);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_f16_with_proposals_f32) {
|
||||
@@ -77,11 +190,11 @@ TEST(type_prop_layers, detection_f16_with_proposals_f32) {
|
||||
attrs,
|
||||
element::f16,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f16);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f16);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_not_normalized) {
|
||||
TEST(type_prop_layers, detection_output_v0_not_normalized) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
@@ -94,11 +207,11 @@ TEST(type_prop_layers, detection_output_not_normalized) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 800, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_negative_keep_top_k) {
|
||||
TEST(type_prop_layers, detection_output_v0_negative_keep_top_k) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
@@ -112,11 +225,11 @@ TEST(type_prop_layers, detection_output_negative_keep_top_k) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 40, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 40, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_no_share_location) {
|
||||
TEST(type_prop_layers, detection_output_v0_no_share_location) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
@@ -131,11 +244,11 @@ TEST(type_prop_layers, detection_output_no_share_location) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 40, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 40, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_calculated_num_prior_boxes) {
|
||||
TEST(type_prop_layers, detection_output_v0_calculated_num_prior_boxes) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
@@ -150,11 +263,11 @@ TEST(type_prop_layers, detection_output_calculated_num_prior_boxes) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 80, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 80, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_top_k) {
|
||||
TEST(type_prop_layers, detection_output_v0_top_k) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = 7;
|
||||
@@ -168,11 +281,11 @@ TEST(type_prop_layers, detection_output_top_k) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{1, 1, 56, 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_shape(), (Shape{1, 1, 56, 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_all_dynamic_shapes) {
|
||||
TEST(type_prop_layers, detection_output_v0_all_dynamic_shapes) {
|
||||
PartialShape dyn_shape = PartialShape::dynamic();
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
@@ -185,11 +298,11 @@ TEST(type_prop_layers, detection_output_all_dynamic_shapes) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, Dimension::dynamic(), 7}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{1, 1, Dimension::dynamic(), 7}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_dynamic_batch) {
|
||||
TEST(type_prop_layers, detection_output_v0_dynamic_batch) {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
@@ -202,8 +315,8 @@ TEST(type_prop_layers, detection_output_dynamic_batch) {
|
||||
attrs,
|
||||
element::f32,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), (PartialShape{{1, 1, Dimension::dynamic(), 7}}));
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{{1, 1, Dimension::dynamic(), 7}}));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
|
||||
void detection_output_invalid_data_type_test(element::Type box_logits_et,
|
||||
@@ -232,7 +345,7 @@ void detection_output_invalid_data_type_test(element::Type box_logits_et,
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_data_type) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_data_type) {
|
||||
detection_output_invalid_data_type_test(element::i32,
|
||||
element::f32,
|
||||
element::f32,
|
||||
@@ -268,7 +381,7 @@ TEST(type_prop_layers, detection_output_invalid_data_type) {
|
||||
"same as box logits data type (f32). Got i32");
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_mismatched_batch_size) {
|
||||
TEST(type_prop_layers, detection_output_v0_mismatched_batch_size) {
|
||||
{
|
||||
try {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
@@ -316,7 +429,7 @@ TEST(type_prop_layers, detection_output_mismatched_batch_size) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_ranks) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_ranks) {
|
||||
{
|
||||
try {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
@@ -382,7 +495,7 @@ TEST(type_prop_layers, detection_output_invalid_ranks) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_box_logits_shape) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_box_logits_shape) {
|
||||
// share_location = true
|
||||
{
|
||||
try {
|
||||
@@ -437,7 +550,7 @@ TEST(type_prop_layers, detection_output_invalid_box_logits_shape) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_class_preds_shape) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_class_preds_shape) {
|
||||
try {
|
||||
op::DetectionOutputAttrs attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
@@ -460,7 +573,7 @@ TEST(type_prop_layers, detection_output_invalid_class_preds_shape) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_proposals_shape) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_proposals_shape) {
|
||||
// variance_encoded_in_target = false
|
||||
{
|
||||
try {
|
||||
@@ -567,7 +680,7 @@ TEST(type_prop_layers, detection_output_invalid_proposals_shape) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_aux_class_preds) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_aux_class_preds) {
|
||||
// invalid batch size
|
||||
{
|
||||
try {
|
||||
@@ -623,7 +736,7 @@ TEST(type_prop_layers, detection_output_invalid_aux_class_preds) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_invalid_aux_box_preds) {
|
||||
TEST(type_prop_layers, detection_output_v0_invalid_aux_box_preds) {
|
||||
// invalid batch size
|
||||
{
|
||||
try {
|
||||
@@ -680,24 +793,44 @@ TEST(type_prop_layers, detection_output_invalid_aux_box_preds) {
|
||||
|
||||
// ------------------------------ V8 ------------------------------
|
||||
namespace {
|
||||
std::shared_ptr<op::v8::DetectionOutput> create_detection_output_v8(const PartialShape& box_logits_shape,
|
||||
const PartialShape& class_preds_shape,
|
||||
const PartialShape& proposals_shape,
|
||||
std::shared_ptr<op::v8::DetectionOutput> create_detection_output_v8(PartialShape box_logits_shape,
|
||||
PartialShape class_preds_shape,
|
||||
PartialShape proposals_shape,
|
||||
const op::v8::DetectionOutput::Attributes& attrs,
|
||||
element::Type input_type) {
|
||||
element::Type input_type,
|
||||
bool set_labels = false) {
|
||||
if (set_labels) {
|
||||
// The labels are set for all of the shapes,
|
||||
// but the output dimension is always a product of multiplication, so labels are not preserved
|
||||
set_shape_labels(box_logits_shape, 10);
|
||||
set_shape_labels(class_preds_shape, 20);
|
||||
set_shape_labels(proposals_shape, 30);
|
||||
}
|
||||
|
||||
auto box_logits = make_shared<op::Parameter>(input_type, box_logits_shape);
|
||||
auto class_preds = make_shared<op::Parameter>(input_type, class_preds_shape);
|
||||
auto proposals = make_shared<op::Parameter>(input_type, proposals_shape);
|
||||
return make_shared<op::v8::DetectionOutput>(box_logits, class_preds, proposals, attrs);
|
||||
}
|
||||
|
||||
std::shared_ptr<op::v8::DetectionOutput> create_detection_output2_v8(const PartialShape& box_logits_shape,
|
||||
const PartialShape& class_preds_shape,
|
||||
const PartialShape& proposals_shape,
|
||||
const PartialShape& aux_class_preds_shape,
|
||||
const PartialShape& aux_box_preds_shape,
|
||||
std::shared_ptr<op::v8::DetectionOutput> create_detection_output2_v8(PartialShape box_logits_shape,
|
||||
PartialShape class_preds_shape,
|
||||
PartialShape proposals_shape,
|
||||
PartialShape aux_class_preds_shape,
|
||||
PartialShape aux_box_preds_shape,
|
||||
const op::v8::DetectionOutput::Attributes& attrs,
|
||||
element::Type input_type) {
|
||||
element::Type input_type,
|
||||
bool set_labels = false) {
|
||||
if (set_labels) {
|
||||
// The labels are set for all of the shapes,
|
||||
// but the output dimension is always a product of multiplication, so labels are not preserved
|
||||
set_shape_labels(box_logits_shape, 10);
|
||||
set_shape_labels(class_preds_shape, 20);
|
||||
set_shape_labels(proposals_shape, 30);
|
||||
set_shape_labels(aux_class_preds_shape, 40);
|
||||
set_shape_labels(aux_box_preds_shape, 50);
|
||||
}
|
||||
|
||||
auto box_logits = make_shared<op::Parameter>(input_type, box_logits_shape);
|
||||
auto class_preds = make_shared<op::Parameter>(input_type, class_preds_shape);
|
||||
auto proposals = make_shared<op::Parameter>(input_type, proposals_shape);
|
||||
@@ -750,13 +883,10 @@ std::vector<op::v8::DetectionOutput::Attributes> create_attributes_vector() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(type_prop_layers, detection_outputv8_all_static) {
|
||||
TEST(type_prop_layers, detection_output_v8_all_static) {
|
||||
// this case covers deducing a number of classes value
|
||||
// since this value is not saved in attributes
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
|
||||
// initialize attributes affecting shape inference
|
||||
// others remain by default
|
||||
Dimension N = 5;
|
||||
Dimension num_prior_boxes = 100;
|
||||
Dimension priors_batch_size = N;
|
||||
@@ -776,16 +906,12 @@ TEST(type_prop_layers, detection_outputv8_all_static) {
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, num_classes, num_prior_boxes);
|
||||
|
||||
auto op = create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_outputv8_dynamic) {
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
|
||||
// initialize attributes affecting shape inference
|
||||
// others remain by default
|
||||
TEST(type_prop_layers, detection_output_v8_dynamic) {
|
||||
Dimension N = 13;
|
||||
Dimension num_prior_boxes = 33;
|
||||
Dimension priors_batch_size = 1;
|
||||
@@ -804,16 +930,12 @@ TEST(type_prop_layers, detection_outputv8_dynamic) {
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, num_classes, num_prior_boxes);
|
||||
|
||||
auto op = create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_outputv8_num_classes_not_deduced) {
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
|
||||
// initialize attributes affecting shape inference
|
||||
// others remain by default
|
||||
TEST(type_prop_layers, detection_output_v8_num_classes_not_deduced) {
|
||||
Dimension N = 13;
|
||||
Dimension num_prior_boxes = 33;
|
||||
Dimension priors_batch_size = 1;
|
||||
@@ -831,17 +953,13 @@ TEST(type_prop_layers, detection_outputv8_num_classes_not_deduced) {
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, Dimension::dynamic(), num_prior_boxes);
|
||||
|
||||
auto op = create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_outputv8_num_classes_no_deduction) {
|
||||
TEST(type_prop_layers, detection_output_v8_num_classes_no_deduction) {
|
||||
// In this case a number of classes and a number of prior boxes are not deduced
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
|
||||
// initialize attributes affecting shape inference
|
||||
// others remain by default
|
||||
Dimension N = 3;
|
||||
Dimension priors_batch_size = N;
|
||||
|
||||
@@ -859,18 +977,14 @@ TEST(type_prop_layers, detection_outputv8_num_classes_no_deduction) {
|
||||
Dimension::dynamic());
|
||||
|
||||
auto op = create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_outputv8_dynamic2) {
|
||||
TEST(type_prop_layers, detection_output_v8_dynamic2) {
|
||||
// In this case a number of prior boxes is deduced using additional input
|
||||
// and after that a number of classes is deduced using the second input shape
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
|
||||
// initialize attributes affecting shape inference
|
||||
// others remain by default
|
||||
Dimension N = 13;
|
||||
Dimension num_prior_boxes = 33;
|
||||
Dimension priors_batch_size = 1;
|
||||
@@ -895,7 +1009,137 @@ TEST(type_prop_layers, detection_outputv8_dynamic2) {
|
||||
ad_box_preds_shape,
|
||||
attrs,
|
||||
element::f32);
|
||||
ASSERT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
ASSERT_EQ(op->get_element_type(), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_v8_intervals_3in) {
|
||||
auto N = Dimension(2, 4);
|
||||
auto priors_batch_size = N;
|
||||
auto num_prior_boxes = Dimension(8, 10);
|
||||
|
||||
auto attrs_vector = create_attributes_vector();
|
||||
for (const auto& attrs : attrs_vector) {
|
||||
Dimension prior_box_size = attrs.normalized ? 4 : 5;
|
||||
|
||||
PartialShape box_logits_shape{N, {40, 240}};
|
||||
PartialShape class_preds_shape = {N, {10, 60}};
|
||||
PartialShape proposals_shape = {priors_batch_size,
|
||||
attrs.variance_encoded_in_target ? 1 : 2,
|
||||
prior_box_size * num_prior_boxes};
|
||||
|
||||
PartialShape output_shape_reference = compute_reference_output_shape(attrs.keep_top_k,
|
||||
attrs.top_k,
|
||||
N,
|
||||
Dimension::dynamic(),
|
||||
Dimension::dynamic());
|
||||
|
||||
auto op =
|
||||
create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32, true);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference)
|
||||
<< "Failed for keep_top_k=" << ov::util::vector_to_string(attrs.keep_top_k) << " top_k=" << attrs.top_k
|
||||
<< " and variance_encoded_in_target=" << attrs.variance_encoded_in_target << std::endl;
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_v8_interval_batch_3in) {
|
||||
auto N = Dimension(2, 4);
|
||||
auto priors_batch_size = N;
|
||||
auto num_prior_boxes = Dimension(6);
|
||||
auto num_classes = Dimension(10);
|
||||
|
||||
auto attrs_vector = create_attributes_vector();
|
||||
for (const auto& attrs : attrs_vector) {
|
||||
Dimension num_loc_classes = attrs.share_location ? 1 : num_classes;
|
||||
Dimension prior_box_size = attrs.normalized ? 4 : 5;
|
||||
|
||||
PartialShape box_logits_shape = {N, num_prior_boxes * num_loc_classes * 4};
|
||||
PartialShape class_preds_shape = {N, num_prior_boxes * num_classes};
|
||||
PartialShape proposals_shape = {priors_batch_size,
|
||||
attrs.variance_encoded_in_target ? 1 : 2,
|
||||
num_prior_boxes * prior_box_size};
|
||||
|
||||
PartialShape output_shape_reference =
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, num_classes, num_prior_boxes);
|
||||
|
||||
auto op =
|
||||
create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32, true);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference)
|
||||
<< "Failed for keep_top_k=" << ov::util::vector_to_string(attrs.keep_top_k) << " top_k=" << attrs.top_k
|
||||
<< " and variance_encoded_in_target=" << attrs.variance_encoded_in_target << std::endl;
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_v8_interval_batch_5in) {
|
||||
auto N = Dimension(2, 4);
|
||||
auto priors_batch_size = Dimension(1, 2);
|
||||
auto num_prior_boxes = Dimension(6);
|
||||
auto num_classes = Dimension(10);
|
||||
|
||||
auto attrs_vector = create_attributes_vector();
|
||||
for (const auto& attrs : attrs_vector) {
|
||||
Dimension num_loc_classes = attrs.share_location ? 1 : num_classes;
|
||||
Dimension prior_box_size = attrs.normalized ? 4 : 5;
|
||||
|
||||
PartialShape box_logits_shape = {N, num_prior_boxes * num_loc_classes * 4};
|
||||
PartialShape class_preds_shape = {N, num_prior_boxes * num_classes};
|
||||
PartialShape proposals_shape = {priors_batch_size,
|
||||
attrs.variance_encoded_in_target ? 1 : 2,
|
||||
num_prior_boxes * prior_box_size};
|
||||
PartialShape ad_class_preds_shape = {N, num_prior_boxes * 2};
|
||||
|
||||
PartialShape output_shape_reference =
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, num_classes, num_prior_boxes);
|
||||
|
||||
auto op =
|
||||
create_detection_output_v8(box_logits_shape, class_preds_shape, proposals_shape, attrs, element::f32, true);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference)
|
||||
<< "Failed for keep_top_k=" << ov::util::vector_to_string(attrs.keep_top_k) << " top_k=" << attrs.top_k
|
||||
<< " and variance_encoded_in_target=" << attrs.variance_encoded_in_target << std::endl;
|
||||
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(ov::no_label));
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, detection_output_v8_default_ctor) {
|
||||
Dimension N = 13;
|
||||
Dimension num_prior_boxes = 33;
|
||||
Dimension priors_batch_size = 1;
|
||||
Dimension num_classes = 10;
|
||||
|
||||
for (const auto& attrs : create_attributes_vector()) {
|
||||
Dimension num_loc_classes = attrs.share_location ? 1 : num_classes;
|
||||
Dimension prior_box_size = attrs.normalized ? 4 : 5;
|
||||
|
||||
PartialShape box_logits_shape = {N, num_prior_boxes * num_loc_classes * 4};
|
||||
PartialShape class_preds_shape = {N, num_prior_boxes * num_classes};
|
||||
PartialShape proposals_shape = {priors_batch_size,
|
||||
attrs.variance_encoded_in_target ? 1 : 2,
|
||||
num_prior_boxes * prior_box_size};
|
||||
PartialShape ad_class_preds_shape = {N, num_prior_boxes * 2};
|
||||
|
||||
PartialShape output_shape_reference =
|
||||
compute_reference_output_shape(attrs.keep_top_k, attrs.top_k, N, num_classes, num_prior_boxes);
|
||||
|
||||
auto input_type = element::f32;
|
||||
auto box_logits = make_shared<op::Parameter>(input_type, box_logits_shape);
|
||||
auto class_preds = make_shared<op::Parameter>(input_type, class_preds_shape);
|
||||
auto proposals = make_shared<op::Parameter>(input_type, proposals_shape);
|
||||
auto ad_class_preds = make_shared<op::Parameter>(input_type, ad_class_preds_shape);
|
||||
auto ad_box_preds = make_shared<op::Parameter>(input_type, box_logits_shape);
|
||||
|
||||
auto op = make_shared<op::v8::DetectionOutput>();
|
||||
op->set_attrs(attrs);
|
||||
op->set_arguments(OutputVector{box_logits, class_preds, proposals, ad_class_preds, ad_box_preds});
|
||||
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), output_shape_reference);
|
||||
EXPECT_EQ(op->get_element_type(), element::f32);
|
||||
}
|
||||
}
|
||||
|
||||
+47
-6
@@ -9,6 +9,8 @@
|
||||
#include <utils/shape_inference/shape_inference.hpp>
|
||||
|
||||
#include "utils/shape_inference/static_shape.hpp"
|
||||
#include "detection_output_shape_inference.hpp"
|
||||
|
||||
|
||||
using namespace ov;
|
||||
using namespace ov::intel_cpu;
|
||||
@@ -30,7 +32,7 @@ std::shared_ptr<Node> create_detection_output(const PartialShape& box_logits_sha
|
||||
return std::make_shared<T1>(box_logits, class_preds, proposals, aux_class_preds, aux_box_preds, attrs);
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output_top_k) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v0_top_k) {
|
||||
op::v0::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = 7;
|
||||
@@ -55,7 +57,7 @@ TEST(StaticShapeInferenceTest, detection_output_top_k) {
|
||||
ASSERT_EQ(output_shapes[0], StaticShape({1, 1, 56, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output_no_share_location) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v0_no_share_location) {
|
||||
op::v0::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
@@ -81,7 +83,7 @@ TEST(StaticShapeInferenceTest, detection_output_no_share_location) {
|
||||
ASSERT_EQ(output_shapes[0], StaticShape({1, 1, 40, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v0_basic) {
|
||||
op::v0::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
@@ -105,7 +107,27 @@ TEST(StaticShapeInferenceTest, detection_output) {
|
||||
ASSERT_EQ(output_shapes[0], (StaticShape{1, 1, 800, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_outputv8_top_k) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v0_default_ctor) {
|
||||
auto op = std::make_shared<op::v0::DetectionOutput>();
|
||||
|
||||
op::v0::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.num_classes = 2;
|
||||
attrs.normalized = true;
|
||||
op->set_attrs(attrs);
|
||||
|
||||
const std::vector<StaticShape> input_shapes = {StaticShape{4, 20},
|
||||
StaticShape{4, 10},
|
||||
StaticShape{4, 2, 20},
|
||||
StaticShape{4, 10},
|
||||
StaticShape{4, 20}};
|
||||
std::vector<StaticShape> output_shapes = {StaticShape{}};
|
||||
|
||||
shape_infer(op.get(), input_shapes, output_shapes);
|
||||
EXPECT_EQ(output_shapes[0], (StaticShape{1, 1, 800, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output_v8_top_k) {
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = 7;
|
||||
@@ -129,7 +151,7 @@ TEST(StaticShapeInferenceTest, detection_outputv8_top_k) {
|
||||
ASSERT_EQ(output_shapes[0], StaticShape({1, 1, 56, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_outputv8_no_share_location) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v8_no_share_location) {
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {-1};
|
||||
attrs.top_k = -1;
|
||||
@@ -154,7 +176,7 @@ TEST(StaticShapeInferenceTest, detection_outputv8_no_share_location) {
|
||||
ASSERT_EQ(output_shapes[0], StaticShape({1, 1, 40, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output_v8) {
|
||||
TEST(StaticShapeInferenceTest, detection_output_v8_basic) {
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.normalized = true;
|
||||
@@ -176,3 +198,22 @@ TEST(StaticShapeInferenceTest, detection_output_v8) {
|
||||
shape_inference(op.get(), input_shapes, output_shapes);
|
||||
ASSERT_EQ(output_shapes[0], (StaticShape{1, 1, 800, 7}));
|
||||
}
|
||||
|
||||
TEST(StaticShapeInferenceTest, detection_output_v8_default_ctor) {
|
||||
auto op = std::make_shared<op::v8::DetectionOutput>();
|
||||
|
||||
op::v8::DetectionOutput::Attributes attrs;
|
||||
attrs.keep_top_k = {200};
|
||||
attrs.normalized = true;
|
||||
op->set_attrs(attrs);
|
||||
|
||||
const std::vector<StaticShape> input_shapes = {StaticShape{4, 20},
|
||||
StaticShape{4, 10},
|
||||
StaticShape{4, 2, 20},
|
||||
StaticShape{4, 10},
|
||||
StaticShape{4, 20}};
|
||||
std::vector<StaticShape> output_shapes = {StaticShape{}};
|
||||
|
||||
shape_infer(op.get(), input_shapes, output_shapes);
|
||||
EXPECT_EQ(output_shapes[0], (StaticShape{1, 1, 800, 7}));
|
||||
}
|
||||
Reference in New Issue
Block a user