[GPU] Added paddings processing for dynamic convolutions primitives; enabled convolution osv16 optimized shape agnostic kernel (#19001)
This commit is contained in:
1 parent
5ae9d80113
commit
e7565eda3e
24 files changed
+297
-91
No files matched your search
@@ -155,7 +155,10 @@ void prepare_padding::run(program& p) {
|
||||
continue;
|
||||
|
||||
auto conv = node.get_primitive();
|
||||
if (node.is_dynamic()) continue;
|
||||
|
||||
if (node.is_dynamic() && !node.use_explicit_padding())
|
||||
continue;
|
||||
|
||||
auto& conv_input_node = node.get_dependency(0);
|
||||
auto conv_layout = node.get_output_layout();
|
||||
|
||||
@@ -197,7 +200,8 @@ void prepare_padding::run(program& p) {
|
||||
layout filter_layout = filter_node.get_output_layout().convert_to_weights_layout(conv->grouped_weights_shape);
|
||||
|
||||
// Compute initial required paddings for primitive used as input for convolution.
|
||||
auto pad = conv->padding_begin;
|
||||
auto padding_begin = conv->padding_begin;
|
||||
auto padding_end = conv->padding_end;
|
||||
auto stride = conv->stride;
|
||||
auto dilation = conv->dilation;
|
||||
uint32_t stride_z = stride.size() >= 3 ? static_cast<uint32_t>(stride[stride.size() - 3]) : 1;
|
||||
@@ -208,23 +212,40 @@ void prepare_padding::run(program& p) {
|
||||
uint32_t dilation_y = dilation.size() >= 2 ? static_cast<uint32_t>(dilation[dilation.size() - 2]) : 1;
|
||||
uint32_t dilation_x = dilation.size() >= 1 ? static_cast<uint32_t>(dilation[dilation.size() - 1]) : 1;
|
||||
|
||||
tensor::value_type pad_z = pad.size() >= 3 ? pad[pad.size() - 3] : 0;
|
||||
tensor::value_type pad_y = pad.size() >= 2 ? pad[pad.size() - 2] : 0;
|
||||
tensor::value_type pad_x = pad.size() >= 1 ? pad[pad.size() - 1] : 0;
|
||||
tensor::value_type pad_z = padding_begin.size() >= 3 ? padding_begin[padding_begin.size() - 3] : 0;
|
||||
tensor::value_type pad_y = padding_begin.size() >= 2 ? padding_begin[padding_begin.size() - 2] : 0;
|
||||
tensor::value_type pad_x = padding_begin.size() >= 1 ? padding_begin[padding_begin.size() - 1] : 0;
|
||||
|
||||
auto input_limit_x = -pad_x + (conv_layout.spatial(0) - 1) * stride_x +
|
||||
(filter_layout.spatial(0) - 1) * dilation_x + 1;
|
||||
auto input_limit_y = -pad_y + (conv_layout.spatial(1) - 1) * stride_y +
|
||||
(filter_layout.spatial(1) - 1) * dilation_y + 1;
|
||||
auto input_limit_z = -pad_z + (conv_layout.spatial(2) - 1) * stride_z +
|
||||
(filter_layout.spatial(2) - 1) * dilation_z + 1;
|
||||
tensor::value_type padding_begin_x, padding_begin_y, padding_begin_z;
|
||||
tensor::value_type padding_end_x, padding_end_y, padding_end_z;
|
||||
|
||||
auto padding_begin_x = std::max(pad_x, 0);
|
||||
auto padding_begin_y = std::max(pad_y, 0);
|
||||
auto padding_begin_z = std::max(pad_z, 0);
|
||||
auto padding_end_x = std::max<tensor::value_type>(input_limit_x - prev_prim_output_layout.spatial(0), 0);
|
||||
auto padding_end_y = std::max<tensor::value_type>(input_limit_y - prev_prim_output_layout.spatial(1), 0);
|
||||
auto padding_end_z = std::max<tensor::value_type>(input_limit_z - prev_prim_output_layout.spatial(2), 0);
|
||||
if (node.is_dynamic() && node.use_explicit_padding()) {
|
||||
padding_begin_x = std::max(pad_x, 0);
|
||||
padding_begin_y = std::max(pad_y, 0);
|
||||
padding_begin_z = std::max(pad_z, 0);
|
||||
|
||||
pad_z = padding_end.size() >= 3 ? padding_end[padding_end.size() - 3] : 0;
|
||||
pad_y = padding_end.size() >= 2 ? padding_end[padding_end.size() - 2] : 0;
|
||||
pad_x = padding_end.size() >= 1 ? padding_end[padding_end.size() - 1] : 0;
|
||||
|
||||
padding_end_x = std::max(pad_x, 0);
|
||||
padding_end_y = std::max(pad_y, 0);
|
||||
padding_end_z = std::max(pad_z, 0);
|
||||
} else {
|
||||
auto input_limit_x = -pad_x + (conv_layout.spatial(0) - 1) * stride_x +
|
||||
(filter_layout.spatial(0) - 1) * dilation_x + 1;
|
||||
auto input_limit_y = -pad_y + (conv_layout.spatial(1) - 1) * stride_y +
|
||||
(filter_layout.spatial(1) - 1) * dilation_y + 1;
|
||||
auto input_limit_z = -pad_z + (conv_layout.spatial(2) - 1) * stride_z +
|
||||
(filter_layout.spatial(2) - 1) * dilation_z + 1;
|
||||
|
||||
padding_begin_x = std::max(pad_x, 0);
|
||||
padding_begin_y = std::max(pad_y, 0);
|
||||
padding_begin_z = std::max(pad_z, 0);
|
||||
padding_end_x = std::max<tensor::value_type>(input_limit_x - prev_prim_output_layout.spatial(0), 0);
|
||||
padding_end_y = std::max<tensor::value_type>(input_limit_y - prev_prim_output_layout.spatial(1), 0);
|
||||
padding_end_z = std::max<tensor::value_type>(input_limit_z - prev_prim_output_layout.spatial(2), 0);
|
||||
}
|
||||
|
||||
// Adjust right padding, so entire buffer size in X dimension is properly aligned.
|
||||
// TODO: NOTE: Will be reenabled with next check-in once heuristic for line-aligned algorithm will be added.
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
ov::CoordinateDiff pads_begin(primitive->padding_begin.begin(), primitive->padding_begin.end());
|
||||
ov::CoordinateDiff pads_end(primitive->padding_end.begin(), primitive->padding_end.end());
|
||||
const auto auto_pad = primitive->auto_pad;
|
||||
conv_params.has_explicit_paddings = primitive->auto_pad == ov::op::PadType::EXPLICIT;
|
||||
if (auto_pad == ov::op::PadType::SAME_UPPER || auto_pad == ov::op::PadType::SAME_LOWER) {
|
||||
pads_begin.clear();
|
||||
pads_end.clear();
|
||||
@@ -110,10 +111,15 @@ public:
|
||||
uint32_t kz = weights_layout.spatial(2);
|
||||
conv_params.filterSize = { kx, ky, kz };
|
||||
|
||||
uint32_t pad_z = std::max<std::ptrdiff_t>(pads_begin.size() >= 3 ? pads_begin[pads_begin.size() - 3] : 0, 0);
|
||||
uint32_t pad_y = std::max<std::ptrdiff_t>(pads_begin.size() >= 2 ? pads_begin[pads_begin.size() - 2] : 0, 0);
|
||||
uint32_t pad_x = std::max<std::ptrdiff_t>(pads_begin.size() >= 1 ? pads_begin[pads_begin.size() - 1] : 0, 0);
|
||||
conv_params.padding = {pad_x, pad_y, pad_z};
|
||||
uint32_t pad_begin_z = std::max<std::ptrdiff_t>(pads_begin.size() >= 3 ? pads_begin[pads_begin.size() - 3] : 0, 0);
|
||||
uint32_t pad_begin_y = std::max<std::ptrdiff_t>(pads_begin.size() >= 2 ? pads_begin[pads_begin.size() - 2] : 0, 0);
|
||||
uint32_t pad_begin_x = std::max<std::ptrdiff_t>(pads_begin.size() >= 1 ? pads_begin[pads_begin.size() - 1] : 0, 0);
|
||||
conv_params.padding_begin = {pad_begin_x, pad_begin_y, pad_begin_z};
|
||||
|
||||
uint32_t pad_end_z = std::max<std::ptrdiff_t>(pads_end.size() >= 3 ? pads_end[pads_end.size() - 3] : 0, 0);
|
||||
uint32_t pad_end_y = std::max<std::ptrdiff_t>(pads_end.size() >= 2 ? pads_end[pads_end.size() - 2] : 0, 0);
|
||||
uint32_t pad_end_x = std::max<std::ptrdiff_t>(pads_end.size() >= 1 ? pads_end[pads_end.size() - 1] : 0, 0);
|
||||
conv_params.padding_end = {pad_end_x, pad_end_y, pad_end_z};
|
||||
|
||||
uint32_t stride_z = stride.size() >= 3 ? static_cast<uint32_t>(stride[stride.size() - 3]) : 1;
|
||||
uint32_t stride_y = stride.size() >= 2 ? static_cast<uint32_t>(stride[stride.size() - 2]) : 1;
|
||||
@@ -183,7 +189,7 @@ public:
|
||||
}
|
||||
}
|
||||
conv_params.filterSize = { ky, kx, kz };
|
||||
conv_params.padding = {pad_y, pad_x, pad_z};
|
||||
conv_params.padding_begin = {pad_begin_y, pad_begin_x, pad_begin_z};
|
||||
conv_params.stride = {stride_y, stride_x, stride_z};
|
||||
conv_params.dilation = {dilation_y, dilation_x, dilation_z};
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
uint32_t pad_y = std::max<std::ptrdiff_t>(pad.size() >= 2 ? pad[pad.size() - 2] : 0, 0);
|
||||
uint32_t pad_x = std::max<std::ptrdiff_t>(pad.size() >= 1 ? pad[pad.size() - 1] : 0, 0);
|
||||
|
||||
params.padding = {pad_x, pad_y, pad_z};
|
||||
params.padding_begin = {pad_x, pad_y, pad_z};
|
||||
|
||||
uint32_t stride_z = stride.size() >= 3 ? static_cast<uint32_t>(stride[stride.size() - 3]) : 1;
|
||||
uint32_t stride_y = stride.size() >= 2 ? static_cast<uint32_t>(stride[stride.size() - 2]) : 1;
|
||||
|
||||
@@ -42,12 +42,12 @@ public:
|
||||
static std::string to_string(binary_convolution_node const& node);
|
||||
typed_primitive_inst(network& network, binary_convolution_node const& node);
|
||||
|
||||
bool need_reset_input_memory() const override {
|
||||
bool need_reset_input_memory(size_t idx = 0) const override {
|
||||
if (idx != 0)
|
||||
return false;
|
||||
|
||||
auto input_layout = _deps[0].first->_impl_params->get_output_layout(0);
|
||||
if (input_layout.data_padding) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return input_layout.data_padding ? true : false;
|
||||
}
|
||||
|
||||
bool need_reset_output_memory() const override {
|
||||
|
||||
@@ -128,12 +128,12 @@ public:
|
||||
static layout calc_output_layout(convolution_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(convolution_node const& node);
|
||||
|
||||
bool need_reset_input_memory() const override {
|
||||
bool need_reset_input_memory(size_t idx = 0) const override {
|
||||
if (idx != 0)
|
||||
return false;
|
||||
|
||||
auto input_layout = _deps[0].first->_impl_params->get_output_layout(0);
|
||||
if (input_layout.data_padding) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return input_layout.data_padding ? true : false;
|
||||
}
|
||||
|
||||
bool need_reset_output_memory() const override {
|
||||
|
||||
@@ -60,12 +60,12 @@ public:
|
||||
static layout calc_output_layout(deconvolution_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(deconvolution_node const& node);
|
||||
|
||||
bool need_reset_input_memory() const override {
|
||||
bool need_reset_input_memory(size_t idx = 0) const override {
|
||||
if (idx != 0)
|
||||
return false;
|
||||
|
||||
auto input_layout = _deps[0].first->_impl_params->get_output_layout(0);
|
||||
if (input_layout.data_padding) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return input_layout.data_padding ? true : false;
|
||||
}
|
||||
|
||||
bool need_reset_output_memory() const override {
|
||||
|
||||
@@ -388,17 +388,26 @@ protected:
|
||||
return { layout(in_layout.get<ShapeType>(), output_type, in_layout.format) };
|
||||
}
|
||||
|
||||
virtual bool need_reset_input_memory() const {
|
||||
virtual bool need_reset_input_memory(size_t) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool need_reset_output_memory() const {
|
||||
std::vector<primitive_id> users;
|
||||
std::vector<std::pair<primitive_id, size_t>> users;
|
||||
for (auto u : _node->get_users())
|
||||
users.push_back(u->id());
|
||||
users.emplace_back(u->id(), u->get_dependency_index(*_node));
|
||||
|
||||
for (const auto& u : _network.get_primitives(users)) {
|
||||
if (u->need_reset_input_memory())
|
||||
for (const auto& u : users) {
|
||||
auto user_inst = _network.get_primitive(u.first);
|
||||
// Check users of optimized_out inst, as the optimized out inst will not be able to
|
||||
// reset it's memory
|
||||
if (user_inst->can_be_optimized()) {
|
||||
if (user_inst->need_reset_output_memory())
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (user_inst->need_reset_input_memory(u.second))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -33,7 +33,10 @@ public:
|
||||
static layout calc_output_layout(reduce_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(reduce_node const& node);
|
||||
|
||||
bool need_reset_input_memory() const override {
|
||||
bool need_reset_input_memory(size_t idx = 0) const override {
|
||||
if (idx != 0)
|
||||
return false;
|
||||
|
||||
auto input_layout = _deps[0].first->_impl_params->get_output_layout(_deps[0].second);
|
||||
if (!format::format::is_simple_data_format(input_layout.format) && input_layout.feature() % 16 != 0) {
|
||||
return true;
|
||||
|
||||
@@ -1035,11 +1035,16 @@ format layout_optimizer::get_expected_format(convolution_node const& node) {
|
||||
auto output_layout = node.get_output_layout(0);
|
||||
auto weights_layout = node.weights().get_output_layout().convert_to_weights_layout(prim->grouped_weights_shape);
|
||||
auto expected_format = output_layout.format;
|
||||
bool i8_u8_input = input_layout.data_type == data_types::u8 || input_layout.data_type == data_types::i8;
|
||||
|
||||
if (prim->deformable_mode) {
|
||||
return format::adjust_to_rank(format::bfyx, output_layout.get_partial_shape().size());
|
||||
}
|
||||
|
||||
// Use planar bfyx format for dynamic convolutions with explicit padding
|
||||
if (node.is_dynamic() && output_layout.get_partial_shape().size() == 4 && node.use_explicit_padding() && !i8_u8_input)
|
||||
return format::bfyx;
|
||||
|
||||
if (input_layout.is_dynamic() || output_layout.is_dynamic()) {
|
||||
if (input_layout.get_partial_shape().size() <= 4)
|
||||
expected_format = format::b_fs_yx_fsv16;
|
||||
@@ -1052,7 +1057,6 @@ format layout_optimizer::get_expected_format(convolution_node const& node) {
|
||||
|
||||
bool onednn_valid_post_ops = get_post_ops_count(node) <= 32;
|
||||
bool use_onednn_impls = _optimization_attributes.use_onednn_impls && input_layout.data_type != data_types::f32;
|
||||
bool i8_u8_input = input_layout.data_type == data_types::u8 || input_layout.data_type == data_types::i8;
|
||||
|
||||
if (use_onednn_impls && onednn_valid_post_ops) {
|
||||
expected_format = node.get_preferred_output_fmt();
|
||||
|
||||
@@ -350,7 +350,8 @@ void primitive_inst::update_shape() {
|
||||
_impl_params->memory_deps = memory_deps;
|
||||
|
||||
auto update_output_layout = [&](layout& layout, size_t idx) {
|
||||
layout.data_padding = padding::max(_node->get_primitive()->output_paddings[idx], layout.data_padding);
|
||||
auto data_padding = padding::max(_impl_params->get_output_layout(idx).data_padding, layout.data_padding);
|
||||
layout.data_padding = padding::max(_node->get_primitive()->output_paddings[idx], data_padding);
|
||||
if (_impl_params->get_output_layout(idx) != layout) {
|
||||
GPU_DEBUG_TRACE_DETAIL << id() << ": update shape: was: " << _impl_params->get_output_layout(idx).to_short_string()
|
||||
<< " now: " << layout.to_short_string() << std::endl;
|
||||
@@ -437,7 +438,7 @@ event::ptr primitive_inst::realloc_if_needed() {
|
||||
_outputs[0]->set_reused(true);
|
||||
_outputs[0] = _network.get_engine().reinterpret_buffer(*_outputs[0], actual_layout);
|
||||
}
|
||||
if (need_reset_output_memory()) {
|
||||
if (need_reset_output_memory() && !can_be_optimized()) {
|
||||
ev = _outputs[0]->fill(_network.get_stream());
|
||||
}
|
||||
} else {
|
||||
@@ -995,6 +996,7 @@ primitive_inst::primitive_inst(network& network, program_node const& node, bool
|
||||
if (_impl) {
|
||||
_impl->set_node_params(node);
|
||||
if (_impl->is_dynamic() && !_impl->is_cpu()) {
|
||||
GPU_DEBUG_TRACE_DETAIL << id() << ": initialize impl with dynamic impl " << _impl->get_kernel_name() << std::endl;
|
||||
_dynamic_impl = _impl->clone();
|
||||
// Actual shape info layout is the following:
|
||||
// input_0 -> input_1, ..., fused_dep_0, fused_dep1, ..., output_0, output_1, ...
|
||||
|
||||
+9
-1
@@ -56,6 +56,7 @@ if (_kernel_data.leftovers)
|
||||
REQD_SUB_GROUP_SIZE(SUB_GROUP_SIZE)
|
||||
__attribute__((reqd_work_group_size(1, 1, SUB_GROUP_SIZE)))
|
||||
KERNEL(convolution_gpu_bfyx_os_iyx_osv16)(
|
||||
OPTIONAL_SHAPE_INFO_ARG
|
||||
const __global UNIT_TYPE* input,
|
||||
__global UNIT_TYPE* output,
|
||||
const __global UNIT_TYPE* weights
|
||||
@@ -237,7 +238,14 @@ KERNEL(convolution_gpu_bfyx_os_iyx_osv16)(
|
||||
for(uint r = 0; r < OUTPUT_BLOCK_HEIGHT; r++) {
|
||||
if(!(or + r >= OUTPUT_SIZE_Y))
|
||||
{
|
||||
#if (OUTPUT_SIZE_X % OUTPUT_BLOCK_WIDTH) == 0 // in this case we don't need to check if we're outside of X boundaries
|
||||
|
||||
#if !IS_DYNAMIC
|
||||
#if (OUTPUT_SIZE_X % OUTPUT_BLOCK_WIDTH) == 0
|
||||
#define CAN_SKIP_CHECK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CAN_SKIP_CHECK // in this case we don't need to check if we're outside of X boundaries
|
||||
uint out_vstore_offset = 0;
|
||||
#if (OUT_BLOCK_WIDTH % 8) > 3
|
||||
MAKE_VECTOR_TYPE(UNIT_TYPE, 4) tmp = MAKE_VECTOR_TYPE(UNIT_TYPE, 4)(
|
||||
|
||||
+9
-9
@@ -281,12 +281,12 @@ bool ConvolutionKernel_b_fs_yx_fsv_16_32_imad_dw::HasPaddedInput(const convoluti
|
||||
+ (params.filterSize.z - 1) * params.dilation.z + 1;
|
||||
|
||||
bool has_pad = true;
|
||||
has_pad &= params.padding.x <= params.inputs[0].X().pad.before;
|
||||
has_pad &= params.padding.y <= params.inputs[0].Y().pad.before;
|
||||
has_pad &= params.padding.z <= params.inputs[0].Z().pad.before;
|
||||
has_pad &= inputLimitX <= params.padding.x + params.inputs[0].X().v + params.inputs[0].X().pad.after;
|
||||
has_pad &= inputLimitY <= params.padding.y + params.inputs[0].Y().v + params.inputs[0].Y().pad.after;
|
||||
has_pad &= inputLimitZ <= params.padding.z + params.inputs[0].Z().v + params.inputs[0].Z().pad.after;
|
||||
has_pad &= params.padding_begin.x <= params.inputs[0].X().pad.before;
|
||||
has_pad &= params.padding_begin.y <= params.inputs[0].Y().pad.before;
|
||||
has_pad &= params.padding_begin.z <= params.inputs[0].Z().pad.before;
|
||||
has_pad &= inputLimitX <= params.padding_begin.x + params.inputs[0].X().v + params.inputs[0].X().pad.after;
|
||||
has_pad &= inputLimitY <= params.padding_begin.y + params.inputs[0].Y().v + params.inputs[0].Y().pad.after;
|
||||
has_pad &= inputLimitZ <= params.padding_begin.z + params.inputs[0].Z().v + params.inputs[0].Z().pad.after;
|
||||
|
||||
return has_pad;
|
||||
}
|
||||
@@ -300,9 +300,9 @@ bool ConvolutionKernel_b_fs_yx_fsv_16_32_imad_dw::ParamsHavePadding(const convol
|
||||
+ (params.filterSize.z - 1) * params.dilation.z + 1;
|
||||
|
||||
bool needs_pad = false;
|
||||
needs_pad |= params.padding.x != 0;
|
||||
needs_pad |= params.padding.y != 0;
|
||||
needs_pad |= params.padding.z != 0;
|
||||
needs_pad |= params.padding_begin.x != 0;
|
||||
needs_pad |= params.padding_begin.y != 0;
|
||||
needs_pad |= params.padding_begin.z != 0;
|
||||
needs_pad |= inputLimitX > params.inputs[0].X().v;
|
||||
needs_pad |= inputLimitY > params.inputs[0].Y().v;
|
||||
needs_pad |= inputLimitZ > params.inputs[0].Z().v;
|
||||
|
||||
+34
-11
@@ -28,7 +28,7 @@ bool ConvolutionKernelBase::Validate(const Params& p, const optional_params& o)
|
||||
JitConstants ConvolutionKernelBase::GetJitConstants(const convolution_params& params, const DispatchData& dispatchData) const {
|
||||
JitConstants mem_consts = WeightBiasKernelBase::GetJitConstants(params);
|
||||
mem_consts.Merge(GetFusedPrimitivesJitConstants(params, dispatchData));
|
||||
const auto& padding = params.padding;
|
||||
const auto& padding = params.padding_begin;
|
||||
const auto& input = params.inputs[0];
|
||||
|
||||
int64_t input_offset_with_padding =
|
||||
@@ -37,7 +37,7 @@ JitConstants ConvolutionKernelBase::GetJitConstants(const convolution_params& pa
|
||||
|
||||
mem_consts.AddConstants({
|
||||
MakeJitConstant("STRIDE", params.stride),
|
||||
MakeJitConstant("PADDING", params.padding),
|
||||
MakeJitConstant("PADDING", padding),
|
||||
MakeJitConstant("DILATION", params.dilation),
|
||||
MakeJitConstant("FILTER_ARRAY_NUM", params.groups),
|
||||
MakeJitConstant("INPUT0_OFFSET_WITH_PADDING", input_offset_with_padding),
|
||||
@@ -183,11 +183,17 @@ KernelsData ConvolutionKernelBase::GetCommonKernelsData(const Params& params,
|
||||
}
|
||||
|
||||
if (NeedPaddedInput()) {
|
||||
kd.reorderInput = ConvolutionUpdateInputParams(newParams);
|
||||
if (newParams.has_dynamic_inputs()) {
|
||||
if (!CheckConvolutionExplicitPaddings(newParams))
|
||||
return {};
|
||||
} else {
|
||||
kd.reorderInput = ConvolutionUpdateInputParams(newParams);
|
||||
|
||||
if (kd.reorderInput && !options.allowInputReordering)
|
||||
return {};
|
||||
if (kd.reorderInput && !options.allowInputReordering)
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
DispatchData dispatchData = SetDefault(newParams, autoTuneIndex);
|
||||
|
||||
if (!params.is_shape_agnostic && !CheckWorkGroups(dispatchData)) {
|
||||
@@ -264,7 +270,7 @@ bool CheckConvolutionPaddedInputDesc(const convolution_params& params, const Dat
|
||||
reqDesc.Feature().pad.after <= params.inputs[0].Feature().pad.after &&
|
||||
reqDesc.Batch().pad.after <= params.inputs[0].Batch().pad.after;
|
||||
|
||||
properPadding &= ((params.padding.x == 0 && params.padding.y == 0) || params.inputs[0].GetPaddedVal() == 0.f);
|
||||
properPadding &= ((params.padding_begin.x == 0 && params.padding_begin.y == 0) || params.inputs[0].GetPaddedVal() == 0.f);
|
||||
|
||||
return properPadding;
|
||||
}
|
||||
@@ -276,16 +282,14 @@ static DataTensor GetConvolutionBFYXPaddedTensor(const convolution_params& cp) {
|
||||
DataTensor t = cp.inputs[0];
|
||||
std::vector<Tensor::Pad> pad{{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} };
|
||||
|
||||
pad[0].before = cp.padding.x;
|
||||
pad[1].before = cp.padding.y;
|
||||
pad[2].before = cp.padding.z;
|
||||
|
||||
pad[0].before = cp.padding_begin.x;
|
||||
pad[1].before = cp.padding_begin.y;
|
||||
pad[2].before = cp.padding_begin.z;
|
||||
|
||||
const auto inputLimitX = (cp.outputs[0].X().v - 1) * cp.stride.x + (cp.filterSize.x - 1) * cp.dilation.x + 1;
|
||||
const auto inputLimitY = (cp.outputs[0].Y().v - 1) * cp.stride.y + (cp.filterSize.y - 1) * cp.dilation.y + 1;
|
||||
const auto inputLimitZ = (cp.outputs[0].Z().v - 1) * cp.stride.z + (cp.filterSize.z - 1) * cp.dilation.z + 1;
|
||||
|
||||
|
||||
pad[0].after = (size_t)std::max(static_cast<int>(inputLimitX) - static_cast<int>(t.X().v) - static_cast<int>(pad[0].before), static_cast<int>(0));
|
||||
pad[1].after = (size_t)std::max(static_cast<int>(inputLimitY) - static_cast<int>(t.Y().v) - static_cast<int>(pad[1].before), static_cast<int>(0));
|
||||
pad[2].after = (size_t)std::max(static_cast<int>(inputLimitZ) - static_cast<int>(t.Z().v) - static_cast<int>(pad[2].before), static_cast<int>(0));
|
||||
@@ -303,10 +307,29 @@ static DataTensor GetConvolutionBFYXPaddedTensor(const convolution_params& cp) {
|
||||
return {dims, t.GetDType(), t.GetLayout()};
|
||||
}
|
||||
|
||||
bool CheckConvolutionExplicitPaddings(const convolution_params& conv_params) {
|
||||
if (!conv_params.has_explicit_paddings)
|
||||
return false;
|
||||
|
||||
bool proper_padding = true;
|
||||
proper_padding &= conv_params.padding_begin.x == conv_params.inputs[0].X().pad.before &&
|
||||
conv_params.padding_begin.y == conv_params.inputs[0].Y().pad.before &&
|
||||
conv_params.padding_begin.z == conv_params.inputs[0].Z().pad.before;
|
||||
|
||||
proper_padding &= conv_params.padding_end.x == conv_params.inputs[0].X().pad.after &&
|
||||
conv_params.padding_end.y == conv_params.inputs[0].Y().pad.after &&
|
||||
conv_params.padding_end.z == conv_params.inputs[0].Z().pad.after;
|
||||
|
||||
return proper_padding;
|
||||
}
|
||||
|
||||
bool ConvolutionCheckInput(const Params& p, const optional_params& o) {
|
||||
const convolution_params& params = static_cast<const convolution_params&>(p);
|
||||
const convolution_optional_params& optParams = static_cast<const convolution_optional_params&>(o);
|
||||
|
||||
if (params.has_dynamic_inputs())
|
||||
return CheckConvolutionExplicitPaddings(params);
|
||||
|
||||
const auto req_input = GetConvolutionBFYXPaddedTensor(params);
|
||||
const bool bProperInputDesc = CheckConvolutionPaddedInputDesc(params, req_input);
|
||||
const bool bInputPadded = optParams.allowInputReordering || bProperInputDesc;
|
||||
|
||||
+1
@@ -73,6 +73,7 @@ protected:
|
||||
|
||||
bool ConvolutionCheckInput(const Params& p, const optional_params& o);
|
||||
bool CheckConvolutionPaddedInputDesc(const convolution_params& params, const DataTensor& reqDesc);
|
||||
bool CheckConvolutionExplicitPaddings(const convolution_params& conv_params);
|
||||
bool ConvolutionUpdateInputParams(convolution_params& params);
|
||||
|
||||
} // namespace kernel_selector
|
||||
+1
-1
@@ -111,7 +111,7 @@ bool convolution_kernel_bfyx_1x1_opt::Validate(const Params& p, const optional_p
|
||||
if (cp.outputs[0].Feature().v % 64 != 0)
|
||||
return false;
|
||||
|
||||
if (cp.padding.x != 0 || cp.padding.y != 0)
|
||||
if (cp.padding_begin.x != 0 || cp.padding_begin.y != 0)
|
||||
return false;
|
||||
|
||||
if (cp.inputs[0].Feature().v % 2 != 0) {
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ JitConstants ConvolutionKernel_bfyx_depthwise_weights_lwg::GetJitConstants(const
|
||||
const DispatchData& dispatchData) const {
|
||||
auto mem_consts = ConvolutionKernelBase::GetJitConstants(params, dispatchData);
|
||||
|
||||
if (params.padding.x != 0 || params.padding.y != 0)
|
||||
if (params.padding_begin.x != 0 || params.padding_begin.y != 0)
|
||||
mem_consts.AddConstant(MakeJitConstant("BOUNDARY_CHECK", 1));
|
||||
|
||||
return mem_consts;
|
||||
|
||||
+3
-2
@@ -50,6 +50,7 @@ ParamsKey ConvolutionKernel_bfyx_os_iyx_osv16::GetSupportedKey() const {
|
||||
k.EnableBatching();
|
||||
k.EnableDilation();
|
||||
k.EnableGroupedConvolution();
|
||||
k.EnableDynamicShapesSupport();
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -128,7 +129,7 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy
|
||||
// if less than 16 values is required to compute one single row of output
|
||||
// then each WI shall compute one single row to maximize reuse within SIMD subgroup (this gives very nice
|
||||
// performance results)
|
||||
} else if (cp.outputs[0].X().v + (cp.filterSize.x - 1) * cp.dilation.x < sub_group_size) {
|
||||
} else if (!p.is_shape_agnostic && cp.outputs[0].X().v + (cp.filterSize.x - 1) * cp.dilation.x < sub_group_size) {
|
||||
option.blockWidth = cp.outputs[0].X().v;
|
||||
option.blockHeight = 1;
|
||||
option.prefetch = 4;
|
||||
@@ -153,7 +154,7 @@ ConvolutionKernel_bfyx_os_iyx_osv16::AutoTuneOption ConvolutionKernel_bfyx_os_iy
|
||||
|
||||
// if this is not 1x1 batch1 case then shrink filters, other way we're memory bound and it's best to use 16x1 block
|
||||
// sizes
|
||||
if (cp.filterSize.x != 1 || cp.filterSize.y != 1 || cp.outputs[0].Batch().v != 1) {
|
||||
if (!p.is_shape_agnostic && (cp.filterSize.x != 1 || cp.filterSize.y != 1 || cp.outputs[0].Batch().v != 1)) {
|
||||
shrink_blocks_to_output_size(cp.outputs[0].X().v, cp.outputs[0].Y().v, option.blockWidth, option.blockHeight, sub_group_size);
|
||||
}
|
||||
return option;
|
||||
|
||||
+4
-4
@@ -51,8 +51,8 @@ JitConstants ConvolutionKernel_Winograd_2x3_s1_fused::GetJitConstants(const conv
|
||||
auto C4_up16 = ((uint32_t)((idepth + 15) / 16) * 16) / 4;
|
||||
|
||||
// if there's input padding then input offset should be ignored
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : params.padding.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : params.padding.y;
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : params.padding_begin.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : params.padding_begin.y;
|
||||
|
||||
jit.AddConstants({
|
||||
MakeJitConstant("H", rows),
|
||||
@@ -89,8 +89,8 @@ ConvolutionKernel_Winograd_2x3_s1_fused::Parent::DispatchData ConvolutionKernel_
|
||||
const auto cols = arg.inputs[0].X().v + input_pad_x;
|
||||
|
||||
// if there's input padding then input offset should be ignored
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : arg.padding.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : arg.padding.y;
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : arg.padding_begin.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : arg.padding_begin.y;
|
||||
|
||||
auto P = rows - 2 + 2 * inoffset_y;
|
||||
auto Q = cols - 2 + 2 * inoffset_x;
|
||||
|
||||
+4
-4
@@ -52,8 +52,8 @@ JitConstants ConvolutionKernel_Winograd_6x3_s1_fused::GetJitConstants(const conv
|
||||
auto C4_up16 = ((uint32_t)((idepth + 15) / 16) * 16) / 4;
|
||||
|
||||
// if there's input padding then input offset should be ignored
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : params.padding.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : params.padding.y;
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : params.padding_begin.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : params.padding_begin.y;
|
||||
|
||||
jit.AddConstants({
|
||||
MakeJitConstant("H", rows),
|
||||
@@ -101,8 +101,8 @@ ConvolutionKernel_Winograd_6x3_s1_fused::Parent::DispatchData ConvolutionKernel_
|
||||
const auto cols = arg.inputs[0].X().v + input_pad_x;
|
||||
|
||||
// if there's input padding then input offset should be ignored
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : arg.padding.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : arg.padding.y;
|
||||
const auto inoffset_x = (input_pad_x) ? 0 : arg.padding_begin.x;
|
||||
const auto inoffset_y = (input_pad_y) ? 0 : arg.padding_begin.y;
|
||||
|
||||
auto P = rows - 2 + 2 * inoffset_y;
|
||||
auto Q = cols - 2 + 2 * inoffset_x;
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ std::string convolution_params::to_string() const {
|
||||
s << filterSize.x << "_" << filterSize.y << "_";
|
||||
s << stride.x << "_" << stride.y << "_";
|
||||
s << dilation.x << "_" << dilation.y << "_";
|
||||
s << padding.x << "_" << padding.y << "_";
|
||||
s << padding_begin.x << "_" << padding_begin.y << "_";
|
||||
s << 1;
|
||||
|
||||
return s.str();
|
||||
@@ -33,7 +33,7 @@ std::string convolution_params::to_cache_string_v2() const {
|
||||
s << filterSize.x << "_" << filterSize.y << "_" << filterSize.z << ";";
|
||||
s << stride.x << "_" << stride.y << "_" << stride.z << ";";
|
||||
s << dilation.x << "_" << dilation.y << "_" << dilation.z << ";";
|
||||
s << padding.x << "_" << padding.y << "_" << padding.z << ";";
|
||||
s << padding_begin.x << "_" << padding_begin.y << "_" << padding_begin.z << ";";
|
||||
s << 1 << ";";
|
||||
s << groups;
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ struct convolution_params : public weight_bias_zero_point_params {
|
||||
uSize filterSize;
|
||||
uSize stride;
|
||||
uSize dilation;
|
||||
uSize padding;
|
||||
uSize padding_begin;
|
||||
uSize padding_end;
|
||||
bool transposed = false;
|
||||
QuantizationType quantization = QuantizationType::NONE;
|
||||
bool deformable_mode = false;
|
||||
@@ -29,6 +30,7 @@ struct convolution_params : public weight_bias_zero_point_params {
|
||||
uint32_t deformable_groups = 1;
|
||||
bool bilinear_interpolation_pad {false};
|
||||
bool deformable_mask_enabled {false};
|
||||
bool has_explicit_paddings {false};
|
||||
|
||||
std::string to_string() const override;
|
||||
std::string to_cache_string_v2() const override;
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ JitConstants DeformableConvolutionKernel_bfyx_interp::GetJitConstants(const conv
|
||||
jit.AddConstant(MakeJitConstant("FILTER_SIZE_X", params.kernelSize.x));
|
||||
jit.AddConstant(MakeJitConstant("FILTER_SIZE_Y", params.kernelSize.y));
|
||||
jit.AddConstants({MakeJitConstant("STRIDE", params.stride),
|
||||
MakeJitConstant("PADDING", params.padding),
|
||||
MakeJitConstant("PADDING", params.padding_begin),
|
||||
MakeJitConstant("DILATION", params.dilation)
|
||||
});
|
||||
jit.AddConstants({MakeJitConstant("DEFORMABLE_GROUPS", params.deformable_groups)});
|
||||
|
||||
@@ -21,7 +21,7 @@ TEST(eltwise_activation_fusing_test, basic_dynamic_rank4) {
|
||||
// is_valid_fusion() should work properly when conv->add->prelu case
|
||||
auto& engine = get_test_engine();
|
||||
|
||||
layout weight_layout = layout{ov::PartialShape{1, 3, 3, 3}, data_types::f32, format::bfyx};
|
||||
layout weight_layout = layout{ov::PartialShape{1, 3, 3, 3}, data_types::f16, format::bfyx};
|
||||
auto weights = engine.allocate_memory(weight_layout);
|
||||
set_values<FLOAT16>(weights, {
|
||||
1.0f, 1.0f, 1.0f,
|
||||
@@ -42,11 +42,11 @@ TEST(eltwise_activation_fusing_test, basic_dynamic_rank4) {
|
||||
set_values(input_mem, {11.0f, 11.0f, 11.0f, 11.0f,
|
||||
11.0f, 11.0f, 11.0f, 11.0f,
|
||||
11.0f, 11.0f, 11.0f, 11.0f});
|
||||
std::vector<float> ref = { 33.0625f, 55.09375f, 55.09375f, 33.0625f,
|
||||
55.09375f, 99.1875f, 429.75f, 385.75f,
|
||||
385.75f, 760.5f, 1091.0f, 716.5f,
|
||||
363.75f, 716.5f, 716.5f, 363.75f};
|
||||
|
||||
std::vector<float> ref = { 77.0f, 143.0f, 143.0f, 77.0f,
|
||||
143.0f, 275.0f, 275.0f, 143.0f,
|
||||
143.0f, 275.0f, 275.0f, 143.0f,
|
||||
77.0f, 143.0f, 143.0f, 77.0f };
|
||||
|
||||
auto const1 = engine.allocate_memory(layout{ov::PartialShape({1, 1, 1, 1}), data_types::f32, format::bfyx});
|
||||
set_values(const1, {11.0f});
|
||||
auto const2 = engine.allocate_memory(layout{ov::PartialShape({1, 1, 1, 1}), data_types::f32, format::bfyx});
|
||||
|
||||
@@ -8866,7 +8866,7 @@ public:
|
||||
void SetUp() override {
|
||||
rg.set_seed(GET_SUITE_NAME);
|
||||
}
|
||||
|
||||
|
||||
static void TearDownTestCase() {
|
||||
all_generic_params.clear();
|
||||
all_layer_params.clear();
|
||||
@@ -9954,3 +9954,129 @@ TEST(convolution_f32_fw_gpu, basic_convolution_no_bias_swap_xy) {
|
||||
}
|
||||
EXPECT_TRUE(found_define);
|
||||
}
|
||||
|
||||
struct conv_dyn_test_params {
|
||||
ov::Shape in_shape;
|
||||
ov::Shape wei_shape;
|
||||
ov::Strides stride;
|
||||
ov::Strides dilation;
|
||||
ov::CoordinateDiff pad_begin;
|
||||
ov::CoordinateDiff pad_end;
|
||||
};
|
||||
|
||||
class conv_dyn_test : public testing::TestWithParam<conv_dyn_test_params> {};
|
||||
TEST_P(conv_dyn_test, convolution_gpu_bfyx_os_iyx_osv16_no_bias) {
|
||||
auto& engine = get_test_engine();
|
||||
auto p = GetParam();
|
||||
|
||||
auto is_grouped = p.wei_shape.size() == 5;
|
||||
auto groups_num = is_grouped ? static_cast<uint32_t>(p.wei_shape[0]) : 1;
|
||||
|
||||
auto calculate_ref = [&](memory::ptr input, memory::ptr weights, ExecutionConfig config) {
|
||||
auto in_layout = input->get_layout();
|
||||
|
||||
topology topology_ref(
|
||||
input_layout("input", in_layout),
|
||||
data("weights", weights),
|
||||
convolution("conv", input_info("input"), "weights", no_bias, groups_num, p.stride, p.dilation, p.pad_begin, p.pad_end, is_grouped));
|
||||
|
||||
network network_ref(engine, topology_ref, config);
|
||||
network_ref.set_input_data("input", input);
|
||||
|
||||
auto outputs_ref = network_ref.execute();
|
||||
|
||||
return outputs_ref.at("conv").get_memory();
|
||||
};
|
||||
|
||||
auto in_layout = layout{ov::PartialShape{ov::Dimension(), ov::Dimension(p.in_shape[1]), ov::Dimension(), ov::Dimension()}, data_types::f32, format::bfyx};
|
||||
auto input = engine.allocate_memory({ p.in_shape, data_types::f32, format::bfyx });
|
||||
auto weights = engine.allocate_memory({p.wei_shape, data_types::f32, is_grouped ? format::bfzyx : format::bfyx});
|
||||
|
||||
tests::random_generator rg(GET_SUITE_NAME);
|
||||
VF<float> input_rnd = rg.generate_random_1d<float>(ov::shape_size(p.in_shape), -10, 10);
|
||||
VF<float> weights_rnd = rg.generate_random_1d<float>(ov::shape_size(p.wei_shape), -10, 10);
|
||||
|
||||
set_values(input, input_rnd);
|
||||
set_values(weights, weights_rnd);
|
||||
|
||||
topology topology(
|
||||
input_layout("input", in_layout),
|
||||
data("weights", weights),
|
||||
convolution("conv", input_info("input"), "weights", no_bias, groups_num, p.stride, p.dilation, p.pad_begin, p.pad_end, is_grouped));
|
||||
|
||||
ExecutionConfig config = get_test_default_config(engine);
|
||||
ov::intel_gpu::ImplementationDesc conv_impl = { format::bfyx, "convolution_gpu_bfyx_os_iyx_osv16", impl_types::ocl };
|
||||
config.set_property(ov::intel_gpu::force_implementations(ov::intel_gpu::ImplForcingMap{ { "conv", conv_impl } }));
|
||||
config.set_property(ov::intel_gpu::allow_new_shape_infer(true));
|
||||
config.set_property(ov::enable_profiling(true));
|
||||
|
||||
network network(engine, topology, config);
|
||||
network.set_input_data("input", input);
|
||||
|
||||
auto inst = network.get_primitive("conv");
|
||||
auto impl = inst->get_impl();
|
||||
ASSERT_TRUE(impl != nullptr);
|
||||
ASSERT_TRUE(impl->is_dynamic());
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
auto output_memory = outputs.at("conv").get_memory();
|
||||
auto output_memory_ref = calculate_ref(input, weights, config);
|
||||
|
||||
cldnn::mem_lock<float> output_ptr(output_memory, get_test_stream());
|
||||
cldnn::mem_lock<float> output_ptr_ref(output_memory_ref, get_test_stream());
|
||||
|
||||
ASSERT_EQ(outputs.at("conv").get_layout(), output_memory_ref->get_layout());
|
||||
for (size_t i = 0; i < output_ptr.size(); i++) {
|
||||
ASSERT_EQ(output_ptr[i], output_ptr_ref[i]);
|
||||
}
|
||||
|
||||
{
|
||||
// Change original shape for the second run
|
||||
auto new_shape = p.in_shape;
|
||||
new_shape[2] += 4;
|
||||
new_shape[3] += 8;
|
||||
|
||||
auto input = engine.allocate_memory({ new_shape, data_types::f32, format::bfyx });
|
||||
|
||||
VF<float> input_rnd = rg.generate_random_1d<float>(ov::shape_size(p.in_shape), -10, 10);
|
||||
set_values(input, input_rnd);
|
||||
|
||||
network.set_input_data("input", input);
|
||||
auto outputs = network.execute();
|
||||
|
||||
auto output_memory = outputs.at("conv").get_memory();
|
||||
auto output_memory_ref = calculate_ref(input, weights, config);
|
||||
|
||||
cldnn::mem_lock<float> output_ptr(output_memory, get_test_stream());
|
||||
cldnn::mem_lock<float> output_ptr_ref(output_memory_ref, get_test_stream());
|
||||
|
||||
ASSERT_EQ(outputs.at("conv").get_layout(), output_memory_ref->get_layout());
|
||||
for (size_t i = 0; i < output_ptr.size(); i++) {
|
||||
ASSERT_EQ(output_ptr[i], output_ptr_ref[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke, conv_dyn_test,
|
||||
testing::ValuesIn(std::vector<conv_dyn_test_params>{
|
||||
{ ov::Shape{1, 8, 14, 14}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 8, 32, 32}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 8, 60, 60}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 8, 64, 64}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 8, 110, 111}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 8, 110, 111}, ov::Shape{16, 8, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 8, 110, 111}, ov::Shape{16, 8, 5, 5}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{2, 640, 32, 32}, ov::Shape{640, 640, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 32, 16, 16}, ov::Shape{32, 32, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{2, 32, 16, 16}, ov::Shape{32, 32, 3, 3}, ov::Strides{2, 2}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 32, 32, 32}, ov::Shape{64, 32, 1, 1}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 4, 32, 32}, ov::Shape{32, 4, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 4, 64, 64}, ov::Shape{4, 4, 1, 1}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 32, 28, 28}, ov::Shape{32, 1, 1, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 48, 16, 16}, ov::Shape{48, 48, 4, 4}, ov::Strides{4, 4}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 16, 28, 28}, ov::Shape{32, 16, 2, 2}, ov::Strides{2, 2}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 3, 32, 32}, ov::Shape{96, 3, 4, 4}, ov::Strides{4, 4}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
{ ov::Shape{1, 768, 7, 7}, ov::Shape{768, 1, 1, 3, 3}, ov::Strides{1, 1}, ov::Strides{1, 1}, ov::CoordinateDiff{1, 1}, ov::CoordinateDiff{1, 1} },
|
||||
{ ov::Shape{1, 48, 56, 56}, ov::Shape{48, 48, 8, 8}, ov::Strides{8, 8}, ov::Strides{1, 1}, ov::CoordinateDiff{0, 0}, ov::CoordinateDiff{0, 0} },
|
||||
}));
|
||||
Reference in new issue
Block a user