From b91f9e0a039ce1e74b0153dfcdfd90d2dca76d10 Mon Sep 17 00:00:00 2001 From: Georgi Gerganov Date: Tue, 1 Sep 2026 00:43:21 +0300 Subject: [PATCH] metal : fix absolute output indices in fusion patterns ggml_can_fuse_subgraph_ext expects the outputs array to contain absolute graph node indices (it indexes cgraph->nodes[outputs[i]]), but the fusion table query was passing a relative index (n_ops - 1). As a result the last node of every pattern was not recognized as an output and was subjected to the elidable use-count check, which failed for essentially all fusions. This silently disabled the norm/MUL fusion and caused a ~5% token-generation regression. Pass the absolute graph index of the last node instead. Assisted-by: pi:llama.cpp/DeepSeek-V4-Flash-0731 --- ggml/src/ggml-metal/ggml-metal-fuse.cpp | 6 +++--- ggml/src/ggml-metal/ggml-metal-fuse.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ggml/src/ggml-metal/ggml-metal-fuse.cpp b/ggml/src/ggml-metal/ggml-metal-fuse.cpp index d4c065e49d..7ded58534a 100644 --- a/ggml/src/ggml-metal/ggml-metal-fuse.cpp +++ b/ggml/src/ggml-metal/ggml-metal-fuse.cpp @@ -7,14 +7,12 @@ // ---- helpers ------------------------------------------------------------- -// the pattern outputs, defaulting to the last node +// the pattern outputs (absolute graph node indices); the default is the last node static const int * ggml_metal_fuse_outputs(const struct ggml_metal_fuse * fuse, int * buf) { if (fuse->outputs) { return fuse->outputs; } - buf[0] = fuse->n_ops - 1; - return buf; } @@ -224,7 +222,9 @@ const struct ggml_metal_fuse * ggml_metal_fuse_next( continue; } + // ggml_can_fuse_subgraph_ext expects outputs as absolute graph node indices int outputs_buf[GGML_MAX_SRC]; + outputs_buf[0] = node_idxs[idx + fuse->n_ops - 1]; const int * outputs = ggml_metal_fuse_outputs(fuse, outputs_buf); const int n_outputs = fuse->n_outputs ? fuse->n_outputs : 1; diff --git a/ggml/src/ggml-metal/ggml-metal-fuse.h b/ggml/src/ggml-metal/ggml-metal-fuse.h index 63ab0847fd..9186926932 100644 --- a/ggml/src/ggml-metal/ggml-metal-fuse.h +++ b/ggml/src/ggml-metal/ggml-metal-fuse.h @@ -40,7 +40,7 @@ struct ggml_metal_fuse { enum ggml_metal_fuse_id id; const enum ggml_op * ops; // op sequence (fixed length) int n_ops; // number of ops - const int * outputs; // output node indices relative to the subgraph start (nullptr => { n_ops-1 }) + const int * outputs; // output node indices (absolute graph indices; nullptr => the last node) int n_outputs;// number of outputs (0 => default last node) // extra backend constraints on top of ggml_can_fuse_subgraph // nodes[j] is the j-th node of the pattern