From e1753bded691a45f9219247edebe4fa36c69fe86 Mon Sep 17 00:00:00 2001 From: Steve Yoo Date: Thu, 18 Apr 2024 15:05:17 +0900 Subject: [PATCH] [GPU] Reshape keeps data padding of padded input (#23880) ### Details: - *Fix to keep reshape data padding of padded input* ### Tickets: - *137553* --- .../intel_gpu/src/graph/primitive_inst.cpp | 2 +- .../unit/test_cases/reshape_gpu_test.cpp | 120 ++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/plugins/intel_gpu/src/graph/primitive_inst.cpp b/src/plugins/intel_gpu/src/graph/primitive_inst.cpp index 6dda7d9147f..73c59f82969 100644 --- a/src/plugins/intel_gpu/src/graph/primitive_inst.cpp +++ b/src/plugins/intel_gpu/src/graph/primitive_inst.cpp @@ -399,7 +399,7 @@ void primitive_inst::update_shape() { _impl_params->memory_deps = memory_deps; auto update_output_layout = [&](layout& layout, size_t idx) { - if (!_node->is_type()) { + if (!_node->is_type() || (!_node->get_input_layout(0).has_dynamic_pad() && !_node->can_be_optimized())) { auto data_padding = padding::max(_impl_params->get_output_layout(idx).data_padding, layout.data_padding); layout.data_padding = padding::max(_node->get_primitive()->get_output_padding(idx), data_padding); } diff --git a/src/plugins/intel_gpu/tests/unit/test_cases/reshape_gpu_test.cpp b/src/plugins/intel_gpu/tests/unit/test_cases/reshape_gpu_test.cpp index e28ab166787..7ccd5966c46 100644 --- a/src/plugins/intel_gpu/tests/unit/test_cases/reshape_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_cases/reshape_gpu_test.cpp @@ -1568,3 +1568,123 @@ TEST(reshape_gpu_f32, shrink_chain_full_cached) { TEST(reshape_gpu_f32, shrink_chain_out_cached) { test_shrink_chain_out(true); } + +TEST(reshape_gpu_f32, followed_by_convolution_dynamic) { + auto& engine = get_test_engine(); + + ov::Shape in0_shape = { 1, 1, 4, 5 }; + + auto in0_dyn_layout = layout{ov::PartialShape::dynamic(in0_shape.size()), data_types::f32, format::bfyx}; + auto weights = engine.allocate_memory({ data_types::f32, format::bfyx, { 1, 1, 3, 2 } }); + + set_values(weights, { + 1.0f, 2.0f, 1.0f, + 2.0f, 1.0f, 2.0f + }); + + topology topology( + input_layout("input", in0_dyn_layout), + shape_of("shape_of_input", input_info("input"), data_types::i32), + reshape("reshape", input_info("input"), input_info("shape_of_input"), false, ov::PartialShape::dynamic(4), + cldnn::reshape::reshape_mode::base, padding({0, 0, 1, 1}, {0, 0, 1, 1})), + data("weights", weights), + convolution("conv", input_info("reshape"), "weights", "", 1, { 2, 1 }, {1, 1}, {0, 0}, {0, 0}, false)); + + ExecutionConfig config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + network network(engine, topology, config); + + // first execute + { + auto input0 = engine.allocate_memory({ in0_shape, data_types::f32, format::bfyx }); + set_values(input0, { + 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, + 2.0f, 2.0f, 3.0f, 4.0f, 6.0f, + 3.0f, 3.0f, 3.0f, 5.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f + }); + network.set_input_data("input", input0); + + auto inst = network.get_primitive("conv"); + auto impl = inst->get_impl(); + ASSERT_TRUE(impl != nullptr); + ASSERT_TRUE(impl->is_dynamic()); + + auto outputs = network.execute(); + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "conv"); + + auto output_memory = outputs.at("conv").get_memory(); + auto output_layout = output_memory->get_layout(); + cldnn::mem_lock output_ptr(output_memory, get_test_stream()); + + int y_size = output_layout.spatial(1); + int x_size = output_layout.spatial(0); + int f_size = output_layout.feature(); + int b_size = output_layout.batch(); + ASSERT_EQ(output_layout.format, format::bfyx); + ASSERT_EQ(y_size, 2); + ASSERT_EQ(x_size, 3); + ASSERT_EQ(f_size, 1); + ASSERT_EQ(b_size, 1); + + VVF output_vec = { + { 20.0f, 27.0f, 38.0f }, + { 17.0f, 19.0f, 19.0f } + }; + for (int y = 0; y < y_size; ++y) { + for (int x = 0; x < x_size; ++x) { + ASSERT_EQ(output_vec[y][x], output_ptr[y * x_size + x]); + } + } + } + + // second execute + { + in0_shape = { 1, 1, 6, 4 }; + auto input0 = engine.allocate_memory({ in0_shape, data_types::f32, format::bfyx }); + set_values(input0, { + 1.0f, 2.0f, 3.0f, 4.0f, + 2.0f, 2.0f, 3.0f, 4.0f, + 3.0f, 3.0f, 3.0f, 5.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 5.0f, 4.0f, 3.0f, 2.0f, + 4.0f, 4.0f, 3.0f, 3.0f, + }); + network.set_input_data("input", input0); + + auto inst = network.get_primitive("conv"); + auto impl = inst->get_impl(); + ASSERT_TRUE(impl != nullptr); + ASSERT_TRUE(impl->is_dynamic()); + + auto outputs = network.execute(); + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "conv"); + + auto output_memory = outputs.at("conv").get_memory(); + auto output_layout = output_memory->get_layout(); + cldnn::mem_lock output_ptr(output_memory, get_test_stream()); + + int y_size = output_layout.spatial(1); + int x_size = output_layout.spatial(0); + int f_size = output_layout.feature(); + int b_size = output_layout.batch(); + ASSERT_EQ(output_layout.format, format::bfyx); + ASSERT_EQ(y_size, 3); + ASSERT_EQ(x_size, 2); + ASSERT_EQ(f_size, 1); + ASSERT_EQ(b_size, 1); + + VVF output_vec = { + { 20.f, 27.f }, + { 17.f, 19.f }, + { 34.f, 29.f } + }; + for (int y = 0; y < y_size; ++y) { + for (int x = 0; x < x_size; ++x) { + ASSERT_EQ(output_vec[y][x], output_ptr[y * x_size + x]); + } + } + } +}