#include "../node_context.h" #include "../op_table.h" #include "../utils.h" #include #include #include #include #include namespace ov { namespace frontend { namespace ggml { namespace op { OutputVector translate_add(const NodeContext & context) { num_inputs_check(context, 2, 2); if (context.get_op_case() == 1) { // MoE expert-plane sum (see is_moe_expert_sum_add): input 1 is a VIEW plane of the // shared base tensor `experts` = [n_embd, n_expert_used, n_tokens, 1] (ggml order) -> // [1, n_tokens, n_expert_used, n_embd] (OV order). The whole ADD chain is equivalent to // reducing the expert axis (OV axis 2) of that base, so bypass the chain and the // per-plane Slices entirely. size_t view_size = context.get_view_input_size(1); auto base_name = context.get_view_input_src_name(1, view_size - 1); auto base = context.get_input(base_name); auto reduced = std::make_shared( base, ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1}, {2}), false); auto res = std::make_shared(reduced, ov::op::v0::Constant::create(ov::element::i64, {1}, {1})); return rename_outputs_with_suffix({res}, context.get_name()); } auto input_0 = process_view_input_new(context, 0); auto input_1 = process_view_input_new(context, 1); auto res = std::make_shared(input_0, input_1); return rename_outputs_with_suffix({res}, context.get_name()); } } // namespace op } // namespace ggml } // namespace frontend } // namespace ov