Review detectron generate proposal for: (#17103)

- interval shape propagation
- label propagation
- template implementation of shape_infer
- add more unit tests for dynamic and static shapes
This commit is contained in:
Pawel Raasz
2023-05-08 08:34:37 +02:00
committed by GitHub
parent 78cdf22040
commit f93c8dda78
6 changed files with 528 additions and 192 deletions

View File

@@ -57,6 +57,8 @@ public:
return m_attrs;
}
void set_attrs(Attributes attrs);
private:
Attributes m_attrs;
};

View File

@@ -4,47 +4,44 @@
#pragma once
#include <openvino/op/experimental_detectron_generate_proposals.hpp>
#include "openvino/op/experimental_detectron_generate_proposals.hpp"
namespace ov {
namespace op {
namespace v6 {
template <class T>
void shape_infer(const ExperimentalDetectronGenerateProposalsSingleImage* op,
const std::vector<T>& input_shapes,
std::vector<T>& output_shapes) {
NODE_VALIDATION_CHECK(op, input_shapes.size() == 4 && output_shapes.size() == 2);
auto post_nms_count = static_cast<size_t>(op->get_attrs().post_nms_count);
template <class TShape>
std::vector<TShape> shape_infer(const ExperimentalDetectronGenerateProposalsSingleImage* op,
const std::vector<TShape>& input_shapes) {
NODE_VALIDATION_CHECK(op, input_shapes.size() == 4);
const auto& im_info_shape = input_shapes[0];
const auto& anchors_shape = input_shapes[1];
const auto& deltas_shape = input_shapes[2];
const auto& scores_shape = input_shapes[3];
const auto im_info_shape_rank = im_info_shape.rank();
NODE_VALIDATION_CHECK(op,
im_info_shape_rank.compatible(1),
"The 'input_im_info' input is expected to be a 1D. Got: ",
im_info_shape);
if (im_info_shape_rank.is_static()) {
NODE_VALIDATION_CHECK(op,
im_info_shape[0].compatible(3),
"The 'input_im_info' shape is expected to be a compatible with [3]. Got: ",
im_info_shape);
}
NODE_VALIDATION_CHECK(op,
im_info_shape_rank.is_dynamic() || im_info_shape[0].compatible(3),
"The 'input_im_info' shape is expected to be a compatible with [3]. Got: ",
im_info_shape);
const auto anchors_shape_rank = anchors_shape.rank();
NODE_VALIDATION_CHECK(op,
anchors_shape_rank.compatible(2),
"The 'input_anchors' input is expected to be a 2D. Got: ",
anchors_shape);
if (anchors_shape_rank.is_static()) {
NODE_VALIDATION_CHECK(op,
anchors_shape[1].compatible(4),
"The second dimension of 'input_anchors' should be compatible with 4. Got: ",
anchors_shape[1]);
}
NODE_VALIDATION_CHECK(op,
anchors_shape_rank.is_dynamic() || anchors_shape[1].compatible(4),
"The second dimension of 'input_anchors' should be compatible with 4. Got: ",
anchors_shape[1]);
const auto deltas_shape_rank = deltas_shape.rank();
const auto scores_shape_rank = scores_shape.rank();
@@ -56,29 +53,32 @@ void shape_infer(const ExperimentalDetectronGenerateProposalsSingleImage* op,
scores_shape_rank.compatible(3),
"The 'input_scores' input is expected to be a 3D. Got: ",
scores_shape);
if (deltas_shape_rank.is_static() && scores_shape_rank.is_static()) {
NODE_VALIDATION_CHECK(op,
deltas_shape[1].compatible(scores_shape[1]),
"Heights for inputs 'input_deltas' and 'input_scores' should be "
"equal. Got: ",
"Heights for inputs 'input_deltas' and 'input_scores' should be equal. Got: ",
deltas_shape[1],
scores_shape[1]);
NODE_VALIDATION_CHECK(op,
deltas_shape[2].compatible(scores_shape[2]),
"Width for inputs 'input_deltas' and 'input_scores' should be "
"equal. Got: ",
"Width for inputs 'input_deltas' and 'input_scores' should be equal. Got: ",
deltas_shape[2],
scores_shape[2]);
}
auto& rois_shape = output_shapes[0];
auto& rois_scores_shape = output_shapes[1];
rois_shape.resize(2);
rois_scores_shape.resize(1);
rois_shape[0] = post_nms_count;
rois_shape[1] = 4;
rois_scores_shape[0] = post_nms_count;
auto post_nms_count = static_cast<typename TShape::value_type>(op->get_attrs().post_nms_count);
auto output_shapes = std::vector<TShape>(2, TShape{post_nms_count});
output_shapes[0].push_back(4);
return output_shapes;
}
template <class TShape>
void shape_infer(const ExperimentalDetectronGenerateProposalsSingleImage* op,
const std::vector<TShape>& input_shapes,
std::vector<TShape>& output_shapes) {
output_shapes = shape_infer(op, input_shapes);
}
} // namespace v6

View File

@@ -2,19 +2,18 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "ngraph/op/experimental_detectron_generate_proposals.hpp"
#include <experimental_detectron_generate_proposals_shape_inference.hpp>
#include "openvino/op/experimental_detectron_generate_proposals.hpp"
#include "experimental_detectron_generate_proposals_shape_inference.hpp"
#include "itt.hpp"
#include "ngraph/attribute_visitor.hpp"
#include "ngraph/op/util/op_types.hpp"
#include "ngraph/validation_util.hpp"
#include "openvino/core/attribute_visitor.hpp"
using namespace std;
using namespace ngraph;
namespace ov {
namespace op {
namespace v6 {
op::v6::ExperimentalDetectronGenerateProposalsSingleImage::ExperimentalDetectronGenerateProposalsSingleImage(
ExperimentalDetectronGenerateProposalsSingleImage::ExperimentalDetectronGenerateProposalsSingleImage(
const Output<Node>& im_info,
const Output<Node>& anchors,
const Output<Node>& deltas,
@@ -25,18 +24,18 @@ op::v6::ExperimentalDetectronGenerateProposalsSingleImage::ExperimentalDetectron
constructor_validate_and_infer_types();
}
shared_ptr<Node> op::v6::ExperimentalDetectronGenerateProposalsSingleImage::clone_with_new_inputs(
shared_ptr<Node> ExperimentalDetectronGenerateProposalsSingleImage::clone_with_new_inputs(
const OutputVector& new_args) const {
OV_OP_SCOPE(v6_ExperimentalDetectronGenerateProposalsSingleImage_clone_with_new_inputs);
check_new_args_count(this, new_args);
return make_shared<op::v6::ExperimentalDetectronGenerateProposalsSingleImage>(new_args.at(0),
new_args.at(1),
new_args.at(2),
new_args.at(3),
m_attrs);
return make_shared<ExperimentalDetectronGenerateProposalsSingleImage>(new_args.at(0),
new_args.at(1),
new_args.at(2),
new_args.at(3),
m_attrs);
}
bool op::v6::ExperimentalDetectronGenerateProposalsSingleImage::visit_attributes(AttributeVisitor& visitor) {
bool ExperimentalDetectronGenerateProposalsSingleImage::visit_attributes(AttributeVisitor& visitor) {
OV_OP_SCOPE(v6_ExperimentalDetectronGenerateProposalsSingleImage_visit_attributes);
visitor.on_attribute("min_size", m_attrs.min_size);
visitor.on_attribute("nms_threshold", m_attrs.nms_threshold);
@@ -45,17 +44,36 @@ bool op::v6::ExperimentalDetectronGenerateProposalsSingleImage::visit_attributes
return true;
}
void op::v6::ExperimentalDetectronGenerateProposalsSingleImage::validate_and_infer_types() {
void ExperimentalDetectronGenerateProposalsSingleImage::validate_and_infer_types() {
OV_OP_SCOPE(v6_ExperimentalDetectronGenerateProposalsSingleImage_validate_and_infer_types);
std::vector<ov::PartialShape> output_shapes = {ov::PartialShape{}, ov::PartialShape{}};
std::vector<ov::PartialShape> input_shapes = {get_input_partial_shape(0),
get_input_partial_shape(1),
get_input_partial_shape(2),
get_input_partial_shape(3)};
shape_infer(this, input_shapes, output_shapes);
const auto input_size = get_input_size();
auto out_et = element::dynamic;
const auto& input_et = get_input_element_type(0);
set_output_type(0, input_et, output_shapes[0]);
set_output_type(1, input_et, output_shapes[1]);
auto input_shapes = std::vector<ov::PartialShape>();
input_shapes.reserve(input_size);
for (size_t i = 0; i < input_size; ++i) {
NODE_VALIDATION_CHECK(this,
element::Type::merge(out_et, out_et, get_input_element_type(i)) &&
(out_et.is_dynamic() || out_et.is_real()),
"Input[",
i,
"] type '",
get_input_element_type(i),
"' is not floating point or not same as others inputs.");
input_shapes.push_back(get_input_partial_shape(i));
}
const auto output_shapes = shape_infer(this, input_shapes);
set_output_type(0, out_et, output_shapes[0]);
set_output_type(1, out_et, output_shapes[1]);
}
void ExperimentalDetectronGenerateProposalsSingleImage::set_attrs(Attributes attrs) {
m_attrs = std::move(attrs);
}
} // namespace v6
} // namespace op
} // namespace ov

View File

@@ -4,107 +4,375 @@
#include <vector>
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "common_test_utils/test_assertions.hpp"
#include "gmock/gmock.h"
#include "openvino/opsets/opset11.hpp"
#include "util/type_prop.hpp"
using namespace ngraph;
using namespace ov;
using namespace ov::opset11;
using namespace testing;
using ExperimentalProposals = op::v6::ExperimentalDetectronGenerateProposalsSingleImage;
using Attrs = op::v6::ExperimentalDetectronGenerateProposalsSingleImage::Attributes;
class TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test
: public TypePropOpTest<op::v6::ExperimentalDetectronGenerateProposalsSingleImage> {
protected:
using Attrs = op::v6::ExperimentalDetectronGenerateProposalsSingleImage::Attributes;
TEST(type_prop, detectron_proposals) {
Attrs attrs;
attrs.min_size = 0.0f;
attrs.nms_threshold = 0.699999988079071f;
attrs.post_nms_count = 1000;
attrs.pre_nms_count = 1000;
size_t post_nms_count = 1000;
auto im_info = std::make_shared<op::Parameter>(element::f32, Shape{3});
auto anchors = std::make_shared<op::Parameter>(element::f32, Shape{201600, 4});
auto deltas = std::make_shared<op::Parameter>(element::f32, Shape{12, 200, 336});
auto scores = std::make_shared<op::Parameter>(element::f32, Shape{3, 200, 336});
auto proposals = std::make_shared<ExperimentalProposals>(im_info, anchors, deltas, scores, attrs);
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
EXPECT_EQ(proposals->get_output_shape(0), (Shape{post_nms_count, 4}));
EXPECT_EQ(proposals->get_output_shape(1), (Shape{post_nms_count}));
im_info = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(1));
anchors = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(2));
deltas = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(3));
scores = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(3));
proposals = std::make_shared<ExperimentalProposals>(im_info, anchors, deltas, scores, attrs);
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
EXPECT_EQ(proposals->get_output_shape(0), (Shape{post_nms_count, 4}));
EXPECT_EQ(proposals->get_output_shape(1), (Shape{post_nms_count}));
}
TEST(type_prop, detectron_proposals_dynamic) {
struct ShapesAndAttrs {
PartialShape im_info_shape;
PartialShape anchors_shape;
PartialShape deltas_shape;
PartialShape scores_shape;
size_t post_nms_count;
};
const auto dyn_dim = Dimension::dynamic();
const auto dyn_shape = PartialShape::dynamic();
std::vector<ShapesAndAttrs> shapes = {
{{3}, {201600, 4}, {12, 200, 336}, {3, 200, 336}, 1000},
{{3}, {201600, 4}, {12, 200, 336}, dyn_shape, 500},
{{3}, {201600, 4}, dyn_shape, {3, 200, 336}, 700},
{{3}, {201600, 4}, dyn_shape, dyn_shape, 300},
{{3}, dyn_shape, {12, 200, 336}, {3, 200, 336}, 200},
{{3}, dyn_shape, {12, 200, 336}, dyn_shape, 40},
{{3}, dyn_shape, dyn_shape, {3, 200, 336}, 70},
{{3}, dyn_shape, dyn_shape, dyn_shape, 60},
{dyn_shape, {201600, 4}, {12, 200, 336}, {3, 200, 336}, 500},
{dyn_shape, {201600, 4}, {12, 200, 336}, dyn_shape, 400},
{dyn_shape, {201600, 4}, dyn_shape, {3, 200, 336}, 350},
{dyn_shape, {201600, 4}, dyn_shape, dyn_shape, 440},
{dyn_shape, dyn_shape, {12, 200, 336}, {3, 200, 336}, 315},
{dyn_shape, dyn_shape, {12, 200, 336}, dyn_shape, 130},
{dyn_shape, dyn_shape, dyn_shape, {3, 200, 336}, 1000},
{dyn_shape, dyn_shape, dyn_shape, dyn_shape, 700},
{{3}, {dyn_dim, 4}, {12, 200, 336}, {3, 200, 336}, 540},
{{3}, {dyn_dim, 4}, {12, 200, 336}, {dyn_dim, 200, 336}, 600},
{{3}, {dyn_dim, 4}, {dyn_dim, 200, 336}, {3, 200, 336}, 75},
{{3}, {dyn_dim, 4}, {dyn_dim, 200, 336}, {dyn_dim, 200, 336}, 80},
{{3}, {201600, 4}, {12, 200, dyn_dim}, {3, 200, dyn_dim}, 430},
{{3}, {201600, 4}, {12, dyn_dim, 336}, {3, dyn_dim, 336}, 180},
{{3}, {201600, 4}, {12, dyn_dim, dyn_dim}, {3, dyn_dim, dyn_dim}, 170},
{{3}, {dyn_dim, 4}, {12, 200, dyn_dim}, {3, 200, dyn_dim}, 200},
{{3}, {dyn_dim, 4}, {12, dyn_dim, 336}, {3, dyn_dim, 336}, 800},
{{3}, {dyn_dim, 4}, {12, dyn_dim, dyn_dim}, {3, dyn_dim, dyn_dim}, 560},
};
for (const auto& s : shapes) {
Attrs attrs;
attrs.min_size = 0.0f;
attrs.nms_threshold = 0.699999988079071f;
attrs.post_nms_count = static_cast<int64_t>(s.post_nms_count);
attrs.pre_nms_count = 1000;
auto im_info = std::make_shared<op::Parameter>(element::f32, s.im_info_shape);
auto anchors = std::make_shared<op::Parameter>(element::f32, s.anchors_shape);
auto deltas = std::make_shared<op::Parameter>(element::f32, s.deltas_shape);
auto scores = std::make_shared<op::Parameter>(element::f32, s.scores_shape);
auto proposals = std::make_shared<ExperimentalProposals>(im_info, anchors, deltas, scores, attrs);
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
EXPECT_EQ(proposals->get_output_shape(0), (Shape{s.post_nms_count, 4}));
EXPECT_EQ(proposals->get_output_shape(1), (Shape{s.post_nms_count}));
static Attrs make_attrs(int64_t post_nms_count) {
return {0.0f, 0.0f, post_nms_count, 0};
}
};
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, default_ctor) {
const auto im_info = std::make_shared<Parameter>(element::f32, Shape{3});
const auto anchors = std::make_shared<Parameter>(element::f32, Shape{201600, 4});
const auto deltas = std::make_shared<Parameter>(element::f32, Shape{12, 200, 336});
const auto scores = std::make_shared<Parameter>(element::f32, Shape{3, 200, 336});
const auto op = make_op();
op->set_arguments(OutputVector{im_info, anchors, deltas, scores});
op->set_attrs({1.1f, 20.3f, 20, 0});
op->validate_and_infer_types();
EXPECT_EQ(op->get_input_size(), 4);
EXPECT_EQ(op->get_output_size(), 2);
EXPECT_FLOAT_EQ(op->get_attrs().min_size, 1.1f);
EXPECT_FLOAT_EQ(op->get_attrs().nms_threshold, 20.3f);
EXPECT_EQ(op->get_attrs().post_nms_count, 20);
EXPECT_EQ(op->get_attrs().pre_nms_count, 0);
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::f32)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape", &Output<Node>::get_shape, Shape({20, 4})),
Property("ROIs Score shape", &Output<Node>::get_shape, Shape({20}))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, basic_shape_inference) {
const auto im_info = std::make_shared<Parameter>(element::f64, Shape{3});
const auto anchors = std::make_shared<Parameter>(element::f64, Shape{201600, 4});
const auto deltas = std::make_shared<Parameter>(element::f64, Shape{12, 200, 336});
const auto scores = std::make_shared<Parameter>(element::f64, Shape{3, 200, 336});
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(132));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::f64)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape", &Output<Node>::get_shape, Shape({132, 4})),
Property("ROIs Score shape", &Output<Node>::get_shape, Shape({132}))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, all_input_got_dynamic_type) {
const auto im_info = std::make_shared<Parameter>(element::dynamic, Shape{3});
const auto anchors = std::make_shared<Parameter>(element::dynamic, Shape{201600, 4});
const auto deltas = std::make_shared<Parameter>(element::dynamic, Shape{12, 200, 336});
const auto scores = std::make_shared<Parameter>(element::dynamic, Shape{3, 200, 336});
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(132));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::dynamic)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape", &Output<Node>::get_shape, Shape({132, 4})),
Property("ROIs Score shape", &Output<Node>::get_shape, Shape({132}))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, some_input_got_dynamic_type) {
const auto im_info = std::make_shared<Parameter>(element::dynamic, Shape{3});
const auto anchors = std::make_shared<Parameter>(element::f64, Shape{201600, 4});
const auto deltas = std::make_shared<Parameter>(element::f64, Shape{12, 200, 336});
const auto scores = std::make_shared<Parameter>(element::dynamic, Shape{3, 200, 336});
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(132));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::f64)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape", &Output<Node>::get_shape, Shape({132, 4})),
Property("ROIs Score shape", &Output<Node>::get_shape, Shape({132}))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, interval_shapes) {
auto im_info_shape = PartialShape{{2, 4}};
auto anchors_shape = PartialShape{{1, 201600}, {1, 4}};
auto deltas_shape = PartialShape{{1, 12}, {1, 200}, {336, -1}};
auto scores_shape = PartialShape{{1, 3}, {100, 200}, {2, 336}};
set_shape_labels(im_info_shape, 10);
set_shape_labels(anchors_shape, 20);
set_shape_labels(deltas_shape, 30);
set_shape_labels(scores_shape, 40);
const auto im_info = std::make_shared<Parameter>(element::f16, im_info_shape);
const auto anchors = std::make_shared<Parameter>(element::f16, anchors_shape);
const auto deltas = std::make_shared<Parameter>(element::f16, deltas_shape);
const auto scores = std::make_shared<Parameter>(element::f16, scores_shape);
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(44));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::f16)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape",
&Output<Node>::get_partial_shape,
AllOf(PartialShape({44, 4}), ResultOf(get_shape_labels, Each(ov::no_label)))),
Property("ROIs Score shape",
&Output<Node>::get_partial_shape,
AllOf(PartialShape({44}), ResultOf(get_shape_labels, Each(ov::no_label))))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, all_inputs_dynamic_rank) {
const auto im_info = std::make_shared<Parameter>(element::bf16, PartialShape::dynamic());
const auto anchors = std::make_shared<Parameter>(element::bf16, PartialShape::dynamic());
const auto deltas = std::make_shared<Parameter>(element::bf16, PartialShape::dynamic());
const auto scores = std::make_shared<Parameter>(element::bf16, PartialShape::dynamic());
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(100));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::bf16)));
EXPECT_THAT(op->outputs(),
ElementsAre(Property("ROIs shape",
&Output<Node>::get_partial_shape,
AllOf(PartialShape({100, 4}), ResultOf(get_shape_labels, Each(ov::no_label)))),
Property("ROIs Score shape",
&Output<Node>::get_partial_shape,
AllOf(PartialShape({100}), ResultOf(get_shape_labels, Each(ov::no_label))))));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, input_not_floating_point) {
const auto bad_param = std::make_shared<Parameter>(element::i32, PartialShape::dynamic());
const auto ok_param = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
OV_EXPECT_THROW(auto op = make_op(bad_param, ok_param, ok_param, ok_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[0] type 'i32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(ok_param, bad_param, ok_param, ok_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[1] type 'i32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(ok_param, ok_param, bad_param, ok_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[2] type 'i32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(ok_param, ok_param, ok_param, bad_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[3] type 'i32' is not floating point or not same as others inputs"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, input_mixed_floating_point_type) {
const auto f32_param = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
const auto f16_param = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
OV_EXPECT_THROW(auto op = make_op(f32_param, f16_param, f16_param, f16_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[1] type 'f16' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(f16_param, f32_param, f16_param, f16_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[1] type 'f32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(f16_param, f16_param, f32_param, f16_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[2] type 'f32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(auto op = make_op(f16_param, f16_param, f16_param, f32_param, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Input[3] type 'f32' is not floating point or not same as others inputs"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, im_infos_not_1d) {
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{10, 5});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{5, 50, 20});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(std::make_shared<Parameter>(element::f32, PartialShape{}),
anchors,
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_im_info' input is expected to be a 1D"));
OV_EXPECT_THROW(auto op = make_op(std::make_shared<Parameter>(element::f32, PartialShape{2, 3}),
anchors,
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_im_info' input is expected to be a 1D"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, anchors_not_2d) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{5, 50, 20});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(im_info,
std::make_shared<Parameter>(element::f32, PartialShape{1}),
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_anchors' input is expected to be a 2D"));
OV_EXPECT_THROW(auto op = make_op(im_info,
std::make_shared<Parameter>(element::f32, PartialShape{2, 3, 1}),
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_anchors' input is expected to be a 2D"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, deltas_not_3d) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{5, 4});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(im_info,
anchors,
std::make_shared<Parameter>(element::f32, PartialShape{1}),
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_deltas' input is expected to be a 3D"));
OV_EXPECT_THROW(auto op = make_op(im_info,
anchors,
std::make_shared<Parameter>(element::f32, PartialShape{2, 50, 20, 3}),
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_deltas' input is expected to be a 3D"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, scores_not_3d) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{5, 4});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(im_info,
anchors,
deltas,
std::make_shared<Parameter>(element::f32, PartialShape{1}),
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_scores' input is expected to be a 3D"));
OV_EXPECT_THROW(auto op = make_op(im_info,
anchors,
deltas,
std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20, 11}),
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_scores' input is expected to be a 3D"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, im_info_dim0_not_compatible) {
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{5, 4});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(std::make_shared<Parameter>(element::f32, PartialShape{{0, 2}}),
anchors,
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_im_info' shape is expected to be a compatible with [3]"));
OV_EXPECT_THROW(auto op = make_op(std::make_shared<Parameter>(element::f32, PartialShape{{4, -1}}),
anchors,
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The 'input_im_info' shape is expected to be a compatible with [3]"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, anchors_dim1_not_compatible) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, 50, 20});
OV_EXPECT_THROW(auto op = make_op(im_info,
std::make_shared<Parameter>(element::f32, PartialShape{10, {0, 3}}),
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The second dimension of 'input_anchors' should be compatible with 4"));
OV_EXPECT_THROW(auto op = make_op(im_info,
std::make_shared<Parameter>(element::f32, PartialShape{10, {5, -1}}),
deltas,
scores,
make_attrs(100)),
NodeValidationFailure,
HasSubstr("The second dimension of 'input_anchors' should be compatible with 4"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, heights_deltas_and_scores_not_compatible) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{5, 4});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{15, {0, 50}, 20});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, {51, -1}, 20});
OV_EXPECT_THROW(auto op = make_op(im_info, anchors, deltas, scores, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Heights for inputs 'input_deltas' and 'input_scores' should be equal"));
}
TEST_F(TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test, widths_deltas_and_scores_not_compatible) {
const auto im_info = std::make_shared<Parameter>(element::f32, PartialShape{3});
const auto anchors = std::make_shared<Parameter>(element::f32, PartialShape{5, 4});
const auto deltas = std::make_shared<Parameter>(element::f32, PartialShape{15, {0, 100}, {0, 20}});
const auto scores = std::make_shared<Parameter>(element::f32, PartialShape{15, {51, 60}, {21, -1}});
OV_EXPECT_THROW(auto op = make_op(im_info, anchors, deltas, scores, make_attrs(100)),
NodeValidationFailure,
HasSubstr("Width for inputs 'input_deltas' and 'input_scores' should be equal"));
}
using DetectronGenerateProposalsParams = std::tuple<PartialShape, PartialShape, PartialShape, PartialShape, int64_t>;
class ExperimentalDetectronGenerateProposalsSingleImageV6Test
: public TypePropExperimentalDetectronGenerateProposalsSingleImageV6Test,
public WithParamInterface<DetectronGenerateProposalsParams> {
protected:
void SetUp() override {
std::tie(im_info_shape, anchors_shape, deltas_shape, scores_shape, post_nms_count) = GetParam();
}
PartialShape im_info_shape, anchors_shape, deltas_shape, scores_shape;
int64_t post_nms_count;
};
INSTANTIATE_TEST_SUITE_P(
type_prop,
ExperimentalDetectronGenerateProposalsSingleImageV6Test,
Values(DetectronGenerateProposalsParams({3}, {2, -1}, {-1, 10, 20}, {10, 10, 20}, 10),
DetectronGenerateProposalsParams({{1, 4}}, {-1, {4, 5}}, {2, -1, 20}, {10, 10, 20}, 20),
DetectronGenerateProposalsParams({-1}, {{100, 200}, 4}, {2, {0, 20}, -1}, {{10, 12}, 10, 20}, 30),
DetectronGenerateProposalsParams({3}, {10, 4}, {2, {0, 20}, 100}, {{10, 12}, {10, 20}, {20, -1}}, 40),
DetectronGenerateProposalsParams(PartialShape::dynamic(), {100, 4}, {5, 33, 55}, {21, 33, 55}, 100),
DetectronGenerateProposalsParams({3}, PartialShape::dynamic(), {2, 33, 55}, {5, 33, 55}, 200),
DetectronGenerateProposalsParams({3}, {100, 4}, PartialShape::dynamic(), {5, 33, 55}, 300),
DetectronGenerateProposalsParams({3}, {100, 4}, PartialShape::dynamic(), {5, 33, 55}, 400),
DetectronGenerateProposalsParams({3}, {100, 4}, {5, 33, 55}, PartialShape::dynamic(), 500),
DetectronGenerateProposalsParams(PartialShape::dynamic(1),
PartialShape::dynamic(2),
PartialShape::dynamic(3),
PartialShape::dynamic(3),
100)),
PrintToStringParamName());
TEST_P(ExperimentalDetectronGenerateProposalsSingleImageV6Test, static_rank_shape_inference) {
const auto im_info = std::make_shared<Parameter>(element::f32, im_info_shape);
const auto anchors = std::make_shared<Parameter>(element::f32, anchors_shape);
const auto deltas = std::make_shared<Parameter>(element::f32, deltas_shape);
const auto scores = std::make_shared<Parameter>(element::f32, scores_shape);
const auto op = make_op(im_info, anchors, deltas, scores, make_attrs(post_nms_count));
EXPECT_THAT(op->outputs(), Each(Property("Element type", &Output<Node>::get_element_type, element::f32)));
EXPECT_THAT(
op->outputs(),
ElementsAre(Property("ROIs shape", &Output<Node>::get_partial_shape, PartialShape({post_nms_count, 4})),
Property("ROIs Score shape", &Output<Node>::get_partial_shape, PartialShape({post_nms_count}))));
}

View File

@@ -1,39 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <openvino/op/experimental_detectron_generate_proposals.hpp>
#include "utils.hpp"
using namespace ov;
using namespace ov::intel_cpu;
using ExperimentalProposals = op::v6::ExperimentalDetectronGenerateProposalsSingleImage;
TEST(StaticShapeInferenceTest, ExperimentalProposalsTest) {
ExperimentalProposals::Attributes attrs;
attrs.min_size = 0.0f;
attrs.nms_threshold = 0.699999988079071f;
attrs.post_nms_count = 1000;
attrs.pre_nms_count = 1000;
size_t post_nms_count = 1000;
auto im_info = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{-1});
auto anchors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{-1, -1});
auto deltas = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{-1, -1, -1});
auto scores = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{-1, -1, -1});
auto proposals = std::make_shared<ExperimentalProposals>(im_info, anchors, deltas, scores, attrs);
const std::vector<StaticShape> input_shapes = {StaticShape{3},
StaticShape{201600, 4},
StaticShape{12, 200, 336},
StaticShape{3, 200, 336}};
std::vector<StaticShape> output_shapes = {StaticShape{}, StaticShape{}};
shape_inference(proposals.get(), input_shapes, output_shapes);
ASSERT_EQ(output_shapes[0], (StaticShape{post_nms_count, 4}));
ASSERT_EQ(output_shapes[1], (StaticShape{post_nms_count}));
}

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "common_test_utils/test_assertions.hpp"
#include "experimental_detectron_generate_proposals_shape_inference.hpp"
#include "utils.hpp"
using namespace ov;
using namespace ov::intel_cpu;
using namespace testing;
class ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest
: public OpStaticShapeInferenceTest<op::v6::ExperimentalDetectronGenerateProposalsSingleImage> {
protected:
void SetUp() override {
output_shapes.resize(2);
}
static op_type::Attributes make_attrs(int64_t post_nms_count) {
return {0.0f, 0.0f, post_nms_count, 0};
}
};
TEST_F(ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest, default_ctor) {
op = make_op();
op->set_attrs({0.0f, 0.0f, 100, 0});
input_shapes = ShapeVector{{3}, {12, 4}, {3, 12, 15}, {5, 12, 15}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes, ShapeVector({{100, 4}, {100}}));
}
TEST_F(ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest, inputs_dynamic_rank) {
const auto im_info = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic());
const auto anchors = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic());
const auto deltas = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic());
const auto scores = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic());
op = make_op(im_info, anchors, deltas, scores, make_attrs(100));
input_shapes = ShapeVector{{3}, {12, 4}, {3, 12, 15}, {5, 12, 15}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes, ShapeVector({{100, 4}, {100}}));
}
TEST_F(ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest, inputs_static_rank) {
const auto im_info = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic(1));
const auto anchors = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic(2));
const auto deltas = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic(3));
const auto scores = std::make_shared<op::v0::Parameter>(element::f16, PartialShape::dynamic(3));
op = make_op(im_info, anchors, deltas, scores, make_attrs(1000));
input_shapes = ShapeVector{{3}, {12, 4}, {3, 120, 15}, {5, 120, 15}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes, ShapeVector({{1000, 4}, {1000}}));
}
TEST_F(ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest, im_info_bad_dimension) {
const auto im_info = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(1));
const auto anchors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto deltas = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto scores = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(3));
op = make_op(im_info, anchors, deltas, scores, make_attrs(40));
input_shapes = ShapeVector{{4}, {12, 4}, {3, 120, 15}, {5, 120, 15}};
OV_EXPECT_THROW(shape_inference(op.get(), input_shapes, output_shapes),
NodeValidationFailure,
HasSubstr("The 'input_im_info' shape is expected to be a compatible with [3]"));
}
TEST_F(ExperimentalDetectronGenerateProposalsSingleImageV6StaticShapeInferenceTest, deltas_not_3d) {
const auto im_info = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(1));
const auto anchors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(2));
const auto deltas = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto scores = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(3));
op = make_op(im_info, anchors, deltas, scores, make_attrs(40));
input_shapes = ShapeVector{{3}, {12, 4}, {3, 120, 15, 1}, {5, 120, 15}};
OV_EXPECT_THROW(shape_inference(op.get(), input_shapes, output_shapes),
NodeValidationFailure,
HasSubstr("The 'input_deltas' input is expected to be a 3D"));
}