Commit 098ce526b for llama.cpp
commit 098ce526b546b5a190327c1da82929cee051b9ac
Author: Georgi Gerganov <ggerganov@gmail.com>
Date: Mon Oct 19 11:55:02 2026 +0300
metal : fix moe_reduce fusion race when dst aliases its inputs (#30795)
The fused moe_reduce kernel computes dst = sum(experts[e] * weights[e]) in a
single dispatch, reading experts and weights while writing dst. The graph
allocator computes tensor liveness on the unfused graph, where the inputs are
fully consumed by earlier nodes of the fused group, so it can legally recycle
the input memory as dst. In the fused kernel this becomes a
threadgroup-vs-threadgroup race that produces rare non-deterministic wrong
results (observed with test-llama-archs -a kolibri on the meta backend).
Reject the fusion when dst overlaps either input, same guard as the
mul_mat_add fusion. The unfused MUL + ADD path is always correct.
Assisted-by: pi:llama.cpp/ggml-org/GLM-5.3-Flash-GGUF (2x DGX Spark (RDMA, TP=2))
diff --git a/ggml/src/ggml-metal/ggml-metal-fusion.cpp b/ggml/src/ggml-metal/ggml-metal-fusion.cpp
index d78ca7c4b..020cad29d 100644
--- a/ggml/src/ggml-metal/ggml-metal-fusion.cpp
+++ b/ggml/src/ggml-metal/ggml-metal-fusion.cpp
@@ -636,6 +636,11 @@ static bool ggml_metal_fusion_check_moe_reduce(
if (!match.experts->data || !match.weights->data || !match.dst->data) {
return false;
}
+
+ // the fused kernel reads experts and weights while writing dst, so dst must not overlap either input
+ if (ggml_metal_fusion_overlap(match.dst, match.experts) || ggml_metal_fusion_overlap(match.dst, match.weights)) {
+ return false;
+ }
}
return true;