Commit 21a19cd3b for llama.cpp
commit 21a19cd3be83099ca1b3d00f1d83cc7a40840d9f
Author: lhez <lih@qti.qualcomm.com>
Date: Tue Oct 13 23:16:54 2026 -0700
opencl: fix q8_0 dp4a mul_mat_id and mark PREC_F32 mul_mat_id unsupported for adreno (#30365)
* opencl: fix min handling for moe q8_0 dp4a GEMM
Co-authored-by: Hongqiang Wang <wangh@qti.qualcomm.com>
* opencl: reject PREC_F32 MUL_MAT_ID for adreno
---------
Co-authored-by: Hongqiang Wang <wangh@qti.qualcomm.com>
diff --git a/ggml/src/ggml-opencl/ggml-opencl.cpp b/ggml/src/ggml-opencl/ggml-opencl.cpp
index 2abc0bc58..ea7b16cb0 100644
--- a/ggml/src/ggml-opencl/ggml-opencl.cpp
+++ b/ggml/src/ggml-opencl/ggml-opencl.cpp
@@ -9318,6 +9318,12 @@ static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_te
}
return false;
case GGML_OP_MUL_MAT_ID:
+#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
+ if (ggml_get_op_params_i32(op, 3) == GGML_PREC_F32 &&
+ use_adreno_moe_kernels(backend_ctx, op->src[0])) {
+ return false;
+ }
+#endif
if (op->src[0]->type == GGML_TYPE_Q4_0 ||
op->src[0]->type == GGML_TYPE_Q8_0 ||
op->src[0]->type == GGML_TYPE_MXFP4) {
diff --git a/ggml/src/ggml-opencl/kernels/gemm_moe_q8_1_dp4a.cl b/ggml/src/ggml-opencl/kernels/gemm_moe_q8_1_dp4a.cl
index d0b191e18..0fdd8d203 100644
--- a/ggml/src/ggml-opencl/kernels/gemm_moe_q8_1_dp4a.cl
+++ b/ggml/src/ggml-opencl/kernels/gemm_moe_q8_1_dp4a.cl
@@ -100,6 +100,13 @@ inline int dp4a4(uint w0,uint w1,uint w2,uint w3,uint a0,uint a1,uint a2,uint a3
int r=0; r=dot_acc_sat_4x8packed_ss_int(w0,a0,r); r=dot_acc_sat_4x8packed_ss_int(w1,a1,r);
r=dot_acc_sat_4x8packed_ss_int(w2,a2,r); r=dot_acc_sat_4x8packed_ss_int(w3,a3,r); return r; }
+// Q8_0 and MXFP4 have no min term. Do not multiply zero by an overflowing half activation sum.
+#if MOE_QT == 80 || MOE_QT == 82
+#define MOE_MIN_TERM(t) 0.0f
+#else
+#define MOE_MIN_TERM(t) (mn*(float)sh_s[t])
+#endif
+
// One token's two-half dp4a + uniform scale/min epilogue into acc[t].
#define MOE_DP4A_T(t) do { \
uint4 a0 = vload4(0, &sh_qa[t][0]); \
@@ -107,7 +114,7 @@ inline int dp4a4(uint w0,uint w1,uint w2,uint w3,uint a0,uint a1,uint a2,uint a3
const int raw1 = dp4a4(qw[0],qw[1],qw[2],qw[3], a0.s0,a0.s1,a0.s2,a0.s3); \
const int raw2 = dp4a4(qw[4],qw[5],qw[6],qw[7], a1.s0,a1.s1,a1.s2,a1.s3); \
const float a_d = (float)sh_d[t]; \
- acc[t] += sc0*a_d*(float)raw1 + sc1*a_d*(float)raw2 - mn*(float)sh_s[t]; \
+ acc[t] += sc0*a_d*(float)raw1 + sc1*a_d*(float)raw2 - MOE_MIN_TERM(t); \
} while (0)
__attribute__((qcom_wave_pair_mode(1)))