[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:
parent
f96f021920
commit
627d5e6135
@ -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) {}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user