Skip to content

Commit e60ef7c

Browse files
authored
Merge pull request #154 from raufaser/pr-b-shared-perf
hip: shared perf (MMQ MoE tiles + mmvdq, prefill plumbing)
2 parents 558a6a8 + 31a7396 commit e60ef7c

17 files changed

Lines changed: 1062 additions & 47 deletions

docs/beellama-args.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ build host cannot detect it. Pre-Turing support remains runtime-unqualified
309309
until matching real devices pass the KVarN parity, memory, and model-smoke
310310
tests.
311311

312+
## CUDA/HIP dequant matvec knobs
313+
314+
| Env var | Default | Behavior |
315+
|---|---|---|
316+
| `GGML_CUDA_DQ_MMV` | Arch default (on for RDNA3.5) | `0` forces the K-quant dequant-float matvec off, `1` forces it on. Unset or anything else warns (when set) and keeps the arch default. |
317+
| `GGML_CUDA_DQ_Q6K` | Arch default (on for RDNA3.5) | Same `0`/`1`/arch-default semantics for the Q6_K dequant-float matvec arm. |
318+
| `GGML_CUDA_DQ_ROWS` | `1` | Rows per block for the dequant matvec kernels. Only `1`/`2`/`4`/`8` are instantiated; anything else warns and uses `1`. |
319+
312320
## Migration from earlier versions
313321

314322
| Earlier spelling or surface | v0.4.0 behavior | Replacement |

ggml/src/ggml-backend-meta.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,12 @@ struct ggml_backend_buffer * ggml_backend_meta_alloc_ctx_tensors_from_buft(struc
18951895

18961896
// Speculative graphs can create more than 16 transient views per source
18971897
// tensor when a target or draft uses tensor-parallel Meta placement.
1898-
constexpr size_t compute_headroom = 32;
1898+
// Views of the static tensors that are created between graph evals are stored in the compute
1899+
// containers. The number of such views is proportional to the number of tensors in the graph
1900+
// that share the buffer, which for hybrid recurrent models with n_rs_seq snapshotting can be
1901+
// much larger than 16 per static tensor (e.g. Qwen35: ~2*(n_rs_seq+1) views per recurrent
1902+
// layer are created for the conv-state snapshot copies). Size the headroom accordingly.
1903+
constexpr size_t compute_headroom = 128;
18991904
const ggml_init_params params_static = {
19001905
/*.mem_size =*/ ggml_get_mem_size(ctx),
19011906
/*.mem_buffer =*/ nullptr,

ggml/src/ggml-cuda/ggml-cuda.cu

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "ggml-cuda/mmq.cuh"
3636
#include "ggml-cuda/mmvf.cuh"
3737
#include "ggml-cuda/mmvq.cuh"
38+
#include "ggml-cuda/mmvdq.cuh"
3839
#include "ggml-cuda/moe-weighted-reduction.cuh"
3940
#include "ggml-cuda/norm.cuh"
4041
#include "ggml-cuda/opt-step-adamw.cuh"
@@ -1900,6 +1901,22 @@ static void ggml_cuda_mul_mat(ggml_backend_cuda_context & ctx, const ggml_tensor
19001901
ggml_cuda_mul_mat_f(ctx, src0, src1, nullptr, dst);
19011902
return;
19021903
}
1904+
// GGML_CUDA_DQ_Q6K (unset/invalid = arch default, 0 = off, 1 = on).
1905+
const bool dq_default = GGML_CUDA_CC_IS_RDNA3_5(cc);
1906+
if (ggml_cuda_dq_mmv_enabled(dq_default) && ne11 == 1
1907+
&& (src0->type == GGML_TYPE_Q4_K || src0->type == GGML_TYPE_Q5_K
1908+
|| (src0->type == GGML_TYPE_Q6_K && ggml_cuda_dq_q6k_enabled(dq_default)))
1909+
&& ggml_is_contiguous(src0) && ggml_is_contiguous(src1) && ggml_is_contiguous(dst)
1910+
&& ne02 == 1 && ne03 == 1 && ne12 == 1 && ne13 == 1 && src0->ne[0] % QK_K == 0) {
1911+
if (src0->type == GGML_TYPE_Q4_K) {
1912+
ggml_cuda_mul_mat_vec_dq_q4_K(ctx, src0, src1, dst);
1913+
} else if (src0->type == GGML_TYPE_Q5_K) {
1914+
ggml_cuda_mul_mat_vec_dq_q5_K(ctx, src0, src1, dst);
1915+
} else {
1916+
ggml_cuda_mul_mat_vec_dq_q6_K(ctx, src0, src1, dst);
1917+
}
1918+
return;
1919+
}
19031920
if (ggml_cuda_should_use_mmvq(src0->type, cc, ne11)) {
19041921
ggml_cuda_mul_mat_vec_q(ctx, src0, src1, nullptr, dst);
19051922
return;
@@ -4032,6 +4049,23 @@ static int ggml_cuda_try_fuse(ggml_backend_cuda_context * cuda_ctx, ggml_cgraph
40324049
}
40334050

40344051
if (ggml_cuda_should_fuse_mul_mat_vec_q(up)) {
4052+
const bool dq_default = GGML_CUDA_CC_IS_RDNA3_5(ggml_cuda_info().devices[cuda_ctx->device].cc);
4053+
if (ggml_cuda_dq_mmv_enabled(dq_default) && ids == nullptr
4054+
&& ggml_get_glu_op(glu) == GGML_GLU_OP_SWIGLU
4055+
&& (src0->type == GGML_TYPE_Q4_K || src0->type == GGML_TYPE_Q5_K
4056+
|| (src0->type == GGML_TYPE_Q6_K && ggml_cuda_dq_q6k_enabled(dq_default)))
4057+
&& gate->src[0]->type == src0->type && ggml_are_same_shape(src0, gate->src[0])
4058+
&& src1->type == GGML_TYPE_F32 && glu->type == GGML_TYPE_F32
4059+
&& src1->ne[1] == 1 && src0->ne[0] % QK_K == 0
4060+
&& ggml_is_contiguous(src0) && ggml_is_contiguous(gate->src[0])
4061+
&& ggml_is_contiguous(src1) && ggml_is_contiguous(glu)
4062+
&& src0->ne[2] == 1 && src0->ne[3] == 1 && src1->ne[2] == 1 && src1->ne[3] == 1) {
4063+
ggml_cuda_mul_mat_vec_dq_glu(*cuda_ctx, src0, gate->src[0], src1, glu);
4064+
fused_mul_mat_vec = true;
4065+
fused_node_count = 3;
4066+
break;
4067+
}
4068+
40354069
ggml_cuda_mm_fusion_args_host fusion_data{};
40364070
fusion_data.gate = gate->src[0];
40374071
fusion_data.glu_op = ggml_get_glu_op(glu);
@@ -4507,6 +4541,19 @@ static enum ggml_status ggml_backend_cuda_graph_compute(ggml_backend_t backend,
45074541
if (graph->is_enabled()) {
45084542
const bool graph_compatible = ggml_cuda_graph_check_compability(cgraph);
45094543
if (graph_compatible) {
4544+
// HIP-only: skip the graph path (incl. the update_required probe) for
4545+
// multi-token (prefill) graphs. Final-tree A/B (27B Q5_K_S, kvarn6,
4546+
// pp512, gfx1100: gate on 466.5 vs gate off 465.4-467.5) shows no
4547+
// measurable difference, so this is currently perf-neutral; the
4548+
// earlier ~6.7% dev-tree reading did not reproduce and is scheduled
4549+
// for investigation. Decode (ne[1]==1, stable shape) keeps replay.
4550+
#if defined(GGML_USE_HIP)
4551+
if (cgraph->n_nodes > 0 && cgraph->nodes[0]->ne[1] > 1) {
4552+
use_cuda_graph = false;
4553+
} else {
4554+
#else
4555+
{
4556+
#endif
45104557
const bool properties_changed = ggml_cuda_graph_update_required(cuda_ctx, cgraph);
45114558

45124559
if (!graph->warmup_complete) {
@@ -4529,6 +4576,7 @@ static enum ggml_status ggml_backend_cuda_graph_compute(ggml_backend_t backend,
45294576
cuda_graph_update_required = graph->instance == nullptr;
45304577
}
45314578
}
4579+
} // else: not prefill
45324580
}
45334581
}
45344582
#endif // USE_CUDA_GRAPH
@@ -4607,9 +4655,13 @@ static void ggml_backend_cuda_graph_optimize(ggml_backend_t backend, ggml_cgraph
46074655
GGML_UNUSED(cgraph);
46084656
#endif
46094657

4610-
static bool enable_graph_optimization = [] {
4611-
const char * env = getenv("GGML_CUDA_GRAPH_OPT");
4612-
return env != nullptr && atoi(env) == 1;
4658+
static bool enable_graph_optimization = [cuda_ctx] {
4659+
const char * env = getenv("GGML_CUDA_GRAPH_OPT");
4660+
if (env != nullptr) {
4661+
return atoi(env) == 1;
4662+
}
4663+
const int cc = ggml_cuda_info().devices[cuda_ctx->device].cc;
4664+
return GGML_CUDA_CC_IS_RDNA3_5(cc);
46134665
}();
46144666

46154667
if (!enable_graph_optimization) {

ggml/src/ggml-cuda/mmq-config-ampere.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_ampere(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
34
CASE(GGML_TYPE_Q1_0, 256, 1, 128, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
45
CASE(GGML_TYPE_Q1_0, 256, 1, 128, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
@@ -379,5 +380,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
379380
CASE(GGML_TYPE_NVFP4, 256, 1, 128, 112, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, true, false);
380381
CASE(GGML_TYPE_NVFP4, 256, 1, 128, 128, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, true, false);
381382

382-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
383+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
383384
}

ggml/src/ggml-cuda/mmq-config-blackwell.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_blackwell(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_MXFP4, 256, 1, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true);
34
CASE(GGML_TYPE_MXFP4, 256, 1, 128, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true);
45
CASE(GGML_TYPE_MXFP4, 256, 1, 128, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_FP4, MMQ_ITER_K_FP4, true, true);

ggml/src/ggml-cuda/mmq-config-cdna.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_cdna(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 512, 1, 128, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
34
CASE(GGML_TYPE_Q1_0, 512, 1, 128, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
45
CASE(GGML_TYPE_Q1_0, 512, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, true, true);
@@ -181,5 +182,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
181182
CASE(GGML_TYPE_NVFP4, 512, 1, 128, 48, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, true, false);
182183
CASE(GGML_TYPE_NVFP4, 512, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, true, false);
183184

184-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 512, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
185+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 512, 1, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
185186
}

ggml/src/ggml-cuda/mmq-config-pascal-dp4a.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_pascal_dp4a(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
34
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
45
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
@@ -269,5 +270,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
269270
CASE(GGML_TYPE_NVFP4, 256, 2, 64, 48, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
270271
CASE(GGML_TYPE_NVFP4, 256, 2, 64, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
271272

272-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
273+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
273274
}

ggml/src/ggml-cuda/mmq-config-pascal-older.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_pascal_older(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
34
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
45
CASE(GGML_TYPE_Q1_0, 256, 2, 64, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
@@ -269,5 +270,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
269270
CASE(GGML_TYPE_NVFP4, 256, 2, 64, 48, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
270271
CASE(GGML_TYPE_NVFP4, 256, 2, 64, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
271272

272-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
273+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
273274
}

ggml/src/ggml-cuda/mmq-config-rdna2.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_rdna2(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 256, 2, 128, 8, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
34
CASE(GGML_TYPE_Q1_0, 256, 2, 128, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
45
CASE(GGML_TYPE_Q1_0, 256, 2, 128, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
@@ -269,5 +270,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
269270
CASE(GGML_TYPE_NVFP4, 256, 2, 128, 48, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
270271
CASE(GGML_TYPE_NVFP4, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
271272

272-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
273+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
273274
}

ggml/src/ggml-cuda/mmq-config-rdna3-5.cuh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_config_rdna3_5(ggml_type type, int J, bool fallback) {
2+
constexpr bool use_typical_moe_ncols = false;
23
CASE(GGML_TYPE_Q1_0, 128, 2, 64, 16, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
34
CASE(GGML_TYPE_Q1_0, 128, 2, 64, 32, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
45
CASE(GGML_TYPE_Q1_0, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, MMQ_ITER_K, false, true);
@@ -286,5 +287,5 @@ static constexpr __host__ __device__ ggml_cuda_mmq_config ggml_cuda_mmq_get_conf
286287
CASE(GGML_TYPE_NVFP4, 256, 2, 128, 112, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
287288
CASE(GGML_TYPE_NVFP4, 256, 2, 128, 128, GGML_CUDA_MMQ_SRAM_LAYOUT_NVFP4, MMQ_ITER_K, false, false);
288289

289-
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, false, true);
290+
return ggml_cuda_mmq_config(GGML_TYPE_COUNT, 256, 2, 128, 64, GGML_CUDA_MMQ_SRAM_LAYOUT_Q8_0, 256, use_typical_moe_ncols, false, true);
290291
}

0 commit comments

Comments
 (0)