#include "../node_context.h" #include "../op_table.h" #include "../utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ov { namespace frontend { namespace ggml { namespace op { OutputVector translate_set_rows(const NodeContext & context) { num_inputs_check(context, 3, 3); auto data = process_view_input_new(context, 0); auto indices = process_view_input_new(context, 1); auto dst = process_view_input_new(context, 2); data = std::make_shared(data, context.get_output_type()); const auto indices_shape = context.get_input_shape(1); const bool multidim_indices = indices_shape.rank().is_static() && indices_shape.rank().get_length() == 4 && ((indices_shape[1].is_static() && indices_shape[1].get_length() > 1) || (indices_shape[2].is_static() && indices_shape[2].get_length() > 1)); auto axes = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{}, {2}); Output res; if (context.is_stateful()) { int concat_axis = 1; int64_t dim2 = dst.get_partial_shape()[2].get_length(); int64_t dim3 = dst.get_partial_shape()[3].get_length(); data = std::make_shared( data, ov::op::v0::Constant::create(ov::element::i64, {4}, {(int64_t) 1, (int64_t) -1, dim2, dim3}), false); res = std::make_shared(OutputVector{dst, data}, concat_axis); } else if (multidim_indices) { auto updates_shape = std::make_shared(data, ov::element::i64); auto indices_rank3 = std::make_shared( indices, ov::op::v0::Constant::create(ov::element::i64, {1}, {0})); auto one = ov::op::v0::Constant::create(ov::element::i64, {1}, {1}); auto indices_rank4_shape = std::make_shared(OutputVector{get_dimensions(updates_shape, {0, 1, 2}), one}, 0); auto indices_rank4 = std::make_shared(indices_rank3, indices_rank4_shape, false); auto broadcasted_indices = std::make_shared(indices_rank4, updates_shape); res = std::make_shared(dst, broadcasted_indices, data, axes); } else { auto row_size = context.get_input_shape(2)[3].get_length(); auto ind_squeezed = std::make_shared( indices, ov::op::v0::Constant::create(ov::element::i64, {3}, {0, 1, 2})); auto data_reshaped = std::make_shared( data, ov::op::v0::Constant::create(ov::element::i64, {4}, {(int64_t) 1, (int64_t) 1, (int64_t) -1, (int64_t) row_size}), false); res = std::make_shared(dst, ind_squeezed, data_reshaped, axes); } auto dst_reshape = std::dynamic_pointer_cast(dst.get_node_shared_ptr()); if (!multidim_indices && dst_reshape) { // Fix the case of multiple sequences, reshape back to original shape [1, n_seq, ctx_per_seq, emb] // ctx_per_seq is not fixed due to llama-bench compatibility auto dst_shape_partial = dst_reshape->get_input_partial_shape(0); std::vector dst_shape = {dst_shape_partial[0].get_length(), dst_shape_partial[1].get_length(), dst_shape_partial[2].is_static() ? dst_shape_partial[2].get_length() : -1, dst_shape_partial[3].get_length()}; res = std::make_shared(res, ov::op::v0::Constant::create(ov::element::i64, {4}, dst_shape), false); } return rename_outputs_with_suffix({res}, context.get_name()); } } // namespace op } // namespace ggml } // namespace frontend } // namespace ov