diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/mark_shape_of_subgraphs.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/mark_shape_of_subgraphs.cpp index 9539117bcf4b18..a40c7dfebb9de6 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/mark_shape_of_subgraphs.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/mark_shape_of_subgraphs.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // +#include "broadcast_inst.h" #include "shape_of_inst.h" #include "read_value_inst.h" #include "reshape_inst.h" @@ -86,6 +87,13 @@ bool mark_shape_of_subgraphs::can_mark_node(const program_node& node) { return false; } + // skip mark_node for broadcast node if dependency nodes are data and shape_of + auto& dependencies = node.get_dependencies(); + if (node.is_type() && dependencies.size() == 2) { + if (dependencies[0].first->is_type() && dependencies[1].first->is_type()) + return false; + } + return true; } diff --git a/src/plugins/intel_gpu/tests/unit/passes/mark_shape_of_subgraphs_test.cpp b/src/plugins/intel_gpu/tests/unit/passes/mark_shape_of_subgraphs_test.cpp index 493ab79bf8e2cb..ee4382e51645cd 100644 --- a/src/plugins/intel_gpu/tests/unit/passes/mark_shape_of_subgraphs_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/passes/mark_shape_of_subgraphs_test.cpp @@ -318,3 +318,108 @@ TEST(mark_shape_of_subgraphs, gather_compressed_no_mark) { ASSERT_FALSE(check_subgraph(prog->get_node("shape_of"), prog->get_node("gather_compressed"))); ASSERT_FALSE(check_subgraph(prog->get_node("shape_of"), prog->get_node("concat"))); } + +TEST(mark_shape_of_subgraphs, broadcast_not_existed_after_shapeof) { + auto& engine = get_test_engine(); + auto input_layout_dynamic = layout{ov::PartialShape{ov::Dimension::dynamic(), 4, ov::Dimension::dynamic(), ov::Dimension::dynamic()}, + data_types::f32, format::bfyx}; + auto data_0 = engine.allocate_memory({ ov::PartialShape{4}, data_types::i32, format::bfyx }); + set_values(data_0, {1, 4, 1, 1}); + auto weights = engine.allocate_memory({ data_types::f16, format::bfyx, {1152, 4, 1, 1} }); + + topology topology; + topology.add(input_layout("input", input_layout_dynamic)); + topology.add(data("data_0", data_0)); + topology.add(data("weights", weights)); + topology.add(shape_of("shape_of", input_info("input"), data_types::i32)); + topology.add(reshape("reshape", input_info("shape_of"), input_info("data_0"), false, {})); + topology.add(convolution("convolution", input_info("reshape"), "weights", "", 1, {1, 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)); + config.set_property(ov::intel_gpu::optimize_data(true)); + network network(engine, topology, config); + + auto prog = network.get_program(); + ASSERT_NE(prog, nullptr); + + ASSERT_TRUE(check_subgraph(prog->get_node("shape_of"), prog->get_node("convolution"))); +} + +TEST(mark_shape_of_subgraphs, broadcast_w_data_and_direct_shapeof_no_mark) { + auto& engine = get_test_engine(); + auto input_layout_dynamic = layout{ov::PartialShape{ov::Dimension::dynamic(), 4, ov::Dimension::dynamic(), ov::Dimension::dynamic()}, + data_types::f32, format::bfyx}; + auto data_0 = engine.allocate_memory({ ov::PartialShape{1}, data_types::i32, format::bfyx }); + set_values(data_0, {0}); + auto weights = engine.allocate_memory({ data_types::f16, format::bfyx, {1152, 4, 2, 2} }); + + topology topology; + topology.add(input_layout("input", input_layout_dynamic)); + topology.add(data("data_0", data_0)); + topology.add(shape_of("shape_of", input_info("input"), data_types::i32)); + topology.add(broadcast("broadcast", input_info("data_0"), input_info("shape_of"), {}, ov::op::BroadcastType::BIDIRECTIONAL)); + topology.add(data("weights", weights)); + topology.add(convolution("convolution", input_info("broadcast"), "weights", "", 1, {1, 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)); + config.set_property(ov::intel_gpu::optimize_data(true)); + network network(engine, topology, config); + + auto prog = network.get_program(); + ASSERT_NE(prog, nullptr); + + ASSERT_FALSE(check_subgraph(prog->get_node("shape_of"), prog->get_node("convolution"))); + ASSERT_FALSE(check_subgraph(prog->get_node("shape_of"), prog->get_node("broadcast"))); +} + +TEST(mark_shape_of_subgraphs, broadcast_w_data_and_indirect_shapeof) { + auto& engine = get_test_engine(); + auto input_layout_dynamic = layout{ov::PartialShape{ov::Dimension::dynamic(), 4, ov::Dimension::dynamic(), ov::Dimension::dynamic()}, + data_types::f32, format::bfyx}; + auto data_0 = engine.allocate_memory({ ov::PartialShape{1}, data_types::i32, format::bfyx }); + set_values(data_0, {0}); + + topology topology; + topology.add(input_layout("input", input_layout_dynamic)); + topology.add(data("data_0", data_0)); + topology.add(shape_of("shape_of", input_info("input"), data_types::i32)); + topology.add(gather("gather", input_info("shape_of"), input_info("data_0"), 0, 0, {})); + topology.add(broadcast("broadcast", input_info("data_0"), input_info("gather"), {}, ov::op::BroadcastType::BIDIRECTIONAL)); + + 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); + + auto prog = network.get_program(); + ASSERT_NE(prog, nullptr); + + ASSERT_TRUE(check_subgraph(prog->get_node("shape_of"), prog->get_node("broadcast"))); +} + +TEST(mark_shape_of_subgraphs, broadcast_w_direct_shapeof_and_data) { + auto& engine = get_test_engine(); + auto input_layout_dynamic = layout{ov::PartialShape{ov::Dimension::dynamic(), 4, ov::Dimension::dynamic(), ov::Dimension::dynamic()}, + data_types::f32, format::bfyx}; + auto target_shape = engine.allocate_memory({ ov::PartialShape{4}, data_types::i32, format::bfyx }); + set_values(target_shape, {4, 4, 1, 1}); + + topology topology; + topology.add(input_layout("input", input_layout_dynamic)); + topology.add(data("target_shape", target_shape)); + topology.add(shape_of("shape_of", input_info("input"), data_types::i32)); + topology.add(broadcast("broadcast", input_info("shape_of"), input_info("target_shape"), {}, ov::op::BroadcastType::BIDIRECTIONAL)); + topology.add(reshape("reshape", input_info("input"), input_info("broadcast"), false, ov::PartialShape{4, 4, 1, 1})); + + 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); + + auto prog = network.get_program(); + ASSERT_NE(prog, nullptr); + + ASSERT_TRUE(check_subgraph(prog->get_node("shape_of"), prog->get_node("broadcast"))); +}