@@ -903,6 +903,8 @@ struct ggml_backend_opencl_context {
903903 cl_kernel kernel_gemv_moe_mxfp4_f32_ns_wimg = nullptr; // weight-as-texture MoE decode GEMV
904904 cl_kernel kernel_gemm_moe_mxfp4_q8_1_dp4a = nullptr; // dp4a (int8) mxfp4 MoE prefill GEMM
905905 cl_kernel kernel_gemm_moe_q4_0_q8_1_dp4a = nullptr; // dp4a (int8) q4_0 MoE prefill GEMM
906+ cl_kernel kernel_gemm_moe_mxfp4_q8_1_dp4a_bin = nullptr; // binary dp4a (int8) mxfp4 MoE prefill GEMM
907+ cl_kernel kernel_gemm_moe_q4_0_q8_1_dp4a_bin = nullptr; // binary dp4a (int8) q4_0 MoE prefill GEMM
906908 cl_kernel kernel_moe_reorder_b;
907909 cl_kernel kernel_moe_histogram, kernel_moe_scan, kernel_moe_fill, kernel_moe_scatter;
908910 cl_kernel kernel_moe_scatter_stable = nullptr; // deterministic slot assignment
@@ -4248,6 +4250,24 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
42484250 GGML_LOG_CONT(".");
42494251 }
42504252
4253+ // gemm_moe_mxfp4_q8_1_dp4a_bin (dp4a prefill GEMM)
4254+ if (backend_ctx->has_integer_dot) {
4255+ size_t bin_size = 0;
4256+ backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a_bin = nullptr;
4257+
4258+ if (use_adreno_bin_kernels(backend_ctx)) {
4259+ const char * kernel_bin = (const char *)backend_ctx->get_adreno_bin_kernel("gemm_moe_mxfp4_q8_1_dp4a_ila", &bin_size);
4260+ if (kernel_bin && bin_size > 0) {
4261+ cl_program prog =
4262+ build_program_from_binary(backend_ctx->context, backend_ctx->device, kernel_bin, CL_moe_compile_opts, bin_size);
4263+
4264+ CL_CHECK((backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a_bin = clCreateKernel(prog, "kernel_gemm_moe_mxfp4_q8_1_dp4a_ila", &err), err));
4265+ CL_CHECK(clReleaseProgram(prog));
4266+ GGML_LOG_CONT(".");
4267+ }
4268+ }
4269+ }
4270+
42514271 // gemm_moe_q4_0_q8_1_dp4a (dp4a prefill GEMM)
42524272 if (backend_ctx->has_integer_dot) {
42534273#ifdef GGML_OPENCL_EMBED_KERNELS
@@ -4265,6 +4285,24 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
42654285 GGML_LOG_CONT(".");
42664286 }
42674287
4288+ // gemm_moe_q4_0_q8_1_dp4a_bin (dp4a prefill GEMM)
4289+ if (backend_ctx->has_integer_dot) {
4290+ size_t bin_size = 0;
4291+ backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a_bin = nullptr;
4292+
4293+ if (use_adreno_bin_kernels(backend_ctx)) {
4294+ const char * kernel_bin = (const char *)backend_ctx->get_adreno_bin_kernel("gemm_moe_q4_0_q8_1_dp4a_ila", &bin_size);
4295+ if (kernel_bin && bin_size > 0) {
4296+ cl_program prog =
4297+ build_program_from_binary(backend_ctx->context, backend_ctx->device, kernel_bin, CL_moe_compile_opts, bin_size);
4298+
4299+ CL_CHECK((backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a_bin = clCreateKernel(prog, "kernel_gemm_moe_q4_0_q8_1_dp4a_ila", &err), err));
4300+ CL_CHECK(clReleaseProgram(prog));
4301+ GGML_LOG_CONT(".");
4302+ }
4303+ }
4304+ }
4305+
42684306 // gemm_moe_q8_1_dp4a (generic dp4a MoE GEMM; MOE_QT=80 -> q8_0 expert variant)
42694307 if (backend_ctx->has_integer_dot) {
42704308#ifdef GGML_OPENCL_EMBED_KERNELS
@@ -21519,7 +21557,9 @@ static void ggml_cl_mul_mat_id(ggml_backend_t backend, const ggml_tensor * src0,
2151921557 // dot prod has to be available
2152021558 use_moe_dp4a = backend_ctx->has_integer_dot && use_moe_dp4a;
2152121559 // bin kernel takes precedence
21522- use_moe_dp4a = use_moe_dp4a && backend_ctx->kernel_gemm_moe_q4_0_f32_ns_bin == nullptr;
21560+ if (backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a_bin == nullptr) {
21561+ use_moe_dp4a = use_moe_dp4a && backend_ctx->kernel_gemm_moe_q4_0_f32_ns_bin == nullptr;
21562+ }
2152321563
2152421564 cl_buffer_region region;
2152521565 region.origin = 0;
@@ -21625,6 +21665,10 @@ static void ggml_cl_mul_mat_id(ggml_backend_t backend, const ggml_tensor * src0,
2162521665
2162621666 // dp4a GEMM
2162721667 cl_kernel dk = backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a;
21668+ if (backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a_bin) {
21669+ dk = backend_ctx->kernel_gemm_moe_q4_0_q8_1_dp4a_bin;
21670+ }
21671+
2162821672 int aidx = 0;
2162921673 CL_CHECK(clSetKernelArg(dk, aidx++, sizeof(cl_mem), &extra0_q4_0->q_img));
2163021674 CL_CHECK(clSetKernelArg(dk, aidx++, sizeof(cl_mem), &extra0_q4_0->d));
@@ -23463,8 +23507,10 @@ static void ggml_cl_mul_mat_id(ggml_backend_t backend, const ggml_tensor * src0,
2346323507 : (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E);
2346423508 // dot prod has to be available
2346523509 use_moe_dp4a = backend_ctx->has_integer_dot && use_moe_dp4a;
23466- // bin kernel takes precedence
23467- use_moe_dp4a = use_moe_dp4a && backend_ctx->kernel_gemm_moe_mxfp4_f32_ns_bin == nullptr;
23510+ // bin kernel takes precedence, dp4a bin kernel has higher priority than normal bin kernel
23511+ if (backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a_bin == nullptr) {
23512+ use_moe_dp4a = use_moe_dp4a && backend_ctx->kernel_gemm_moe_mxfp4_f32_ns_bin == nullptr;
23513+ }
2346823514
2346923515 cl_buffer_region region;
2347023516 region.origin = 0;
@@ -23573,6 +23619,10 @@ static void ggml_cl_mul_mat_id(ggml_backend_t backend, const ggml_tensor * src0,
2357323619
2357423620 // dp4a GEMM
2357523621 cl_kernel dk = backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a;
23622+ if (backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a_bin) {
23623+ dk = backend_ctx->kernel_gemm_moe_mxfp4_q8_1_dp4a_bin;
23624+ }
23625+
2357623626 int aidx = 0;
2357723627 CL_CHECK(clSetKernelArg(dk, aidx++, sizeof(cl_mem), &extra0_mxfp4->q_img));
2357823628 CL_CHECK(clSetKernelArg(dk, aidx++, sizeof(cl_mem), &extra0_mxfp4->e));
0 commit comments