Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ggml/src/ggml-cuda/ggml-cuda.cu
Original file line number Diff line number Diff line change
Expand Up @@ -7481,8 +7481,16 @@ static ggml_backend_feature * ggml_backend_cuda_get_features(ggml_backend_reg_t
GGML_UNUSED(reg);
}

// enable the BF16 WMMA matmul path (mmb); the llama layer calls this per model, by architecture
static void ggml_backend_cuda_set_mmb_enabled(bool enable) {
ggml_cuda_mmb_set_opt_in(enable);
}

static void * ggml_backend_cuda_reg_get_proc_address(ggml_backend_reg_t reg, const char * name) {
GGML_UNUSED(reg);
if (strcmp(name, "ggml_backend_cuda_set_mmb_enabled") == 0) {
return (void *)ggml_backend_cuda_set_mmb_enabled;
}
if (strcmp(name, "ggml_backend_comm_init") == 0) {
return (void *)ggml_backend_cuda_comm_init;
}
Expand Down
18 changes: 17 additions & 1 deletion ggml/src/ggml-cuda/mmb.cu
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "mmb.cuh"

#include <atomic>
#include "unary.cuh"
#include <unordered_map>
#include <map>
Expand Down Expand Up @@ -679,8 +681,17 @@ static const uint16_t * mmb_shadow_lookup(const ggml_tensor * w) {
auto it = g_mmb_shadow.find(w->data); return it == g_mmb_shadow.end() ? nullptr : it->second;
}

// the BF16 WMMA kernels are RDNA3.5 (gfx1151) work: other devices keep the MMQ/MMVQ paths
// The BF16 WMMA kernels are RDNA3.5 (gfx1151) work, and their tiles and fusions are tuned for the
// qwen4exp shapes. On other architectures they take MUL_MATs away from MMQ and lose: dense qwen35
// prefill measured 3.4-3.6x slower on gfx1151 at every ubatch from 512 to 16384, and MoE 1.1-1.2x.
// So the llama layer opts a model in by arch (ggml_backend_cuda_set_mmb_enabled); default is off.
// A process that loads several models shares this flag: the last load wins.
static std::atomic<bool> g_mmb_opt_in{false};

bool mmb_enabled() {
if (!g_mmb_opt_in.load(std::memory_order_relaxed)) {
return false;
}
const int id = ggml_cuda_get_device();
return GGML_CUDA_CC_IS_RDNA3_5(ggml_cuda_info().devices[id].cc);
}
Expand All @@ -697,6 +708,11 @@ bool mmb_glu() { return true; }

} // namespace

// opted in per model by the llama layer, by architecture (see the note on mmb_enabled above)
void ggml_cuda_mmb_set_opt_in(bool enable) {
g_mmb_opt_in.store(enable, std::memory_order_relaxed);
}

const uint16_t * ggml_cuda_mmb_cache_lookup(const ggml_tensor * t) {
const ggml_tensor * root = mmb_root(t);
for (auto & e : g_mmb_slots) if (e.buf && e.root == root && e.data == t->data) return e.buf->get();
Expand Down
2 changes: 2 additions & 0 deletions ggml/src/ggml-cuda/mmb.cuh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include "common.cuh"
// Quantized-weight BF16 WMMA GEMM on gfx1151, from 512 tokens up.
// opted in per model by the llama layer (see ggml_backend_cuda_set_mmb_enabled): tuned for qwen4exp
void ggml_cuda_mmb_set_opt_in(bool enable);
bool ggml_cuda_mmb_supported_mm (const ggml_tensor * src0, const ggml_tensor * src1, const ggml_tensor * dst);
bool ggml_cuda_mmb_supported_mmid(const ggml_tensor * src0, const ggml_tensor * src1, const ggml_tensor * ids, const ggml_tensor * dst);
void ggml_cuda_mul_mat_mmb (ggml_backend_cuda_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst);
Expand Down
11 changes: 11 additions & 0 deletions src/llama.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,17 @@ static std::pair<int, llama_model *> llama_model_load(struct gguf_context * meta
model->hparams.vocab_only = params.vocab_only;
model->hparams.no_alloc = params.no_alloc;

// The CUDA/HIP BF16 WMMA matmul path is tuned for the qwen4exp shapes; on other architectures it
// takes MUL_MATs away from MMQ and loses (dense qwen35 prefill measured 3.4x slower on gfx1151).
// Opt in by architecture rather than by device.
for (size_t i = 0; i < ggml_backend_reg_count(); ++i) {
auto * set_mmb_fn = (void (*)(bool)) ggml_backend_reg_get_proc_address(
ggml_backend_reg_get(i), "ggml_backend_cuda_set_mmb_enabled");
if (set_mmb_fn) {
set_mmb_fn(model->arch == LLM_ARCH_QWEN4EXP);
}
}

try {
model->load_hparams(ml);
} catch(const std::exception & e) {
Expand Down
Loading