[ShapeInfer] Review experimental detectron prior grid generator class for shape inference aspects (#17474)

* Review detectron prior grid generator for:
- Check interval shapes and label propagation.
- Check template implementation of shape infer.
- Add update or correct unit test for static and dynamic shapes.

* Remove ngraph namespace in reviewed op

* Use detectron validation util to check inputs
in all related detectrons operators

* Relax first dim of feat map and im data check

* Fix test after dimension validation update

* Fix typo in detectron util file name
This commit is contained in:
Pawel Raasz
2023-05-16 12:58:00 +02:00
committed by GitHub
parent 5ff0081489
commit 78bb0c4837
9 changed files with 484 additions and 369 deletions

View File

@@ -58,12 +58,12 @@ public:
return m_attrs;
}
/// \brief Set the attributes of the operation ExperimentalDetectronPriorGridGenerator.
/// \param attrs Attributes to set.
void set_attrs(Attributes attrs);
private:
Attributes m_attrs;
template <class T>
friend void shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
const std::vector<T>& input_shapes,
std::vector<T>& output_shapes);
};
} // namespace v6
} // namespace op

View File

@@ -2,30 +2,31 @@
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <openvino/op/experimental_detectron_prior_grid_generator.hpp>
#include "openvino/op/experimental_detectron_prior_grid_generator.hpp"
namespace ov {
namespace op {
namespace v6 {
template <class T>
void shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
const std::vector<T>& input_shapes,
std::vector<T>& output_shapes) {
NODE_VALIDATION_CHECK(op, input_shapes.size() == 3 && output_shapes.size() == 1);
template <class TShape>
std::vector<TShape> shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
const std::vector<TShape>& input_shapes) {
NODE_VALIDATION_CHECK(op, input_shapes.size() == 3);
const auto& priors_shape = input_shapes[0];
const auto& featmap_shape = input_shapes[1];
const auto& im_data_shape = input_shapes[2];
auto& output_shape = output_shapes[0];
size_t output_size = op->m_attrs.flatten ? 2 : 4;
const auto is_flatten = op->get_attrs().flatten;
const size_t output_size = is_flatten ? 2 : 4;
TShape output_shape;
output_shape.resize(output_size);
output_shape[output_size - 1] = 4;
bool prior_rank_static = priors_shape.rank().is_static();
bool featmap_rank_static = featmap_shape.rank().is_static();
bool im_data_rank_static = im_data_shape.rank().is_static();
const auto prior_rank_static = priors_shape.rank().is_static();
const auto featmap_rank_static = featmap_shape.rank().is_static();
const auto im_data_rank_static = im_data_shape.rank().is_static();
if (prior_rank_static) {
NODE_VALIDATION_CHECK(op, priors_shape.size() == 2, "Priors rank must be equal to 2.");
@@ -41,22 +42,19 @@ void shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
if (im_data_rank_static) {
NODE_VALIDATION_CHECK(op, im_data_shape.size() == 4, "Im_data rank must be equal to 4.");
if (featmap_rank_static) {
NODE_VALIDATION_CHECK(op,
featmap_shape[0].compatible(im_data_shape[0]),
"The first dimension of both 'feature_map' and 'im_data' must match. "
"Feature_map: ",
featmap_shape[0],
"; Im_data: ",
im_data_shape[0]);
}
}
if (featmap_rank_static && im_data_rank_static) {
const auto& num_batches_featmap = featmap_shape[0];
const auto& num_batches_im_data = im_data_shape[0];
NODE_VALIDATION_CHECK(op,
num_batches_featmap.compatible(num_batches_im_data),
"The first dimension of both 'feature_map' and 'im_data' must match. "
"Feature_map: ",
num_batches_featmap,
"; Im_data: ",
num_batches_im_data);
}
if (op->m_attrs.flatten) {
if (is_flatten) {
if (prior_rank_static && featmap_rank_static) {
output_shape[0] = featmap_shape[2] * featmap_shape[3] * priors_shape[0];
}
@@ -69,6 +67,15 @@ void shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
output_shape[2] = priors_shape[0];
}
}
return {output_shape};
}
template <class TShape>
void shape_infer(const ExperimentalDetectronPriorGridGenerator* op,
const std::vector<TShape>& input_shapes,
std::vector<TShape>& output_shapes) {
output_shapes = shape_infer(op, input_shapes);
}
} // namespace v6

View File

@@ -7,6 +7,7 @@
#include <memory>
#include "experimental_detectron_detection_output_shape_inference.hpp"
#include "experimental_detectron_shape_infer_utils.hpp"
#include "itt.hpp"
#include "openvino/core/attribute_visitor.hpp"
@@ -39,29 +40,12 @@ bool op::v6::ExperimentalDetectronDetectionOutput::visit_attributes(AttributeVis
void op::v6::ExperimentalDetectronDetectionOutput::validate_and_infer_types() {
OV_OP_SCOPE(v6_ExperimentalDetectronDetectionOutput_validate_and_infer_types);
const auto input_size = get_input_size();
auto out_et = element::dynamic;
const auto shapes_and_type = detectron::validate::all_inputs_same_floating_type(this);
const auto output_shapes = shape_infer(this, shapes_and_type.first);
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(0, shapes_and_type.second, output_shapes[0]);
set_output_type(1, element::i32, output_shapes[1]);
set_output_type(2, out_et, output_shapes[2]);
set_output_type(2, shapes_and_type.second, output_shapes[2]);
}
shared_ptr<Node> op::v6::ExperimentalDetectronDetectionOutput::clone_with_new_inputs(

View File

@@ -5,6 +5,7 @@
#include "openvino/op/experimental_detectron_generate_proposals.hpp"
#include "experimental_detectron_generate_proposals_shape_inference.hpp"
#include "experimental_detectron_shape_infer_utils.hpp"
#include "itt.hpp"
#include "openvino/core/attribute_visitor.hpp"
@@ -47,28 +48,11 @@ bool ExperimentalDetectronGenerateProposalsSingleImage::visit_attributes(Attribu
void ExperimentalDetectronGenerateProposalsSingleImage::validate_and_infer_types() {
OV_OP_SCOPE(v6_ExperimentalDetectronGenerateProposalsSingleImage_validate_and_infer_types);
const auto input_size = get_input_size();
auto out_et = element::dynamic;
const auto shapes_and_type = detectron::validate::all_inputs_same_floating_type(this);
const auto output_shapes = shape_infer(this, shapes_and_type.first);
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]);
set_output_type(0, shapes_and_type.second, output_shapes[0]);
set_output_type(1, shapes_and_type.second, output_shapes[1]);
}
void ExperimentalDetectronGenerateProposalsSingleImage::set_attrs(Attributes attrs) {

View File

@@ -2,18 +2,16 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "ngraph/op/experimental_detectron_prior_grid_generator.hpp"
#include "openvino/op/experimental_detectron_prior_grid_generator.hpp"
#include <experimental_detectron_prior_grid_generator_shape_inference.hpp>
#include <memory>
#include "experimental_detectron_prior_grid_generator_shape_inference.hpp"
#include "experimental_detectron_shape_infer_utils.hpp"
#include "itt.hpp"
#include "ngraph/attribute_visitor.hpp"
#include "ngraph/runtime/host_tensor.hpp"
using namespace std;
using namespace ngraph;
#include "openvino/core/attribute_visitor.hpp"
namespace ov {
op::v6::ExperimentalDetectronPriorGridGenerator::ExperimentalDetectronPriorGridGenerator(
const Output<Node>& priors,
const Output<Node>& feature_map,
@@ -34,29 +32,26 @@ bool op::v6::ExperimentalDetectronPriorGridGenerator::visit_attributes(Attribute
return true;
}
shared_ptr<Node> op::v6::ExperimentalDetectronPriorGridGenerator::clone_with_new_inputs(
std::shared_ptr<Node> op::v6::ExperimentalDetectronPriorGridGenerator::clone_with_new_inputs(
const OutputVector& new_args) const {
OV_OP_SCOPE(v6_ExperimentalDetectronPriorGridGenerator_clone_with_new_inputs);
check_new_args_count(this, new_args);
return make_shared<op::v6::ExperimentalDetectronPriorGridGenerator>(new_args.at(0),
new_args.at(1),
new_args.at(2),
m_attrs);
return std::make_shared<ExperimentalDetectronPriorGridGenerator>(new_args.at(0),
new_args.at(1),
new_args.at(2),
m_attrs);
}
static constexpr size_t priors_port = 0;
static constexpr size_t featmap_port = 1;
static constexpr size_t im_data_port = 2;
void op::v6::ExperimentalDetectronPriorGridGenerator::validate_and_infer_types() {
OV_OP_SCOPE(v6_ExperimentalDetectronPriorGridGenerator_validate_and_infer_types);
const auto& priors_shape = get_input_partial_shape(priors_port);
const auto& featmap_shape = get_input_partial_shape(featmap_port);
const auto& input_et = get_input_element_type(0);
set_output_size(1);
std::vector<ov::PartialShape> output_shapes = {ov::PartialShape{}};
std::vector<ov::PartialShape> input_shapes = {priors_shape, featmap_shape, get_input_partial_shape(im_data_port)};
shape_infer(this, input_shapes, output_shapes);
set_output_type(0, input_et, output_shapes[0]);
const auto shapes_and_type = detectron::validate::all_inputs_same_floating_type(this);
const auto output_shapes = shape_infer(this, shapes_and_type.first);
set_output_type(0, shapes_and_type.second, output_shapes[0]);
}
void op::v6::ExperimentalDetectronPriorGridGenerator::set_attrs(Attributes attrs) {
m_attrs = std::move(attrs);
}
} // namespace ov

View File

@@ -2,254 +2,347 @@
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "common_test_utils/test_assertions.hpp"
#include "gmock/gmock.h"
#include "openvino/opsets/opset11.hpp"
#include "type_prop.hpp"
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/type_prop.hpp"
using namespace ov;
using namespace ov::opset11;
using namespace testing;
using namespace ngraph;
class TypePropExperimentalDetectronPriorGridGeneratorV6Test
: public TypePropOpTest<op::v6::ExperimentalDetectronPriorGridGenerator> {
protected:
using Attrs = op::v6::ExperimentalDetectronPriorGridGenerator::Attributes;
using Attrs = op::v6::ExperimentalDetectronPriorGridGenerator::Attributes;
using GridGenerator = op::v6::ExperimentalDetectronPriorGridGenerator;
TEST(type_prop, detectron_grid_generator_static_shape_flatten) {
Attrs attrs;
attrs.flatten = true;
attrs.h = 0;
attrs.w = 0;
attrs.stride_x = 4.0f;
attrs.stride_y = 4.0f;
auto priors = std::make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto feature_map = std::make_shared<op::Parameter>(element::f32, Shape{1, 256, 200, 336});
auto im_data = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 800, 1344});
auto grid_gen = std::make_shared<GridGenerator>(priors, feature_map, im_data, attrs);
ASSERT_EQ(grid_gen->get_output_element_type(0), element::f32);
EXPECT_EQ(grid_gen->get_output_shape(0), (Shape{201600, 4}));
}
TEST(type_prop, detectron_grid_generator_static_shape_without_flatten) {
Attrs attrs;
attrs.flatten = false;
attrs.h = 0;
attrs.w = 0;
attrs.stride_x = 4.0f;
attrs.stride_y = 4.0f;
auto priors = std::make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto feature_map = std::make_shared<op::Parameter>(element::f32, Shape{1, 256, 200, 336});
auto im_data = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 800, 1344});
auto grid_gen = std::make_shared<GridGenerator>(priors, feature_map, im_data, attrs);
ASSERT_EQ(grid_gen->get_output_element_type(0), element::f32);
EXPECT_EQ(grid_gen->get_output_shape(0), (Shape{200, 336, 3, 4}));
}
TEST(type_prop, detectron_grid_generator_dynamic_shapes) {
Attrs attrs;
attrs.flatten = false;
attrs.h = 0;
attrs.w = 0;
attrs.stride_x = 4.0f;
attrs.stride_y = 4.0f;
struct ShapesAndAttrs {
PartialShape priors_shape;
PartialShape feature_map_shape;
PartialShape ref_out_shape;
bool flatten;
static Attrs make_attrs(bool flatten) {
return {flatten, 0, 0, 4.0f, 4.0f};
};
const Shape im_data_shape = Shape{1, 3, 800, 1344};
const auto dyn_dim = Dimension::dynamic();
std::vector<ShapesAndAttrs> shapes = {
{{3, 4}, {1, 256, 200, dyn_dim}, {dyn_dim, 4}, true},
{{3, 4}, {1, 256, dyn_dim, 336}, {dyn_dim, 4}, true},
{{3, 4}, {1, 256, dyn_dim, dyn_dim}, {dyn_dim, 4}, true},
{{dyn_dim, 4}, {1, 256, 200, dyn_dim}, {dyn_dim, 4}, true},
{{dyn_dim, 4}, {1, 256, dyn_dim, 336}, {dyn_dim, 4}, true},
{{dyn_dim, 4}, {1, 256, dyn_dim, dyn_dim}, {dyn_dim, 4}, true},
{{3, 4}, {1, 256, 200, dyn_dim}, {200, dyn_dim, 3, 4}, false},
{{3, 4}, {1, 256, dyn_dim, 336}, {dyn_dim, 336, 3, 4}, false},
{{3, 4}, {1, 256, dyn_dim, dyn_dim}, {dyn_dim, dyn_dim, 3, 4}, false},
{{dyn_dim, 4}, {1, 256, 200, dyn_dim}, {200, dyn_dim, dyn_dim, 4}, false},
{{dyn_dim, 4}, {1, 256, dyn_dim, 336}, {dyn_dim, 336, dyn_dim, 4}, false},
{{dyn_dim, 4}, {1, 256, dyn_dim, dyn_dim}, {dyn_dim, dyn_dim, dyn_dim, 4}, false}};
for (const auto& s : shapes) {
auto grid_attrs = attrs;
grid_attrs.flatten = s.flatten;
auto priors = std::make_shared<op::Parameter>(element::f32, s.priors_shape);
auto feature_map = std::make_shared<op::Parameter>(element::f32, s.feature_map_shape);
auto im_data = std::make_shared<op::Parameter>(element::f32, im_data_shape);
auto grid_gen = std::make_shared<GridGenerator>(priors, feature_map, im_data, grid_attrs);
ASSERT_EQ(grid_gen->get_output_element_type(0), element::f32);
ASSERT_TRUE(grid_gen->get_output_partial_shape(0).same_scheme(s.ref_out_shape));
}
}
struct GridGeneratorIntervalsTestParams {
PartialShape priors_shape;
PartialShape feature_map_shape;
PartialShape im_data_shape;
PartialShape ref_out_shape;
bool flatten;
};
struct GridGeneratorIntervalsTest : ::testing::TestWithParam<GridGeneratorIntervalsTestParams> {};
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, default_ctor_no_flatten) {
const auto priors = std::make_shared<Parameter>(element::f32, Shape{3, 4});
const auto feature_map = std::make_shared<Parameter>(element::f32, Shape{1, 3, 200, 336});
const auto im_data = std::make_shared<Parameter>(element::f32, Shape{1, 3, 800, 1344});
TEST_P(GridGeneratorIntervalsTest, detectron_grid_generator_dynamic_shapes_intervals_2) {
auto params = GetParam();
const auto op = make_op();
op->set_arguments(OutputVector{priors, feature_map, im_data});
op->set_attrs(make_attrs(false));
op->validate_and_infer_types();
Attrs attrs;
attrs.flatten = false;
attrs.h = 0;
attrs.w = 0;
attrs.stride_x = 4.0f;
attrs.stride_y = 4.0f;
auto grid_attrs = attrs;
grid_attrs.flatten = params.flatten;
auto priors = std::make_shared<op::Parameter>(element::f32, params.priors_shape);
auto feature_map = std::make_shared<op::Parameter>(element::f32, params.feature_map_shape);
auto im_data = std::make_shared<op::Parameter>(element::f32, params.im_data_shape);
auto grid_gen = std::make_shared<GridGenerator>(priors, feature_map, im_data, grid_attrs);
ASSERT_EQ(grid_gen->get_output_element_type(0), element::f32);
ASSERT_TRUE(grid_gen->get_output_partial_shape(0).same_scheme(params.ref_out_shape));
EXPECT_EQ(op->get_output_element_type(0), element::f32);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({200, 336, 3, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, static_shape_flatten) {
auto priors_shape = PartialShape{3, 4};
auto feat_map_shape = PartialShape{1, 4, 6, 10};
auto im_data_shape = PartialShape{1, 4, 128, 128};
set_shape_labels(priors_shape, 10);
set_shape_labels(feat_map_shape, 20);
set_shape_labels(im_data_shape, 30);
const auto priors = std::make_shared<Parameter>(element::f64, priors_shape);
const auto feature_map = std::make_shared<Parameter>(element::f64, feat_map_shape);
const auto im_data = std::make_shared<Parameter>(element::f64, im_data_shape);
const auto op = make_op(priors, feature_map, im_data, make_attrs(true));
EXPECT_EQ(op->get_output_element_type(0), element::f64);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({180, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, static_shape_without_flatten) {
auto priors_shape = PartialShape{3, 4};
auto feat_map_shape = PartialShape{1, 4, 6, 10};
auto im_data_shape = PartialShape{1, 4, 128, 128};
set_shape_labels(priors_shape, 10);
set_shape_labels(feat_map_shape, 20);
set_shape_labels(im_data_shape, 30);
const auto priors = std::make_shared<Parameter>(element::f16, priors_shape);
const auto feature_map = std::make_shared<Parameter>(element::f16, feat_map_shape);
const auto im_data = std::make_shared<Parameter>(element::f16, im_data_shape);
const auto op = make_op(priors, feature_map, im_data, make_attrs(false));
EXPECT_EQ(op->get_output_element_type(0), element::f16);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({6, 10, 3, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), ElementsAre(22, 23, 10, no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, interval_shapes_flatten) {
auto priors_shape = PartialShape{{2, 5}, {0, 4}};
auto feat_map_shape = PartialShape{1, {3, 4}, {5, 10}, {9, 10}};
auto im_data_shape = PartialShape{1, {2, 4}, {1, 128}, {1, 128}};
set_shape_labels(priors_shape, 10);
set_shape_labels(feat_map_shape, 20);
set_shape_labels(im_data_shape, 30);
const auto priors = std::make_shared<Parameter>(element::bf16, priors_shape);
const auto feature_map = std::make_shared<Parameter>(element::bf16, feat_map_shape);
const auto im_data = std::make_shared<Parameter>(element::bf16, im_data_shape);
const auto op = make_op(priors, feature_map, im_data, make_attrs(true));
EXPECT_EQ(op->get_output_element_type(0), element::bf16);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({{90, 500}, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, interval_shapes_no_flatten) {
auto priors_shape = PartialShape{{2, 5}, {0, 4}};
auto feat_map_shape = PartialShape{1, {3, 4}, {5, 10}, {9, 10}};
auto im_data_shape = PartialShape{1, {2, 4}, {1, 128}, {1, 128}};
set_shape_labels(priors_shape, 10);
set_shape_labels(feat_map_shape, 20);
set_shape_labels(im_data_shape, 30);
const auto priors = std::make_shared<Parameter>(element::bf16, priors_shape);
const auto feature_map = std::make_shared<Parameter>(element::bf16, feat_map_shape);
const auto im_data = std::make_shared<Parameter>(element::bf16, im_data_shape);
const auto op = make_op(priors, feature_map, im_data, make_attrs(false));
EXPECT_EQ(op->get_output_element_type(0), element::bf16);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({{5, 10}, {9, 10}, {2, 5}, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), ElementsAre(22, 23, 10, no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, all_inputs_dynamic_rank_flatten) {
const auto priors = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto feature_map = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto im_data = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto op = make_op(priors, feature_map, im_data, make_attrs(true));
EXPECT_EQ(op->get_output_element_type(0), element::f16);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({-1, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, all_inputs_dynamic_rank_no_flatten) {
const auto priors = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto feature_map = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto im_data = std::make_shared<Parameter>(element::f16, PartialShape::dynamic());
const auto op = make_op(priors, feature_map, im_data, make_attrs(false));
EXPECT_EQ(op->get_output_element_type(0), element::f16);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({-1, -1, -1, 4}));
EXPECT_THAT(get_shape_labels(op->get_output_partial_shape(0)), Each(no_label));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, all_input_got_dynamic_type) {
const auto priors = std::make_shared<Parameter>(element::dynamic, Shape{2, 4});
const auto feature_map = std::make_shared<Parameter>(element::dynamic, Shape{1, 4, 5, 5});
const auto im_data = std::make_shared<Parameter>(element::dynamic, Shape{1, 4, 500, 500});
const auto op = make_op(priors, feature_map, im_data, make_attrs(false));
EXPECT_EQ(op->get_output_element_type(0), element::dynamic);
EXPECT_EQ(op->get_output_shape(0), Shape({5, 5, 2, 4}));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, some_input_got_dynamic_type) {
const auto priors = std::make_shared<Parameter>(element::dynamic, Shape{2, 4});
const auto feature_map = std::make_shared<Parameter>(element::f32, Shape{1, 4, 5, 5});
const auto im_data = std::make_shared<Parameter>(element::dynamic, Shape{1, 4, 500, 500});
const auto op = make_op(priors, feature_map, im_data, make_attrs(false));
EXPECT_EQ(op->get_output_element_type(0), element::f32);
EXPECT_EQ(op->get_output_shape(0), Shape({5, 5, 2, 4}));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, 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(std::ignore = make_op(bad_param, ok_param, ok_param, make_attrs(false)),
NodeValidationFailure,
HasSubstr("Input[0] type 'i32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(std::ignore = make_op(ok_param, bad_param, ok_param, make_attrs(false)),
NodeValidationFailure,
HasSubstr("Input[1] type 'i32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(std::ignore = make_op(ok_param, ok_param, bad_param, make_attrs(true)),
NodeValidationFailure,
HasSubstr("Input[2] type 'i32' is not floating point or not same as others inputs"));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, 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(std::ignore = make_op(f32_param, f16_param, f16_param, make_attrs(true)),
NodeValidationFailure,
HasSubstr("Input[1] type 'f16' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(std::ignore = make_op(f16_param, f32_param, f16_param, make_attrs(true)),
NodeValidationFailure,
HasSubstr("Input[1] type 'f32' is not floating point or not same as others inputs"));
OV_EXPECT_THROW(std::ignore = make_op(f16_param, f16_param, f32_param, make_attrs(true)),
NodeValidationFailure,
HasSubstr("Input[2] type 'f32' is not floating point or not same as others inputs"));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, priors_not_2d) {
const auto feature_map = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
const auto im_data = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
OV_EXPECT_THROW(std::ignore = make_op(std::make_shared<Parameter>(element::f32, PartialShape{2}),
feature_map,
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Priors rank must be equal to 2."));
OV_EXPECT_THROW(std::ignore = make_op(std::make_shared<Parameter>(element::f32, PartialShape{2, 3, 1}),
feature_map,
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Priors rank must be equal to 2."));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, feature_map_not_4d) {
const auto priors = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
const auto im_data = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
OV_EXPECT_THROW(std::ignore = make_op(priors,
std::make_shared<Parameter>(element::f32, PartialShape::dynamic(2)),
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Feature_map rank must be equal to 4"));
OV_EXPECT_THROW(std::ignore = make_op(priors,
std::make_shared<Parameter>(element::f32, PartialShape::dynamic(5)),
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Feature_map rank must be equal to 4"));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, im_data_not_4d) {
const auto priors = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
const auto feature_map = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
OV_EXPECT_THROW(std::ignore = make_op(priors,
feature_map,
std::make_shared<Parameter>(element::f32, PartialShape::dynamic(3)),
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Im_data rank must be equal to 4"));
OV_EXPECT_THROW(std::ignore = make_op(priors,
feature_map,
std::make_shared<Parameter>(element::f32, PartialShape::dynamic(15)),
make_attrs(false)),
NodeValidationFailure,
HasSubstr("Im_data rank must be equal to 4"));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, priors_2nd_dim_not_compatible) {
const auto feature_map = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
const auto im_data = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
OV_EXPECT_THROW(std::ignore = make_op(std::make_shared<Parameter>(element::f32, PartialShape{-1, {0, 3}}),
feature_map,
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("The last dimension of the 'priors' input must be equal to 4"));
OV_EXPECT_THROW(std::ignore = make_op(std::make_shared<Parameter>(element::f32, PartialShape{-1, {5, -1}}),
feature_map,
im_data,
make_attrs(false)),
NodeValidationFailure,
HasSubstr("The last dimension of the 'priors' input must be equal to 4"));
}
TEST_F(TypePropExperimentalDetectronPriorGridGeneratorV6Test, not_compatible_1st_dim_of_feature_map_and_im_data) {
const auto priors = std::make_shared<Parameter>(element::f32, PartialShape::dynamic());
OV_EXPECT_THROW(
std::ignore = make_op(priors,
std::make_shared<Parameter>(element::f32, PartialShape{3, {0, 3}, -1, -1}),
std::make_shared<Parameter>(element::f32, PartialShape{{0, 2}, {4, 0}, -1, -1}),
make_attrs(false)),
NodeValidationFailure,
HasSubstr("The first dimension of both 'feature_map' and 'im_data' must match"));
OV_EXPECT_THROW(
std::ignore = make_op(priors,
std::make_shared<Parameter>(element::f32, PartialShape{{0, 1}, 4, -1, -1}),
std::make_shared<Parameter>(element::f32, PartialShape{{2, -1}, {2, 10}, -1, -1}),
make_attrs(false)),
NodeValidationFailure,
HasSubstr("The first dimension of both 'feature_map' and 'im_data' must match"));
}
using DetectronPriorGridGenerator = std::tuple<PartialShape, PartialShape, PartialShape, PartialShape, bool>;
class ExperimentalDetectronPriorGridGeneratorV6Test : public TypePropExperimentalDetectronPriorGridGeneratorV6Test,
public WithParamInterface<DetectronPriorGridGenerator> {
protected:
void SetUp() override {
std::tie(priors_shape, feat_map_shape, im_data_shape, exp_shape, is_flatten) = GetParam();
}
PartialShape priors_shape, feat_map_shape, im_data_shape, exp_shape;
bool is_flatten;
};
INSTANTIATE_TEST_SUITE_P(
type_prop,
GridGeneratorIntervalsTest,
::testing::Values(GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, 200, Dimension(0, 100)},
{Dimension(0, 5), 3, 800, 1344},
{Dimension(0, 60000), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{Dimension(0, 7), 256, Dimension(0, 150), 336},
{Dimension(0, 5), 3, 800, 1344},
{Dimension(0, 151200), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, Dimension(0, 150), Dimension(0, 100)},
{Dimension(0, 11), 3, 800, 1344},
{Dimension(0, 45000), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, 200, Dimension(0, 150)},
{Dimension(0, 5), 3, 800, 1344},
{Dimension(0, 90000), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{Dimension(0, 77), 256, Dimension(0, 150), 336},
{Dimension(0, 54), 3, 800, 1344},
{Dimension(0, 151200), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{Dimension(0, 3), 256, Dimension(0, 150), Dimension(0, 100)},
{Dimension(0, 54), 3, 800, 1344},
{Dimension(0, 45000), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, 200, Dimension(0, 100)},
{Dimension(0, 6), 3, 800, 1344},
{200, Dimension(0, 100), 3, 4},
false},
GridGeneratorIntervalsTestParams{{3, 4},
{Dimension(0, 9), 256, Dimension(0, 150), 336},
{Dimension(0, 4), 3, 800, 1344},
{Dimension(0, 150), 336, 3, 4},
false},
GridGeneratorIntervalsTestParams{{3, 4},
{Dimension(1, 3), 256, Dimension(0, 150), Dimension(0, 100)},
{Dimension(0, 4), 3, 800, 1344},
{Dimension(0, 150), Dimension(0, 100), 3, 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{Dimension(5, 11), 256, 200, Dimension(0, 100)},
{Dimension(0, 17), 3, 800, 1344},
{200, Dimension(0, 100), Dimension(0, 3), 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{Dimension(7, 9), 256, Dimension(0, 150), 336},
{Dimension(4, 18), 3, 800, 1344},
{Dimension(0, 150), 336, Dimension(0, 3), 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{Dimension(0, 8), 256, Dimension(0, 150), Dimension(0, 100)},
{Dimension(4, 18), 3, 800, 1344},
{Dimension(0, 150), Dimension(0, 100), Dimension(0, 3), 4},
false},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, 200, Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{Dimension(0, 60000), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, Dimension(0, 150), 336},
Shape{1, 3, 800, 1344},
{Dimension(0, 151200), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, Dimension(0, 150), Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{Dimension(0, 45000), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, 200, Dimension(0, 150)},
Shape{1, 3, 800, 1344},
{Dimension(0, 90000), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, Dimension(0, 150), 336},
Shape{1, 3, 800, 1344},
{Dimension(0, 151200), 4},
true},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, Dimension(0, 150), Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{Dimension(0, 45000), 4},
true},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, 200, Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{200, Dimension(0, 100), 3, 4},
false},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, Dimension(0, 150), 336},
Shape{1, 3, 800, 1344},
{Dimension(0, 150), 336, 3, 4},
false},
GridGeneratorIntervalsTestParams{{3, 4},
{1, 256, Dimension(0, 150), Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{Dimension(0, 150), Dimension(0, 100), 3, 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, 200, Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{200, Dimension(0, 100), Dimension(0, 3), 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, Dimension(0, 150), 336},
Shape{1, 3, 800, 1344},
{Dimension(0, 150), 336, Dimension(0, 3), 4},
false},
GridGeneratorIntervalsTestParams{{Dimension(0, 3), 4},
{1, 256, Dimension(0, 150), Dimension(0, 100)},
Shape{1, 3, 800, 1344},
{Dimension(0, 150), Dimension(0, 100), Dimension(0, 3), 4},
false}),
PrintToDummyParamName());
ExperimentalDetectronPriorGridGeneratorV6Test,
Values(DetectronPriorGridGenerator(PartialShape::dynamic(), {1, -1, 5, 3}, {1, 3, 100, 100}, {5, 3, -1, 4}, false),
DetectronPriorGridGenerator(PartialShape::dynamic(2), {1, -1, 5, 3}, {1, 3, 100, 100}, {5, 3, -1, 4}, false),
DetectronPriorGridGenerator({2, 4}, {1, -1, 5, 3}, {1, 3, 100, 100}, {5, 3, 2, 4}, false),
DetectronPriorGridGenerator({{2, 4}, {2, 5}}, {1, 3, -1, 3}, {1, -1, 100, 100}, {-1, 3, {2, 4}, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape::dynamic(), {1, 5, -1, -1}, {-1, -1, 2, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape::dynamic(4), {1, 5, -1, -1}, {-1, -1, 2, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape{-1, -1, 6, 6}, {1, 5, -1, -1}, {6, 6, 2, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, {0, 5}, 7, 6}, {1, 5, -1, -1}, {7, 6, 2, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, 3, 7, 6}, PartialShape::dynamic(), {7, 6, 2, 4}, false),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, 3, 7, 6}, PartialShape::dynamic(4), {7, 6, 2, 4}, false),
DetectronPriorGridGenerator(PartialShape::dynamic(2),
PartialShape::dynamic(4),
PartialShape::dynamic(4),
PartialShape{-1, -1, -1, 4},
false),
// flatten on
DetectronPriorGridGenerator(PartialShape::dynamic(), {1, -1, 5, 3}, {1, 3, 100, 100}, {-1, 4}, true),
DetectronPriorGridGenerator(PartialShape::dynamic(2), {1, -1, 5, 3}, {1, 3, 100, 100}, {-1, 4}, true),
DetectronPriorGridGenerator({{2, 4}, 4}, {1, -1, 5, 3}, {1, 3, 100, 100}, {{30, 60}, 4}, true),
DetectronPriorGridGenerator({{2, 4}, {2, 5}}, {1, 3, -1, 3}, {1, -1, 100, 100}, {-1, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape::dynamic(), {1, 5, -1, -1}, {-1, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape::dynamic(4), {1, 5, -1, -1}, {-1, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape{-1, -1, 6, 6}, {1, 5, -1, -1}, {72, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, {0, 5}, {6, 7}, 6}, {1, 5, -1, -1}, {{72, 84}, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, 3, 7, 6}, PartialShape::dynamic(), {84, 4}, true),
DetectronPriorGridGenerator({2, 4}, PartialShape{1, 3, 7, 6}, PartialShape::dynamic(4), {84, 4}, true),
DetectronPriorGridGenerator(PartialShape::dynamic(2),
PartialShape::dynamic(4),
PartialShape::dynamic(4),
PartialShape{-1, 4},
true)),
PrintToStringParamName());
TEST_P(ExperimentalDetectronPriorGridGeneratorV6Test, shape_inference) {
const auto priors = std::make_shared<Parameter>(element::bf16, priors_shape);
const auto feat_map = std::make_shared<Parameter>(element::bf16, feat_map_shape);
const auto im_data = std::make_shared<Parameter>(element::bf16, im_data_shape);
const auto op = make_op(priors, feat_map, im_data, make_attrs(is_flatten));
EXPECT_EQ(op->get_output_partial_shape(0), exp_shape);
}

View File

@@ -29,7 +29,7 @@ TEST(attributes, detectron_prior_grid_generator) {
attrs.stride_y = 64;
auto priors = std::make_shared<op::Parameter>(element::f32, Shape{3, 4});
auto feature_map = std::make_shared<op::Parameter>(element::f32, Shape{1, 16, 100, 100});
auto feature_map = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 100, 100});
auto im_data = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 100, 200});
auto proposals = std::make_shared<ExperimentalGenerator>(priors, feature_map, im_data, attrs);

View File

@@ -1,34 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "utils.hpp"
using namespace ov;
using namespace ov::intel_cpu;
TEST(StaticShapeInferenceTest, PriorGridGenerator) {
op::v6::ExperimentalDetectronPriorGridGenerator::Attributes attrs;
attrs.flatten = false;
attrs.h = 0;
attrs.w = 0;
attrs.stride_x = 4.0f;
attrs.stride_y = 4.0f;
auto priors = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{-1, -1});
auto feature_map = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{-1, -1, -1, -1});
auto im_data = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{-1, -1, -1, -1});
auto grid_gen =
std::make_shared<ov::op::v6::ExperimentalDetectronPriorGridGenerator>(priors, feature_map, im_data, attrs);
std::vector<StaticShape> static_input_shapes = {StaticShape{3, 4},
StaticShape{1, 256, 200, 336},
StaticShape{1, 3, 800, 1344}},
static_output_shapes = {StaticShape{}};
shape_inference(grid_gen.get(), static_input_shapes, static_output_shapes);
ASSERT_EQ(static_output_shapes[0], StaticShape({200, 336, 3, 4}));
}

View File

@@ -0,0 +1,86 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include "common_test_utils/test_assertions.hpp"
#include "utils.hpp"
using namespace ov;
using namespace ov::intel_cpu;
using namespace testing;
class ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest
: public OpStaticShapeInferenceTest<op::v6::ExperimentalDetectronPriorGridGenerator> {
protected:
using Attrs = typename op_type::Attributes;
void SetUp() override {
output_shapes.resize(1);
}
static Attrs make_attrs(bool flatten) {
return {flatten, 0, 0, 4.0f, 4.0f};
}
};
TEST_F(ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest, default_ctor) {
op = make_op();
op->set_attrs({true, 0, 0, 5.0f, 5.0f});
input_shapes = ShapeVector{{3, 4}, {1, 5, 7, 2}, {1, 5, 50, 50}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes, ShapeVector({{42, 4}}));
}
TEST_F(ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest, inputs_dynamic_rank) {
const auto priors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto feat_map = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto im_data = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
op = make_op(priors, feat_map, im_data, make_attrs(false));
input_shapes = ShapeVector{{10, 4}, {1, 2, 4, 5}, {1, 2, 100, 100}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes.size(), 1);
EXPECT_EQ(output_shapes.front(), StaticShape({4, 5, 10, 4}));
}
TEST_F(ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest, inputs_static_rank) {
const auto priors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(2));
const auto feat_map = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(4));
const auto im_data = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(4));
op = make_op(priors, feat_map, im_data, make_attrs(true));
input_shapes = ShapeVector{{10, 4}, {1, 2, 4, 5}, {1, 2, 100, 100}};
shape_inference(op.get(), input_shapes, output_shapes);
EXPECT_EQ(output_shapes.size(), 1);
EXPECT_EQ(output_shapes.front(), StaticShape({200, 4}));
}
TEST_F(ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest, feat_map_wrong_rank) {
const auto priors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(2));
const auto feat_map = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(4));
const auto im_data = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
op = make_op(priors, feat_map, im_data, make_attrs(true));
input_shapes = ShapeVector{{10, 4}, {1, 2, 4, 5, 1}, {1, 2, 100, 100}};
OV_EXPECT_THROW(shape_inference(op.get(), input_shapes, output_shapes),
NodeValidationFailure,
HasSubstr("Feature_map rank must be equal to 4"));
}
TEST_F(ExperimentalDetectronPriorGridGeneratorV6StaticShapeInferenceTest, priors_2nd_dim_not_compatible) {
const auto priors = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic());
const auto feat_map = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(4));
const auto im_data = std::make_shared<op::v0::Parameter>(element::f32, PartialShape::dynamic(4));
op = make_op(priors, feat_map, im_data, make_attrs(true));
input_shapes = ShapeVector{{10, 5}, {1, 2, 4, 5}, {1, 2, 100, 100}};
OV_EXPECT_THROW(shape_inference(op.get(), input_shapes, output_shapes),
NodeValidationFailure,
HasSubstr("The last dimension of the 'priors' input must be equal to 4"));
}