Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/plugins/intel_gpu/src/graph/include/reshape_inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct typed_program_node<reshape> : public typed_program_node_base<reshape> {
axis == 1 &&
!input_pshape[1].is_dynamic() &&
input_pshape[1].get_length() == 1 &&
prim->output_partial_shape.size() >= 2 &&
prim->output_partial_shape.size() + 1 == input_pshape.size();
if (!is_axis1_size1_squeeze)
return false;
Expand Down Expand Up @@ -134,8 +135,15 @@ struct typed_program_node<reshape> : public typed_program_node_base<reshape> {
// shape tensor (not a compile-time constant) for the Reshape second input,
// leaving output_pattern empty — requiring it would incorrectly block this
// case even though conditions 1–3 are fully sufficient.
// Only the TransposeSplitMatcher pattern is safe: crop [batch, 1, H, S] → reshape
// drops the size-1 dim → [batch, H, S]. The output must stay ≥ 2D so that the
// downstream CM/OCL kernel still has at least one inner stride to carry the offset.
// A 2D → 1D squeeze (e.g. NMS bbox-coord split [-1, 4] → [-1, 1] → [-1]) does NOT
// meet this condition and must not be optimized — its downstream arithmetic kernels
// are compiled without dynamic-padding support.
if (axis == 1 && !input_pshape[1].is_dynamic() && input_pshape[1].get_length() == 1) {
if (prim->output_partial_shape.size() + 1 == input_pshape.size()) {
if (prim->output_partial_shape.size() >= 2 &&
prim->output_partial_shape.size() + 1 == input_pshape.size()) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,8 @@ TransposeSplitMatcher::TransposeSplitMatcher() {
// This produces 3 outputs of shape [-1, 1, H, S] instead of [1, -1, H, S]
auto new_split_axis = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{}, {1});
auto new_split = std::make_shared<ov::op::v1::Split>(input_node, new_split_axis, split->get_num_splits());
ov::copy_runtime_info(m.get_matched_nodes(), new_split);
ov::replace_node(split, new_split);
ov::copy_runtime_info(m.get_matched_nodes(), new_split);
ov::replace_node(split, new_split);
return true;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,52 @@ TEST(prepare_buffer_fusing, do_runtime_in_place_crop_skips_non_propagatable_resh
ASSERT_FALSE(crop_inst->can_be_optimized());
}

TEST(prepare_buffer_fusing, in_place_crop_axis1_rank_reducing_to_1d_not_optimized) {
auto& engine = get_test_engine();

constexpr int64_t rows = 8;
const auto input_layout_dynamic = layout{ov::PartialShape{-1, 4}, data_types::f32, format::bfyx};
auto input_memory = engine.allocate_memory({{rows, 4}, data_types::f32, format::bfyx});
auto axis_memory = engine.allocate_memory({{}, data_types::i64, format::bfyx});
auto split_lengths_memory = engine.allocate_memory({{4}, data_types::i64, format::bfyx});
auto scale_memory = engine.allocate_memory({{1}, data_types::f32, format::bfyx});

set_values<float>(input_memory, std::vector<float>(rows * 4, 1.0f));
set_values<int64_t>(axis_memory, {1});
set_values<int64_t>(split_lengths_memory, {1, 1, 1, 1});
set_values<float>(scale_memory, {1.0f});

topology topology(
input_layout("input", input_layout_dynamic),
data("axis", axis_memory),
data("split_lengths", split_lengths_memory),
data("scale", scale_memory),
crop("bbox_coordinate", {input_info("input"), input_info("axis"), input_info("split_lengths")},
tensor(1),
tensor(0),
crop_ngraph_op_mode::variadic_split,
0,
1),
reshape("bbox_coordinate_1d",
input_info("bbox_coordinate"),
false,
{-1},
ov::PartialShape{-1},
reshape::reshape_mode::base),
eltwise("bbox_coordinate_scale", {input_info("bbox_coordinate_1d"), input_info("scale")}, eltwise_mode::prod),
reorder("output", input_info("bbox_coordinate_scale"), format::bfyx, data_types::f32));

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_memory);
network.execute();

ASSERT_FALSE(network.get_primitive("bbox_coordinate")->can_be_optimized());
}

TEST(prepare_buffer_fusing, in_place_crop_dynamic_reshape_unsqueeze) {
auto& engine = get_test_engine();

Expand Down
Loading