From 57d64d469c3feec12672a96d9220563fbee31fab Mon Sep 17 00:00:00 2001 From: Xuejun Date: Wed, 13 May 2026 14:08:38 +0800 Subject: [PATCH 1/2] OpenVINO backend: fix the view op dynamic handling issue in gemma4 & enable view + get_row --- ggml/src/ggml-openvino/ggml-openvino.cpp | 1 - .../ggml-openvino/openvino/op/get_rows.cpp | 9 +--- ggml/src/ggml-openvino/openvino/utils.cpp | 42 +++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ggml/src/ggml-openvino/ggml-openvino.cpp b/ggml/src/ggml-openvino/ggml-openvino.cpp index 5913f355c3e..56426496bf2 100644 --- a/ggml/src/ggml-openvino/ggml-openvino.cpp +++ b/ggml/src/ggml-openvino/ggml-openvino.cpp @@ -1036,7 +1036,6 @@ static bool ggml_backend_openvino_device_supports_op(ggml_backend_dev_t dev, con return false; } static std::set ops_not_support_view_input{ - GGML_OP_GET_ROWS, GGML_OP_RMS_NORM, GGML_OP_NORM, GGML_OP_L2_NORM, diff --git a/ggml/src/ggml-openvino/openvino/op/get_rows.cpp b/ggml/src/ggml-openvino/openvino/op/get_rows.cpp index 49f51b7ca3f..1d5c823689f 100644 --- a/ggml/src/ggml-openvino/openvino/op/get_rows.cpp +++ b/ggml/src/ggml-openvino/openvino/op/get_rows.cpp @@ -21,13 +21,8 @@ OutputVector translate_get_rows(const NodeContext & context) { int op_case = context.get_op_case(); Output res; - auto data = context.get_input(0); - auto indices = context.get_input(1); - - if (op_case == 2) { - // The input comes from a VIEW - indices = process_view_input(context, 1); - } + auto data = process_view_input_new(context, 0); + auto indices = process_view_input_new(context, 1); // data[1,b,x,y] ind[1,1,b,x'] test-backend-ops case // data[x,y] ind[1,1,1,x'] normal case diff --git a/ggml/src/ggml-openvino/openvino/utils.cpp b/ggml/src/ggml-openvino/openvino/utils.cpp index 45baf9aa8d9..387b73a8f2d 100644 --- a/ggml/src/ggml-openvino/openvino/utils.cpp +++ b/ggml/src/ggml-openvino/openvino/utils.cpp @@ -492,6 +492,48 @@ ov::Output process_view_input_new(const NodeContext & context, int inp view_stride.size() == view_ggml_shape.size(); const size_t relative_offset = view_offset >= view_src_offset ? view_offset - view_src_offset : 0; + if (same_rank) { + const size_t ndims = view_ggml_shape.size(); + std::vector diff_dims; + for (size_t i = 0; i < ndims; ++i) { + if (view_ggml_shape[i] != view_src_ggml_shape[i]) { + diff_dims.push_back(static_cast(i)); + } + } + + if (diff_dims.size() == 1) { + const size_t slice_dim = static_cast(diff_dims[0]); + bool suffix_stride_match = true; + for (size_t i = slice_dim + 1; i < ndims; ++i) { + if (view_stride[i] != view_src_stride[i]) { + suffix_stride_match = false; + break; + } + } + + if (suffix_stride_match && view_src_stride[slice_dim] > 0 && + relative_offset % view_src_stride[slice_dim] == 0) { + const int64_t begin_val = static_cast(relative_offset / view_src_stride[slice_dim]); + const int64_t end_val = begin_val + static_cast(view_ggml_shape[slice_dim]); + const int64_t dim_size = static_cast(view_src_ggml_shape[slice_dim]); + + if (begin_val >= 0 && end_val <= dim_size) { + auto sliced = std::make_shared( + current, + ov::op::v0::Constant::create(ov::element::i64, {1}, {begin_val}), + ov::op::v0::Constant::create(ov::element::i64, {1}, {end_val}), + ov::op::v0::Constant::create(ov::element::i64, {1}, {1}), + ov::op::v0::Constant::create( + ov::element::i64, + {1}, + {static_cast(slice_dim)})); + sliced->set_friendly_name(view_name); + return sliced; + } + } + } + } + size_t view_elems = 1; size_t src_elems = 1; if (same_rank) { From 1eb1ea34e0331ecb8d1cd797b230cf4f431be1d8 Mon Sep 17 00:00:00 2001 From: Xuejun Date: Wed, 13 May 2026 14:46:01 +0800 Subject: [PATCH 2/2] OpenVINO backend: clean code --- ggml/src/ggml-openvino/openvino/op/get_rows.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/ggml/src/ggml-openvino/openvino/op/get_rows.cpp b/ggml/src/ggml-openvino/openvino/op/get_rows.cpp index 1d5c823689f..380e70a72e0 100644 --- a/ggml/src/ggml-openvino/openvino/op/get_rows.cpp +++ b/ggml/src/ggml-openvino/openvino/op/get_rows.cpp @@ -18,8 +18,6 @@ namespace op { OutputVector translate_get_rows(const NodeContext & context) { num_inputs_check(context, 2, 2); - int op_case = context.get_op_case(); - Output res; auto data = process_view_input_new(context, 0); auto indices = process_view_input_new(context, 1);