Skip to content

ggml-cuda : disable MMQ on devices with less than 48 KiB shared memory - #26141

Merged
am17an merged 1 commit into
ggml-org:masterfrom
KakaruHayate:fix-mmq-smem-fallback
Jul 29, 2026
Merged

am17an merged 1 commit into
ggml-org:masterfrom
KakaruHayate:fix-mmq-smem-fallback

Conversation

@KakaruHayate

@KakaruHayate KakaruHayate commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Overview

ggml_cuda_should_use_mmq() currently selects MMQ purely from the quantization type. The current MMQ configurations are designed and maintained against a minimum of 48 KiB per-block shared memory, the limit provided by NVIDIA Pascal GPUs and later. On devices that report less, no supported MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size exceeds the device's per-block shared memory budget.

This PR disables MMQ when smpbo < 48 KiB so the caller falls back to the BLAS path instead of hitting GGML_ABORT. Some current MUSA QY1 devices report only 28 KiB and are covered by this guard.

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, This is an issue that Claude found and fixed when I was adapting LLAMA.CPP for MUSA RWKV7 downstream

@KakaruHayate
KakaruHayate requested a review from a team as a code owner July 26, 2026 15:15
@github-actions github-actions Bot added ggml changes relating to the ggml tensor library for machine learning CUDA Related to the CUDA backend labels Jul 26, 2026
@ggml-gh-bot

ggml-gh-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

Hi @KakaruHayate, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@KakaruHayate KakaruHayate changed the title CUDA/MUSA: fall back to cuB when no MMQ tile size fits in smem CUDA/MUSA: fall back to cuBlass when no MMQ tile size fits in smem Jul 27, 2026
@KakaruHayate KakaruHayate changed the title CUDA/MUSA: fall back to cuBlass when no MMQ tile size fits in smem ggml-cuda : fall back to cuBLAS when no MMQ tile size fits in shared memory Jul 27, 2026
@KakaruHayate
KakaruHayate force-pushed the fix-mmq-smem-fallback branch from d8776de to 1eee668 Compare July 27, 2026 05:02
@am17an

am17an commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What device do you face this problem in?

@KakaruHayate

Copy link
Copy Markdown
Contributor Author

What device do you face this problem in?

MooreThreads MTT S70. The sharedMemPerBlock of S70 is only 28 KiB.

@am17an

am17an commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Would it be better if you use cublas for all MUSA GPUs? None of the maintainers have access to these GPUs and cannot guarantee MMQ will keep working with these GPUs in the future.

@KakaruHayate

Copy link
Copy Markdown
Contributor Author

Would it be better if you use cublas for all MUSA GPUs? None of the maintainers have access to these GPUs and cannot guarantee MMQ will keep working with these GPUs in the future.

I understand the concern — maintainers don't have access to Moore Threads hardware, so long-term guarantees for the MMQ path on these devices are difficult.

That said, completely disabling MMQ for all MUSA GPUs may be overly broad. On the current S70/S80/S3000 (28 KiB sharedMemPerBlock), some quantizations (Q4_K_M, FP16, etc.) still fit and run with MMQ without issues. Only certain types like Q8_0 exhaust the available shared memory and need the fallback. Newer cards (S4000/S5000) may also have larger shared memory budgets.

Note that this particular abort path essentially never triggers on NVIDIA GPUs. All modern NVIDIA architectures that llama.cpp targets for MMQ (Pascal and later) report at least 48 KiB sharedMemPerBlock by default, which is the baseline the current tile selection was designed around. The 28 KiB case is unique to the Moore Threads hardware.

The current PR only adds a safety check inside ggml_cuda_should_use_mmq(): if no tile size fits into the device's smpbo, it returns false and falls back to cuBLAS instead of aborting. This is a general defensive measure that would also protect any future low-smem devices, not just MUSA.

If the maintainers prefer a more conservative stance, I'm happy to:

  • Add an explicit #ifdef GGML_USE_MUSA path that forces cuBLAS, or
  • Document that MMQ support on Moore Threads is best-effort / untested by the core team.

Just let me know which direction you prefer and I'll adjust the PR accordingly.

@am17an

am17an commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Note that this particular abort path essentially never triggers on NVIDIA GPUs. All modern NVIDIA architectures that llama.cpp targets for MMQ (Pascal and later) report at least 48 KiB sharedMemPerBlock by default, which is the baseline the current tile selection was designed around. The 28 KiB case is unique to the Moore Threads hardware

Probably just add this check then? If smpbo is report less than 48kb then MMQ cannot be used at the moment. Leave a comment about MUSA devices having 28kib

@KakaruHayate

Copy link
Copy Markdown
Contributor Author

Note that this particular abort path essentially never triggers on NVIDIA GPUs. All modern NVIDIA architectures that llama.cpp targets for MMQ (Pascal and later) report at least 48 KiB sharedMemPerBlock by default, which is the baseline the current tile selection was designed around. The 28 KiB case is unique to the Moore Threads hardware

Probably just add this check then? If smpbo is report less than 48kb then MMQ cannot be used at the moment. Leave a comment about MUSA devices having 28kib

This is also feasible. It's very pragmatic and reasonable. I will make changes based on this suggestion.

@KakaruHayate
KakaruHayate force-pushed the fix-mmq-smem-fallback branch from 1eee668 to a5cccfa Compare July 29, 2026 06:56
@KakaruHayate KakaruHayate changed the title ggml-cuda : fall back to cuBLAS when no MMQ tile size fits in shared memory ggml-cuda : disable MMQ on devices with less than 48 KiB shared memory Jul 29, 2026
ggml_cuda_should_use_mmq() selects MMQ purely from the quantization
type. The current MMQ configurations are designed and maintained against
a minimum of 48 KiB per-block shared memory, the limit provided by
NVIDIA Pascal GPUs and later. On devices that report less, no supported
MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size
exceeds the device's per-block shared memory budget.

Disable MMQ when smpbo < 48 KiB so the caller falls back to the BLAS
path instead of hitting GGML_ABORT. Some current MUSA QY1 devices
report only 28 KiB and are covered by this guard.

Reproduced on a Moore Threads MTT S70 (arch mp_21, 28 KiB shared memory
per block) with an RWKV-7 0.1B Q8_0 model:

  $ llama-bench -m rwkv7-g1d-0.1b-Q8_0.gguf -p 128 -n 0
  J_best=0
  ggml/src/ggml-cuda/template-instances/../mmq.cuh:1521: fatal error
  (core dumped)

Only prefill (batch > 1) is affected; token generation is fine. After
the fix the same device falls back to the BLAS path:

  Q8_0    pp128 1470.7 t/s, tg8 55.3 t/s   (was: abort)
  FP16    unchanged
  Q4_K_M  unchanged

This matches a -DGGML_CUDA_FORCE_CUBLAS=ON build (pp128 1464.2 t/s),
which confirms the fallback path is the one being taken.

This is not MUSA-specific: any device with less than 48 KiB per-block
shared memory is affected.
@KakaruHayate
KakaruHayate marked this pull request as draft July 29, 2026 07:02
@KakaruHayate
KakaruHayate force-pushed the fix-mmq-smem-fallback branch from a5cccfa to 0e27a00 Compare July 29, 2026 07:03
@KakaruHayate
KakaruHayate marked this pull request as ready for review July 29, 2026 07:06
@am17an
am17an merged commit caa596a into ggml-org:master Jul 29, 2026
1 check passed
huaxel pushed a commit to huaxel/UmaLlama that referenced this pull request Aug 2, 2026
ggml-org#26141)

ggml_cuda_should_use_mmq() selects MMQ purely from the quantization
type. The current MMQ configurations are designed and maintained against
a minimum of 48 KiB per-block shared memory, the limit provided by
NVIDIA Pascal GPUs and later. On devices that report less, no supported
MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size
exceeds the device's per-block shared memory budget.

Disable MMQ when smpbo < 48 KiB so the caller falls back to the BLAS
path instead of hitting GGML_ABORT. Some current MUSA QY1 devices
report only 28 KiB and are covered by this guard.

Reproduced on a Moore Threads MTT S70 (arch mp_21, 28 KiB shared memory
per block) with an RWKV-7 0.1B Q8_0 model:

  $ llama-bench -m rwkv7-g1d-0.1b-Q8_0.gguf -p 128 -n 0
  J_best=0
  ggml/src/ggml-cuda/template-instances/../mmq.cuh:1521: fatal error
  (core dumped)

Only prefill (batch > 1) is affected; token generation is fine. After
the fix the same device falls back to the BLAS path:

  Q8_0    pp128 1470.7 t/s, tg8 55.3 t/s   (was: abort)
  FP16    unchanged
  Q4_K_M  unchanged

This matches a -DGGML_CUDA_FORCE_CUBLAS=ON build (pp128 1464.2 t/s),
which confirms the fallback path is the one being taken.

This is not MUSA-specific: any device with less than 48 KiB per-block
shared memory is affected.

Co-authored-by: KakaruHayate <KakaruHayate@users.noreply.github.com>
satindergrewal pushed a commit to satindergrewal/llama.cpp that referenced this pull request Aug 12, 2026
ggml-org#26141)

ggml_cuda_should_use_mmq() selects MMQ purely from the quantization
type. The current MMQ configurations are designed and maintained against
a minimum of 48 KiB per-block shared memory, the limit provided by
NVIDIA Pascal GPUs and later. On devices that report less, no supported
MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size
exceeds the device's per-block shared memory budget.

Disable MMQ when smpbo < 48 KiB so the caller falls back to the BLAS
path instead of hitting GGML_ABORT. Some current MUSA QY1 devices
report only 28 KiB and are covered by this guard.

Reproduced on a Moore Threads MTT S70 (arch mp_21, 28 KiB shared memory
per block) with an RWKV-7 0.1B Q8_0 model:

  $ llama-bench -m rwkv7-g1d-0.1b-Q8_0.gguf -p 128 -n 0
  J_best=0
  ggml/src/ggml-cuda/template-instances/../mmq.cuh:1521: fatal error
  (core dumped)

Only prefill (batch > 1) is affected; token generation is fine. After
the fix the same device falls back to the BLAS path:

  Q8_0    pp128 1470.7 t/s, tg8 55.3 t/s   (was: abort)
  FP16    unchanged
  Q4_K_M  unchanged

This matches a -DGGML_CUDA_FORCE_CUBLAS=ON build (pp128 1464.2 t/s),
which confirms the fallback path is the one being taken.

This is not MUSA-specific: any device with less than 48 KiB per-block
shared memory is affected.

Co-authored-by: KakaruHayate <KakaruHayate@users.noreply.github.com>
thecodacus pushed a commit to thecodacus/llama.cpp that referenced this pull request Sep 7, 2026
ggml-org#26141)

ggml_cuda_should_use_mmq() selects MMQ purely from the quantization
type. The current MMQ configurations are designed and maintained against
a minimum of 48 KiB per-block shared memory, the limit provided by
NVIDIA Pascal GPUs and later. On devices that report less, no supported
MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size
exceeds the device's per-block shared memory budget.

Disable MMQ when smpbo < 48 KiB so the caller falls back to the BLAS
path instead of hitting GGML_ABORT. Some current MUSA QY1 devices
report only 28 KiB and are covered by this guard.

Reproduced on a Moore Threads MTT S70 (arch mp_21, 28 KiB shared memory
per block) with an RWKV-7 0.1B Q8_0 model:

  $ llama-bench -m rwkv7-g1d-0.1b-Q8_0.gguf -p 128 -n 0
  J_best=0
  ggml/src/ggml-cuda/template-instances/../mmq.cuh:1521: fatal error
  (core dumped)

Only prefill (batch > 1) is affected; token generation is fine. After
the fix the same device falls back to the BLAS path:

  Q8_0    pp128 1470.7 t/s, tg8 55.3 t/s   (was: abort)
  FP16    unchanged
  Q4_K_M  unchanged

This matches a -DGGML_CUDA_FORCE_CUBLAS=ON build (pp128 1464.2 t/s),
which confirms the fallback path is the one being taken.

This is not MUSA-specific: any device with less than 48 KiB per-block
shared memory is affected.

Co-authored-by: KakaruHayate <KakaruHayate@users.noreply.github.com>
zbrad pushed a commit to zbrad/llama.cpp that referenced this pull request Sep 10, 2026
ggml-org#26141)

ggml_cuda_should_use_mmq() selects MMQ purely from the quantization
type. The current MMQ configurations are designed and maintained against
a minimum of 48 KiB per-block shared memory, the limit provided by
NVIDIA Pascal GPUs and later. On devices that report less, no supported
MMQ tile fits and mul_mat_q_switch_J() aborts when every tile size
exceeds the device's per-block shared memory budget.

Disable MMQ when smpbo < 48 KiB so the caller falls back to the BLAS
path instead of hitting GGML_ABORT. Some current MUSA QY1 devices
report only 28 KiB and are covered by this guard.

Reproduced on a Moore Threads MTT S70 (arch mp_21, 28 KiB shared memory
per block) with an RWKV-7 0.1B Q8_0 model:

  $ llama-bench -m rwkv7-g1d-0.1b-Q8_0.gguf -p 128 -n 0
  J_best=0
  ggml/src/ggml-cuda/template-instances/../mmq.cuh:1521: fatal error
  (core dumped)

Only prefill (batch > 1) is affected; token generation is fine. After
the fix the same device falls back to the BLAS path:

  Q8_0    pp128 1470.7 t/s, tg8 55.3 t/s   (was: abort)
  FP16    unchanged
  Q4_K_M  unchanged

This matches a -DGGML_CUDA_FORCE_CUBLAS=ON build (pp128 1464.2 t/s),
which confirms the fallback path is the one being taken.

This is not MUSA-specific: any device with less than 48 KiB per-block
shared memory is affected.

Co-authored-by: KakaruHayate <KakaruHayate@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CUDA Related to the CUDA backend ggml changes relating to the ggml tensor library for machine learning

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants