[GPU] Fix cl kernel hang issue when x_block_size is 1 at the depthwise convolution(#14037) (#14037)

This commit is contained in:
Paul Youngsoo Ahn authored and GitHub committed 2022-11-17 19:11:56 +04:00
1 parent 8d360ea3e6
commit 094db2b3ae
2 files changed
+116

No files matched your search

@@ -123,6 +123,7 @@ KERNEL(convolution_depthwise)(
INPUT_TYPE src_tail_20 = INPUT_BLOCK_READ(input, input_offset + (input_y + 2) * input_y_pitch + (input_x + 8) * input_x_pitch);
INPUT_TYPE src_tail_21 = INPUT_BLOCK_READ(input, input_offset + (input_y + 2) * input_y_pitch + (input_x + 9) * input_x_pitch);
#if X_BLOCK_SIZE == 8
for (uint i = 0; i < X_BLOCK_SIZE - 2; i++)
{
dst[i] = mad(src_block_0[i + 0], wei_00, dst[i]);
@@ -163,6 +164,19 @@ KERNEL(convolution_depthwise)(
dst[7] = mad(src_tail_20, wei_21, dst[7]);
dst[7] = mad(src_tail_21, wei_22, dst[7]);
}
#else // X_BLOCK_SIZE == 1
dst[0] = mad(src_block_0[0], wei_00, dst[0]);
dst[0] = mad(src_block_0[1], wei_01, dst[0]);
dst[0] = mad(src_block_0[2], wei_02, dst[0]);
dst[0] = mad(src_block_1[0], wei_10, dst[0]);
dst[0] = mad(src_block_1[1], wei_11, dst[0]);
dst[0] = mad(src_block_1[2], wei_12, dst[0]);
dst[0] = mad(src_block_2[0], wei_20, dst[0]);
dst[0] = mad(src_block_2[1], wei_21, dst[0]);
dst[0] = mad(src_block_2[2], wei_22, dst[0]);
#endif
#else // ((FILTER_SIZE_X == 3) && (FILTER_SIZE_Y == 3) && (STRIDE_SIZE_X == 1))
@@ -9192,3 +9192,105 @@ TEST(convolution_gpu_onednn, padding_for_cldnn_kernel_after_onednn) {
}
#endif // ENABLE_ONEDNN_FOR_GPU
TEST(convolution_f32_gpu, convolution_gpu_bfyx_f16_depthwise_x_bloxk_size_1)
{
auto& engine = get_test_engine();
const int batch_num = 1;
const int input_xy = 1;
const int groups = 128;
const int input_f = groups;
const int output_f = groups;
const int filter_y = 3;
const int filter_x = 3;
const uint64_t stride = 1;
const int output_padding = 1;
const int pad_y = filter_y / 2;
const int pad_x = filter_x / 2;
const int f_group_size = 16;
const int f_group_num_in_batch = (output_f % f_group_size) ? (output_f / f_group_size + 1) : (output_f / f_group_size);
const int output_y = 1 + (input_xy + 2 * pad_y - filter_y) / stride + 2 * output_padding;
const int output_x = 1 + (input_xy + 2 * pad_x - filter_x) / stride + 2 * output_padding;
auto input_size = tensor(batch_num, input_f, input_xy, input_xy);
auto input_data = generate_random_4d<FLOAT16>(batch_num, input_f, input_xy, input_xy, -1, 1);
auto input_data_bfyx = flatten_4d(format::bfyx, input_data);
auto input_mem = engine.allocate_memory({ data_types::f16, format::bfyx, input_size });
set_values(input_mem, input_data_bfyx);
auto weights_size = tensor(group(output_f), batch(1), feature(1), spatial(filter_x, filter_y));
auto weights_data = generate_random_4d<FLOAT16>(output_f, 1, filter_y, filter_x, -1, 1);
auto weights_data_bfyx = flatten_4d(format::bfyx, weights_data);
auto weights_mem = engine.allocate_memory({ data_types::f16, format::goiyx, weights_size });
set_values(weights_mem, weights_data_bfyx);
// Will be used to store reference values calculated in branches depending on bias
auto reference_result = VVVVF<FLOAT16>(batch_num, VVVF<FLOAT16>(output_f));
topology topology(
input_layout("input", input_mem->get_layout()),
data("weights_fsv", weights_mem));
// Reorder input to b_fs_yx_fsv16
topology.add(reorder("input_fsv", "input", { data_types::f16, format::b_fs_yx_fsv16, input_size }));
// Calculate reference values without bias
for (auto bi = 0; bi < batch_num; ++bi)
{
for (auto ofi = 0; ofi < output_f; ++ofi)
{
reference_result[bi][ofi] = reference_convolve(
input_data[bi], weights_data[ofi], // input, weights
stride, stride, // strides
0, // bias
1, 1, // dilation
pad_y, pad_x, // input padding
output_padding, output_padding, // output_padding
ofi, ofi + 1, // f_begin, f_end
true); // depthwise
}
}
auto conv_fsv = convolution("conv_fsv", "input_fsv", { "weights_fsv" }, groups,
{ stride, stride }, { pad_y, pad_x });
conv_fsv.output_padding = padding({ 0, 0, output_padding, output_padding }, 0.f);
topology.add(conv_fsv);
build_options options;
options.set_option(build_option::optimize_data(true));
implementation_desc conv_impl = { format::b_fs_yx_fsv16, "convolution_gpu_bfyx_f16_depthwise" };
options.set_option(build_option::force_implementations({ { "conv_fsv", conv_impl } }));
network network(engine, topology, options);
network.set_input_data("input", input_mem);
network.execute();
auto out_mem = network.get_output("conv_fsv").get_memory();
cldnn::mem_lock<FLOAT16> out_ptr(out_mem, get_test_stream());
ASSERT_EQ(out_mem->get_layout().format, format::b_fs_yx_fsv16);
for (int bi = 0; bi < batch_num; ++bi)
for (int fi = 0; fi < output_f; ++fi)
for (int yi = 0; yi < output_y; ++yi)
for (int xi = 0; xi < output_x; ++xi)
{
auto val_ref = reference_result[bi][fi][yi][xi];
auto val = out_ptr[bi * f_group_num_in_batch * f_group_size * output_y * output_x +
(fi / f_group_size) * output_y * output_x * f_group_size +
yi * output_x * f_group_size +
xi * f_group_size +
fi % f_group_size];
auto equal = are_equal(val_ref, val, 1e-2f);
EXPECT_TRUE(equal);
if (!equal)
{
std::cout << "At b = " << bi << ", fi = " << fi << ", yi = " << yi << ", xi = " << xi << std::endl;
}
}
}