[GPU] PriorBox dynamic shape support (#18494)

* initial commit

* add func test case

* add func test file

* add runtime update of output_size and img_size

* fix cl kernel build error

* fix functional test bug

* add func test cases

* fix compile error

* use simple value instead of tensor

* remove redundency code

* removed mutable and add comment

* fix typo

* fix cpplint error

* simplified priorbox constructor

* removed redundant include

* update vector handling for impl_param.output_size and img_size
This commit is contained in:
Wilson Seok 2023-07-24 09:59:28 +09:00 committed by GitHub
parent f96f021920
commit 627d5e6135
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 564 additions and 136 deletions

View File

@ -58,6 +58,10 @@ struct kernel_impl_params {
std::vector<std::shared_ptr<program>> inner_progs = {};
std::vector<std::shared_ptr<network>> inner_nets = {};
std::vector<std::map<size_t, primitive_id>> io_output_maps = {};
// TODO : These values are temporarily added for prior box.
// Such values decided at runtime shape infer and primitive creation will be handled with more generalized way in the near future.
std::vector<size_t> output_size;
std::vector<size_t> img_size;
kernel_impl_params() : prog(nullptr), strm(nullptr), desc(nullptr), unique_id(0) {}

View File

@ -5,6 +5,8 @@
#pragma once
#include "primitive.hpp"
#include "openvino/op/prior_box.hpp"
#include "openvino/op/prior_box_clustered.hpp"
#include <cmath>
#include <vector>
@ -23,6 +25,10 @@ struct prior_box : public primitive_base<prior_box> {
DECLARE_OBJECT_TYPE_SERIALIZATION
using PriorBoxV0Op = ov::op::v0::PriorBox;
using PriorBoxV8Op = ov::op::v8::PriorBox;
using PriorBoxClusteredOp = ov::op::v0::PriorBoxClustered;
/// @brief Constructs prior-box primitive.
/// @param id This primitive id.
/// @param input Input primitive id.
@ -33,44 +39,8 @@ struct prior_box : public primitive_base<prior_box> {
/// @param flip If true, will flip each aspect ratio. For example, if there is aspect ratio "r", aspect ratio "1.0/r" we will generated as well.
/// @param clip If true, will clip the prior so that it is within [0, 1].
/// @param variance Variance for adjusting the prior boxes.
/// @param step_width Step width.
/// @param step_height Step height.
/// @param offset Offset to the top left corner of each cell.
prior_box(const primitive_id& id,
const input_info& input,
const tensor& img_size,
const std::vector<float>& min_sizes,
const std::vector<float>& max_sizes = {},
const std::vector<float>& aspect_ratios = {},
const bool flip = true,
const bool clip = false,
const std::vector<float>& variance = {},
const float step_width = 0.f,
const float step_height = 0.f,
const float offset = 0.5f,
const bool scale_all_sizes = true,
const std::vector<float>& fixed_ratio = {},
const std::vector<float>& fixed_size = {},
const std::vector<float>& density = {},
const padding& output_padding = padding())
: primitive_base(id, {input}, {output_padding}),
img_size(img_size),
min_sizes(min_sizes),
max_sizes(max_sizes),
flip(flip),
clip(clip),
step_width(step_width),
step_height(step_height),
offset(offset),
scale_all_sizes(scale_all_sizes),
fixed_ratio(fixed_ratio),
fixed_size(fixed_size),
density(density),
clustered(false) {
init(aspect_ratios, variance);
}
/// @brief Constructs prior-box primitive, which supports v8 features.
/// @param step_width Step.
/// @param offset Offset to the top left corner of each cell.
prior_box(const primitive_id& id,
const std::vector<input_info>& inputs,
const tensor& output_size,
@ -81,28 +51,30 @@ struct prior_box : public primitive_base<prior_box> {
const bool flip = true,
const bool clip = false,
const std::vector<float>& variance = {},
const float step = 0.0f,
const float offset = 0.5f,
const bool scale_all_sizes = true,
const std::vector<float>& fixed_ratio = {},
const std::vector<float>& fixed_size = {},
const std::vector<float>& density = {},
const float step = 0.0f,
const bool min_max_aspect_ratios_order = true
const bool support_opset8 = false,
const bool min_max_aspect_ratios_order = true,
const padding& output_padding = padding()
)
: primitive_base{id, inputs},
: primitive_base{id, inputs, {output_padding}},
output_size(output_size),
img_size(img_size),
min_sizes(min_sizes),
max_sizes(max_sizes),
flip(flip),
clip(clip),
step{step},
offset(offset),
scale_all_sizes(scale_all_sizes),
fixed_ratio(fixed_ratio),
fixed_size(fixed_size),
density(density),
support_opset8{true},
step{step},
support_opset8{support_opset8},
min_max_aspect_ratios_order{min_max_aspect_ratios_order},
clustered(false) {
init(aspect_ratios, variance);
@ -110,7 +82,7 @@ struct prior_box : public primitive_base<prior_box> {
/// @brief Constructs prior-box primitive, which executes clustered version.
prior_box(const primitive_id& id,
const input_info& input,
const std::vector<input_info>& inputs,
const tensor& img_size,
const bool clip,
const std::vector<float>& variance,
@ -121,7 +93,7 @@ struct prior_box : public primitive_base<prior_box> {
const std::vector<float>& heights,
data_types output_dt,
const padding& output_padding = padding())
: primitive_base(id, {input}, {output_padding}, {optional_data_type{output_dt}}),
: primitive_base(id, inputs, {output_padding}, {optional_data_type{output_dt}}),
img_size(img_size),
flip(false),
clip(clip),
@ -135,6 +107,54 @@ struct prior_box : public primitive_base<prior_box> {
clustered(true) {
}
PriorBoxV0Op::Attributes get_attrs_v0() const {
PriorBoxV0Op::Attributes attrs;
attrs.min_size = min_sizes;
attrs.max_size = max_sizes;
attrs.aspect_ratio = aspect_ratios;
attrs.density = density;
attrs.fixed_ratio = fixed_ratio;
attrs.fixed_size = fixed_size;
attrs.clip = clip;
attrs.flip = flip;
attrs.step = step;
attrs.offset = offset;
attrs.variance = variance;
attrs.scale_all_sizes = scale_all_sizes;
return attrs;
}
PriorBoxV8Op::Attributes get_attrs_v8() const {
PriorBoxV8Op::Attributes attrs;
attrs.min_size = min_sizes;
attrs.max_size = max_sizes;
attrs.aspect_ratio = aspect_ratios;
attrs.density = density;
attrs.fixed_ratio = fixed_ratio;
attrs.fixed_size = fixed_size;
attrs.clip = clip;
attrs.flip = flip;
attrs.step = step;
attrs.offset = offset;
attrs.variance = variance;
attrs.scale_all_sizes = scale_all_sizes;
attrs.min_max_aspect_ratios_order = min_max_aspect_ratios_order;
return attrs;
}
PriorBoxClusteredOp::Attributes get_attrs_clustered() const {
PriorBoxClusteredOp::Attributes attrs;
attrs.widths = widths;
attrs.heights = heights;
attrs.clip = clip;
attrs.step_widths = step_width;
attrs.step_heights = step_height;
attrs.step = step;
attrs.offset = offset;
attrs.variances = variance;
return attrs;
}
/// @brief Spatial size of generated grid with boxes.
tensor output_size{};
/// @brief Image width and height.
@ -151,10 +171,12 @@ struct prior_box : public primitive_base<prior_box> {
bool clip{false};
/// @brief Variance for adjusting the prior boxes.
std::vector<float> variance{};
/// @brief Step width.
/// @brief Step width for clustered version.
float step_width{0.0f};
/// @brief Step height.
/// @brief Step height for clustered version.
float step_height{0.0f};
/// @brief Step.
float step{0.0f};
/// @brief Offset to the top left corner of each cell.
float offset{0.0f};
/// @brief If false, only first min_size is scaled by aspect_ratios
@ -166,7 +188,6 @@ struct prior_box : public primitive_base<prior_box> {
// required for v8
bool support_opset8{false};
float step{0.0f};
bool min_max_aspect_ratios_order{true};
/// @brief Required for clustered version.
@ -175,6 +196,7 @@ struct prior_box : public primitive_base<prior_box> {
std::vector<float> heights{};
bool is_clustered() const { return clustered; }
bool is_v8_support() const { return support_opset8;}
size_t hash() const override {
size_t seed = primitive::hash();

View File

@ -27,11 +27,17 @@ struct prior_box_impl : typed_primitive_impl_ocl<prior_box> {
const auto& primitive = impl_param.typed_desc<prior_box>();
auto params = get_default_params<kernel_selector::prior_box_params>(impl_param);
const auto width = primitive->output_size.spatial[0];
const auto height = primitive->output_size.spatial[1];
const auto image_width = primitive->img_size.spatial[0];
const auto image_height = primitive->img_size.spatial[1];
auto width = primitive->output_size.spatial[0];
auto height = primitive->output_size.spatial[1];
auto image_width = primitive->img_size.spatial[0];
auto image_height = primitive->img_size.spatial[1];
if (width == 0 || height == 0 || image_width == 0 || image_height == 0) {
width = impl_param.output_size[0];
height = impl_param.output_size[1];
image_width = impl_param.img_size[0];
image_height = impl_param.img_size[1];
}
params.min_size = primitive->min_sizes;
params.max_size = primitive->max_sizes;
params.density = primitive->density;

View File

@ -18,6 +18,7 @@ struct typed_program_node<prior_box> : typed_program_node_base<prior_box> {
typed_program_node(std::shared_ptr<prior_box> prim, program& prog);
program_node& input() const { return get_dependency(0); }
std::vector<size_t> get_shape_infer_dependencies() const override { return {0, 1}; }
bool is_clustered() const { return get_primitive()->is_clustered(); }
void calc_result();
@ -35,6 +36,8 @@ class typed_primitive_inst<prior_box> : public typed_primitive_inst_base<prior_b
using parent::parent;
public:
template<typename ShapeType>
static std::vector<layout> calc_output_layouts(prior_box_node const& /*node*/, kernel_impl_params const& impl_param);
static layout calc_output_layout(prior_box_node const& node, kernel_impl_params const& impl_param);
static std::string to_string(prior_box_node const& node);

View File

@ -13,6 +13,9 @@
#include <memory>
#include <algorithm>
#include "prior_box_clustered_shape_inference.hpp"
#include "prior_box_shape_inference.hpp"
namespace cldnn {
GPU_DEFINE_PRIMITIVE_TYPE_ID(prior_box)
@ -437,6 +440,96 @@ layout prior_box_inst::calc_output_layout(prior_box_node const& node, kernel_imp
return {output_type, impl_param.get_input_layout().format, output_shape};
}
template<typename ShapeType>
std::vector<layout> prior_box_inst::calc_output_layouts(prior_box_node const& /*node*/, kernel_impl_params const& impl_param) {
const auto primitive = impl_param.typed_desc<prior_box>();
std::vector<ShapeType> input_shapes = {
impl_param.get_input_layout(0).get<ShapeType>(),
impl_param.get_input_layout(1).get<ShapeType>()
};
std::vector<ShapeType> output_shapes = {ShapeType()};
std::map<size_t, ngraph::HostTensorPtr> const_data;
auto& memory_deps = impl_param.memory_deps;
if (memory_deps.count(0) && memory_deps.count(1)) {
auto output_size_mem = memory_deps.at(0);
auto img_size_mem = memory_deps.at(1);
cldnn::mem_lock<uint8_t, mem_lock_type::read> output_size_lock(output_size_mem, impl_param.get_stream());
cldnn::mem_lock<uint8_t, mem_lock_type::read> img_size_lock(img_size_mem, impl_param.get_stream());
const_data.emplace(0, make_host_tensor(output_size_mem->get_layout(), output_size_lock.data()));
auto p_param = const_cast<kernel_impl_params*>(&impl_param);
if (output_size_mem->get_layout().data_type == cldnn::data_types::i64) {
auto output_height = reinterpret_cast<int64_t*>(output_size_lock.data())[0];
auto output_width = reinterpret_cast<int64_t*>(output_size_lock.data())[1];
auto img_height = reinterpret_cast<int64_t*>(img_size_lock.data())[0];
auto img_width = reinterpret_cast<int64_t*>(img_size_lock.data())[1];
if (p_param->output_size.empty()) {
p_param->output_size.push_back(static_cast<size_t>(output_width));
p_param->output_size.push_back(static_cast<size_t>(output_height));
} else {
p_param->output_size[0] = static_cast<size_t>(output_width);
p_param->output_size[1] = static_cast<size_t>(output_height);
}
if (p_param->img_size.empty()) {
p_param->img_size.push_back(static_cast<size_t>(img_width));
p_param->img_size.push_back(static_cast<size_t>(img_height));
} else {
p_param->img_size[0] = static_cast<size_t>(img_width);
p_param->img_size[1] = static_cast<size_t>(img_height);
}
} else { //int32_t
auto output_height = reinterpret_cast<int32_t*>(output_size_lock.data())[0];
auto output_width = reinterpret_cast<int32_t*>(output_size_lock.data())[1];
auto img_height = reinterpret_cast<int32_t*>(img_size_lock.data())[0];
auto img_width = reinterpret_cast<int32_t*>(img_size_lock.data())[1];
if (p_param->output_size.empty()) {
p_param->output_size.push_back(static_cast<size_t>(output_width));
p_param->output_size.push_back(static_cast<size_t>(output_height));
} else {
p_param->output_size[0] = static_cast<size_t>(output_width);
p_param->output_size[1] = static_cast<size_t>(output_height);
}
if (p_param->img_size.empty()) {
p_param->img_size.push_back(static_cast<size_t>(img_width));
p_param->img_size.push_back(static_cast<size_t>(img_height));
} else {
p_param->img_size[0] = static_cast<size_t>(img_width);
p_param->img_size[1] = static_cast<size_t>(img_height);
}
}
}
if (primitive->is_clustered()) {
ov::op::v0::PriorBoxClustered op;
op.set_attrs(primitive->get_attrs_clustered());
output_shapes = ov::op::v0::shape_infer(&op, input_shapes, const_data);
} else {
if (primitive->is_v8_support()) {
ov::op::v8::PriorBox op;
op.set_attrs(primitive->get_attrs_v8());
output_shapes = ov::op::v8::shape_infer(&op, input_shapes, const_data);
} else {
ov::op::v0::PriorBox op;
op.set_attrs(primitive->get_attrs_v0());
output_shapes = ov::op::v0::shape_infer(&op, input_shapes, const_data);
}
}
const auto output_type = primitive->output_data_types[0].value_or(data_types::f32);
return {layout{output_shapes[0], output_type, impl_param.get_input_layout().format}};
}
template std::vector<layout> prior_box_inst::calc_output_layouts<ov::PartialShape>(prior_box_node const& /*node*/, kernel_impl_params const& impl_param);
std::string prior_box_inst::to_string(prior_box_node const& node) {
auto desc = node.get_primitive();
auto flip = desc->flip ? "true" : "false";

View File

@ -28,41 +28,61 @@ static void CreatePriorBoxClusteredOp(Program& p, const std::shared_ptr<ngraph::
auto input_pshape = op->get_input_partial_shape(0);
auto img_pshape = op->get_input_partial_shape(1);
auto output_pshape = op->get_output_partial_shape(0);
OPENVINO_ASSERT(input_pshape.is_static() && img_pshape.is_static(), "Dynamic shapes are not supported for PriorBoxClustered operation yet");
auto input_shape = input_pshape.to_shape();
auto img_shape = img_pshape.to_shape();
if (!output_pshape.is_dynamic()) {
auto input_shape = input_pshape.to_shape();
auto img_shape = img_pshape.to_shape();
int img_w = static_cast<int>(img_shape.back());
int img_h = static_cast<int>(img_shape.at(img_shape.size() - 2));
cldnn::tensor img_size = (cldnn::tensor) cldnn::spatial(TensorValue(img_w), TensorValue(img_h));
int img_w = static_cast<int>(img_shape.back());
int img_h = static_cast<int>(img_shape.at(img_shape.size() - 2));
cldnn::tensor img_size = (cldnn::tensor) cldnn::spatial(TensorValue(img_w), TensorValue(img_h));
auto step_w = attrs.step_widths;
auto step_h = attrs.step_heights;
if (std::abs(attrs.step_heights - attrs.step_widths) < 1e-5) {
step_w = attrs.step_widths;
step_h = attrs.step_widths;
auto step_w = attrs.step_widths;
auto step_h = attrs.step_heights;
if (std::abs(attrs.step_heights - attrs.step_widths) < 1e-5) {
step_w = attrs.step_widths;
step_h = attrs.step_widths;
}
if (step_w == 0.0f && step_h == 0.0f) {
step_w = static_cast<float>(img_w) / input_shape.back();
step_h = static_cast<float>(img_h) / input_shape.at(img_shape.size() - 2);
}
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs,
img_size,
clip,
variance,
step_w,
step_h,
offset,
width,
height,
cldnn::element_type_to_data_type(op->get_output_element_type(0)));
p.add_primitive(*op, priorBoxPrim);
} else {
auto step_w = attrs.step_widths;
auto step_h = attrs.step_heights;
cldnn::tensor img_size{};
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs,
img_size,
clip,
variance,
step_w,
step_h,
offset,
width,
height,
cldnn::element_type_to_data_type(op->get_output_element_type(0)));
p.add_primitive(*op, priorBoxPrim);
}
if (step_w == 0.0f && step_h == 0.0f) {
step_w = static_cast<float>(img_w) / input_shape.back();
step_h = static_cast<float>(img_h) / input_shape.at(img_shape.size() - 2);
}
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs[0],
img_size,
clip,
variance,
step_w,
step_h,
offset,
width,
height,
cldnn::element_type_to_data_type(op->get_output_element_type(0)));
p.add_primitive(*op, priorBoxPrim);
}
static void CreatePriorBoxOp(Program& p, const std::shared_ptr<ngraph::op::v0::PriorBox>& op) {
@ -83,37 +103,61 @@ static void CreatePriorBoxOp(Program& p, const std::shared_ptr<ngraph::op::v0::P
bool clip = attrs.clip;
bool scale_all_sizes = attrs.scale_all_sizes;
float offset = attrs.offset;
auto step = attrs.step;
auto step_w = attrs.step;
auto step_h = attrs.step;
auto output_pshape = op->get_output_partial_shape(0);
auto img_pshape = op->get_input_partial_shape(1);
OPENVINO_ASSERT(img_pshape.is_static(), "Dynamic shapes are not supported for PriorBox operation yet");
auto img_shape = img_pshape.to_shape();
if (!output_pshape.is_dynamic()) {
auto img_shape = img_pshape.to_shape();
auto wdim = img_shape.back();
auto hdim = img_shape.at(img_shape.size()-2);
auto wdim = img_shape.back();
auto hdim = img_shape.at(img_shape.size()-2);
cldnn::tensor img_size = (cldnn::tensor) cldnn::spatial(TensorValue(wdim), TensorValue(hdim));
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs[0],
img_size,
min_size,
max_size,
aspect_ratio,
flip,
clip,
variance,
step_w,
step_h,
offset,
scale_all_sizes,
fixed_ratio,
fixed_size,
density);
cldnn::tensor output_size{};
cldnn::tensor img_size = (cldnn::tensor) cldnn::spatial(TensorValue(wdim), TensorValue(hdim));
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs,
output_size,
img_size,
min_size,
max_size,
aspect_ratio,
flip,
clip,
variance,
step,
offset,
scale_all_sizes,
fixed_ratio,
fixed_size,
density);
p.add_primitive(*op, priorBoxPrim);
p.add_primitive(*op, priorBoxPrim);
} else {
cldnn::tensor output_size{};
cldnn::tensor img_size{};
auto priorBoxPrim = cldnn::prior_box(layerName,
inputs,
output_size,
img_size,
min_size,
max_size,
aspect_ratio,
flip,
clip,
variance,
step,
offset,
scale_all_sizes,
fixed_ratio,
fixed_size,
density);
p.add_primitive(*op, priorBoxPrim);
}
}
static void CreatePriorBoxOp(Program& p, const std::shared_ptr<ngraph::op::v8::PriorBox>& op) {
@ -122,41 +166,69 @@ static void CreatePriorBoxOp(Program& p, const std::shared_ptr<ngraph::op::v8::P
std::string layer_name = layer_type_name_ID(op);
const auto& attrs = op->get_attrs();
auto output_pshape = op->get_output_partial_shape(0);
const auto output_size_constant = std::dynamic_pointer_cast<ngraph::op::Constant>(op->get_input_node_shared_ptr(0));
const auto image_size_constant = std::dynamic_pointer_cast<ngraph::op::Constant>(op->get_input_node_shared_ptr(1));
OPENVINO_ASSERT(output_size_constant && image_size_constant,
"[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")");
if (!output_pshape.is_dynamic()) {
const auto output_size_constant = std::dynamic_pointer_cast<ngraph::op::Constant>(op->get_input_node_shared_ptr(0));
const auto image_size_constant = std::dynamic_pointer_cast<ngraph::op::Constant>(op->get_input_node_shared_ptr(1));
OPENVINO_ASSERT(output_size_constant && image_size_constant,
"[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")");
const auto output_size = output_size_constant->cast_vector<int64_t>();
const auto width = output_size[0];
const auto height = output_size[1];
const cldnn::tensor output_size_tensor{cldnn::spatial(width, height)};
const auto output_size = output_size_constant->cast_vector<int64_t>();
const auto width = output_size[0];
const auto height = output_size[1];
const cldnn::tensor output_size_tensor{cldnn::spatial(width, height)};
const auto image_size = image_size_constant->cast_vector<int64_t>();
const auto image_width = image_size[0];
const auto image_height = image_size[1];
const cldnn::tensor img_size_tensor{cldnn::spatial(image_width, image_height)};
const auto image_size = image_size_constant->cast_vector<int64_t>();
const auto image_width = image_size[0];
const auto image_height = image_size[1];
const cldnn::tensor img_size_tensor{cldnn::spatial(image_width, image_height)};
const cldnn::prior_box prior_box{layer_name,
inputs,
output_size_tensor,
img_size_tensor,
attrs.min_size,
attrs.max_size,
attrs.aspect_ratio,
attrs.flip,
attrs.clip,
attrs.variance,
attrs.offset,
attrs.scale_all_sizes,
attrs.fixed_ratio,
attrs.fixed_size,
attrs.density,
attrs.step,
attrs.min_max_aspect_ratios_order};
const cldnn::prior_box prior_box{layer_name,
inputs,
output_size_tensor,
img_size_tensor,
attrs.min_size,
attrs.max_size,
attrs.aspect_ratio,
attrs.flip,
attrs.clip,
attrs.variance,
attrs.step,
attrs.offset,
attrs.scale_all_sizes,
attrs.fixed_ratio,
attrs.fixed_size,
attrs.density,
true,
attrs.min_max_aspect_ratios_order};
p.add_primitive(*op, prior_box);
p.add_primitive(*op, prior_box);
} else {
cldnn::tensor output_size{};
cldnn::tensor img_size{};
const cldnn::prior_box prior_box{layer_name,
inputs,
output_size,
img_size,
attrs.min_size,
attrs.max_size,
attrs.aspect_ratio,
attrs.flip,
attrs.clip,
attrs.variance,
attrs.step,
attrs.offset,
attrs.scale_all_sizes,
attrs.fixed_ratio,
attrs.fixed_size,
attrs.density,
true,
attrs.min_max_aspect_ratios_order};
p.add_primitive(*op, prior_box);
}
}
REGISTER_FACTORY_IMPL(v0, PriorBoxClustered);

View File

@ -0,0 +1,227 @@
// Copyright (C) 2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "shared_test_classes/single_layer/shape_of.hpp"
#include "shared_test_classes/single_layer/strided_slice.hpp"
#include "shared_test_classes/single_layer/prior_box.hpp"
#include "shared_test_classes/single_layer/prior_box_clustered.hpp"
#include "shared_test_classes/base/ov_subgraph.hpp"
#include "ie_precision.hpp"
#include "ngraph_functions/builders.hpp"
#include <string>
#include <openvino/pass/constant_folding.hpp>
using namespace ngraph;
using namespace InferenceEngine;
using namespace ov::test;
using ElementType = ov::element::Type_t;
namespace GPULayerTestsDefinitions {
enum class priorbox_type {
V0,
V8,
Clustered
};
typedef std::tuple<
InputShape,
InputShape,
ElementType, // Net precision
priorbox_type
> PriorBoxLayerGPUTestParamsSet;
class PriorBoxLayerGPUTest : public testing::WithParamInterface<PriorBoxLayerGPUTestParamsSet>,
virtual public SubgraphBaseTest {
public:
static std::string getTestCaseName(testing::TestParamInfo<PriorBoxLayerGPUTestParamsSet> obj) {
InputShape input1Shape;
InputShape input2Shape;
ElementType netPrecision;
priorbox_type priorboxType;
std::tie(input1Shape, input1Shape, netPrecision, priorboxType) = obj.param;
std::ostringstream result;
switch (priorboxType) {
case priorbox_type::Clustered:
result << "PriorBoxClusteredTest_";
case priorbox_type::V0:
result << "PriorBoxV0Test_";
case priorbox_type::V8:
default:
result << "PriorBoxV8Test_";
}
result << std::to_string(obj.index) << "_";
result << "netPrec=" << netPrecision << "_";
result << "I1S=";
result << CommonTestUtils::partialShape2str({input1Shape.first}) << "_";
result << "TS=(";
for (const auto& shape : input1Shape.second) {
result << CommonTestUtils::vec2str(shape) << "_";
}
result << ")";
result << "I2S=";
result << CommonTestUtils::partialShape2str({input2Shape.first}) << "_";
result << "TS=(";
for (const auto& shape : input2Shape.second) {
result << CommonTestUtils::vec2str(shape) << "_";
}
result << ")";
return result.str();
}
protected:
void SetUp() override {
targetDevice = CommonTestUtils::DEVICE_GPU;
auto netPrecision = ElementType::undefined;
InputShape input1Shape;
InputShape input2Shape;
priorbox_type priorboxType;
std::tie(input1Shape, input2Shape, netPrecision, priorboxType) = this->GetParam();
init_input_shapes({input1Shape, input2Shape});
inType = ov::element::Type(netPrecision);
outType = ElementType::f32;
auto beginInput = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {2});
auto endInput = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {4});
auto strideInput = ngraph::opset1::Constant::create(ngraph::element::i32, ngraph::Shape{1}, {1});
auto functionParams = builder::makeDynamicParams(inType, inputDynamicShapes);
auto paramOuts = helpers::convert2OutputVector(helpers::castOps2Nodes<opset3::Parameter>(functionParams));
auto shapeOfOp1 = std::make_shared<opset3::ShapeOf>(paramOuts[0], element::i32);
auto stridedSliceOp1 = ngraph::builder::makeStridedSlice(shapeOfOp1, beginInput, endInput, strideInput, element::i32,
{0}, {1}, {0}, {0}, {0});
auto shapeOfOp2 = std::make_shared<opset3::ShapeOf>(paramOuts[1], element::i32);
auto stridedSliceOp2 = ngraph::builder::makeStridedSlice(shapeOfOp2, beginInput, endInput, strideInput, element::i32,
{0}, {1}, {0}, {0}, {0});
switch (priorboxType) {
case priorbox_type::Clustered: {
ngraph::op::v0::PriorBoxClustered::Attributes attributes_clustered;
attributes_clustered.widths = {86, 13, 57, 39, 68, 34, 142, 50, 23};
attributes_clustered.heights = {44, 10, 30, 19, 94, 32, 61, 53, 17};
attributes_clustered.variances = {0.1, 0.1, 0.2, 0.2};
attributes_clustered.step = 16;
attributes_clustered.step_widths = 0;
attributes_clustered.step_heights = 0;
attributes_clustered.offset = 0.5;
attributes_clustered.clip = false;
auto priorBoxOp = std::make_shared<ngraph::op::v0::PriorBoxClustered>(stridedSliceOp1, stridedSliceOp2, attributes_clustered);
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(priorBoxOp)};
function = std::make_shared <ngraph::Function>(results, functionParams, "PriorBoxV0Function");
break;
}
case priorbox_type::V0: {
ngraph::op::v0::PriorBox::Attributes attributes_v0;
attributes_v0.min_size = {64};
attributes_v0.max_size = {300};
attributes_v0.aspect_ratio = {2};
attributes_v0.variance = {0.1, 0.1, 0.2, 0.2};
attributes_v0.step = 16;
attributes_v0.offset = 0.5;
attributes_v0.clip = false;
attributes_v0.flip = true;
attributes_v0.scale_all_sizes = true;
auto priorBoxOp = std::make_shared<ngraph::op::v0::PriorBox>(stridedSliceOp1, stridedSliceOp2, attributes_v0);
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(priorBoxOp)};
function = std::make_shared <ngraph::Function>(results, functionParams, "PriorBoxV0Function");
break;
}
case priorbox_type::V8:
default: {
ngraph::op::v8::PriorBox::Attributes attributes_v8;
attributes_v8.min_size = {64};
attributes_v8.max_size = {300};
attributes_v8.aspect_ratio = {2};
attributes_v8.variance = {0.1, 0.1, 0.2, 0.2};
attributes_v8.step = 16;
attributes_v8.offset = 0.5;
attributes_v8.clip = false;
attributes_v8.flip = true;
attributes_v8.scale_all_sizes = true;
attributes_v8.min_max_aspect_ratios_order = true;
auto priorBoxOp = std::make_shared<ngraph::op::v8::PriorBox>(stridedSliceOp1, stridedSliceOp2, attributes_v8);
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(priorBoxOp)};
function = std::make_shared <ngraph::Function>(results, functionParams, "PriorBoxV8Function");
}
}
ngraph::op::v8::PriorBox::Attributes attributes;
attributes.min_size = {64};
attributes.max_size = {300};
attributes.aspect_ratio = {2};
attributes.variance = {0.1, 0.1, 0.2, 0.2};
attributes.step = 16;
attributes.offset = 0.5;
attributes.clip = false;
attributes.flip = true;
attributes.scale_all_sizes = true;
attributes.min_max_aspect_ratios_order = true;
auto priorBoxOp = std::make_shared<ngraph::op::v8::PriorBox>(stridedSliceOp1, stridedSliceOp2, attributes);
ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(priorBoxOp)};
function = std::make_shared <ngraph::Function>(results, functionParams, "PriorBoxFunction");
}
};
TEST_P(PriorBoxLayerGPUTest, CompareWithRefs) {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
run();
}
namespace {
const std::vector<ElementType> netPrecisions = {
ElementType::f32,
};
const std::vector<priorbox_type> mode = {
priorbox_type::V0,
priorbox_type::V8,
priorbox_type::Clustered
};
std::vector<ov::test::InputShape> inShapesDynamic = {
{
{1, 3, -1, -1},
{
{ 1, 3, 30, 30 },
{ 1, 3, 20, 20 },
{ 1, 3, 40, 40 }
}
},
};
std::vector<ov::test::InputShape> imgShapesDynamic = {
{
{1, 3, -1, -1},
{
{ 1, 3, 224, 224 },
{ 1, 3, 300, 300 },
{ 1, 3, 200, 200 }
}
},
};
INSTANTIATE_TEST_SUITE_P(smoke_prior_box_dynamic,
PriorBoxLayerGPUTest,
::testing::Combine(
::testing::ValuesIn(inShapesDynamic),
::testing::ValuesIn(imgShapesDynamic),
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(mode)),
PriorBoxLayerGPUTest::getTestCaseName);
} // namespace
} // namespace GPULayerTestsDefinitions

View File

@ -80,12 +80,13 @@ public:
attrs.flip,
attrs.clip,
attrs.variances,
attrs.step,
attrs.offset,
attrs.scale_all_sizes,
attrs.fixed_ratios,
attrs.fixed_sizes,
attrs.densities,
attrs.step,
true,
attrs.min_max_aspect_ratios_order);
topo.add(prior_box);
topo.add(reorder("prior_box", input_info("blocked_prior_box"), plain_format, output_data_type));