From 094db2b3aed53c00c5e6aa23cc8dd351ab89878c Mon Sep 17 00:00:00 2001 From: Paul Youngsoo Ahn Date: Fri, 18 Nov 2022 00:11:56 +0900 Subject: [PATCH] [GPU] Fix cl kernel hang issue when x_block_size is 1 at the depthwise convolution(#14037) (#14037) --- .../convolution_gpu_bfyx_f16_depthwise.cl | 14 +++ .../tests/test_cases/convolution_gpu_test.cpp | 102 ++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/convolution_gpu_bfyx_f16_depthwise.cl b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/convolution_gpu_bfyx_f16_depthwise.cl index 7852013e5fc..d8336d938b6 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/convolution_gpu_bfyx_f16_depthwise.cl +++ b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/convolution_gpu_bfyx_f16_depthwise.cl @@ -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)) diff --git a/src/plugins/intel_gpu/tests/test_cases/convolution_gpu_test.cpp b/src/plugins/intel_gpu/tests/test_cases/convolution_gpu_test.cpp index 753958ffb2f..3d0c30e1844 100644 --- a/src/plugins/intel_gpu/tests/test_cases/convolution_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/test_cases/convolution_gpu_test.cpp @@ -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(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(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(batch_num, VVVF(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 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; + } + } +} \ No newline at end of file