[GPU] Defer updating memory of reshape after execution if it is static-shaped and its input memory is null (#22845)

### Details:
 - *Added a condition to defer reshape memory update*
- *If the reshape is static shaped and has null dep memory, its memory
update will be deferred*

### Tickets:
 - *125236*
This commit is contained in:
Steve Yoo 2024-03-12 12:04:47 +09:00 committed by GitHub
parent f8d071002b
commit 15921ea1e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 1 deletions

View File

@ -422,8 +422,13 @@ void network::set_arguments() {
// In that case some_op is static and we may want to set arguments once,
// but dynamic optimized out reshape means that output buffer of reshape is unavailable
// and attempt to set args will fail.
// (dynamic) -> static optimizable reshape -> static optimizable reshape -> some_op
// In that case, it is a limit about second reshape.
auto prim = dep.first->get_impl_params()->desc;
if (dep.first->can_be_optimized() && (dep.first->is_dynamic() || prim->type == read_value::type_id()))
if (dep.first->can_be_optimized() && (dep.first->is_dynamic() ||
dep.first->output_memory_ptr() == nullptr ||
prim->type == read_value::type_id()))
can_set_args = false;
}

View File

@ -207,6 +207,9 @@ void reshape_inst::update_output_memory() {
return;
build_deps(); // reshape need deps
if (node->get_program().get_config().get_property(ov::intel_gpu::allow_new_shape_infer) &&
input_memory_ptr() == nullptr)
return;
OPENVINO_ASSERT(input_memory_ptr() != nullptr, "[GPU] Failed to reuse input in ", id(), " primitive: input memory was not allocated");
_outputs = {_network.get_engine().reinterpret_buffer(input_memory(), _impl_params->get_output_layout())};
}

View File

@ -1043,6 +1043,56 @@ TEST(reshape_gpu_f32, basic_dynamic_shape_to_static_optimized_out) {
}
}
TEST(reshape_gpu_f32, basic_dynamic_shape_to_static_optimized_out_static_optimized_out) {
auto& engine = get_test_engine();
auto input = engine.allocate_memory(layout{ov::PartialShape{1, 2, 10}, data_types::f32, format::bfyx});
topology topology;
topology.add(input_layout("input", layout{ov::PartialShape::dynamic(3), data_types::f32, format::bfyx}));
topology.add(reshape("reshape_1", input_info("input"), false, {1, 2, 10}, {1, 2, 10}));
topology.add(reduce("reduce_1", input_info("reshape_1"), reduce_mode::max, {1}, true));
topology.add(reshape("reshape", input_info("reshape_1"), false, {2, 10}, {2, 10}));
topology.add(reduce("reduce", input_info("reshape"), reduce_mode::max, {1}, true));
// clang-format off
std::vector<float> input_data = {
0.0, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
0.0, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
};
// clang-format on
set_values(input, input_data);
ExecutionConfig config = get_test_default_config(engine);
config.set_property(ov::intel_gpu::allow_new_shape_infer(true));
config.set_property(ov::intel_gpu::optimize_data(true));
network network(engine, topology, config);
network.set_input_data("input", input);
auto outputs = network.execute();
ASSERT_TRUE(network.get_primitive("reshape")->can_be_optimized());
ASSERT_EQ(outputs.size(), size_t(2));
ASSERT_EQ(outputs.begin()->first, "reduce");
auto output = outputs.at("reduce").get_memory();
ASSERT_EQ(output->get_layout().data_type, input->get_layout().data_type);
ASSERT_EQ(output->get_layout().format, format::bfyx);
ASSERT_TRUE(output->get_layout().is_static());
ov::PartialShape expected_shape = {2, 1};
ASSERT_EQ(output->get_layout().get_partial_shape(), expected_shape);
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
std::vector<float> expected_res = {9.f, 9.f};
ASSERT_EQ(output_ptr.size(), expected_res.size());
for (size_t i = 0; i < expected_res.size(); i++) {
ASSERT_EQ(expected_res[i], output_ptr[i]);
}
}
TEST(reshape_gpu_f32, basic_runtime_dynamic_shape_activation_fusion) {
auto& engine = get_test_engine();