Skip to content

[ROCm][Bugfix] Skip AITER tuned GEMM when M*N >= 2^31 on gfx950 - #64567

Merged
AndreasKaratzas merged 6 commits into
vllm-project:mainfrom
ROCm:mm3-dp-gemm-overflow
Oct 30, 2026
Merged

AndreasKaratzas merged 6 commits into
vllm-project:mainfrom
ROCm:mm3-dp-gemm-overflow

Conversation

@micah-wil

@micah-wil micah-wil commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Overview

Skip AITER's tuned GEMM (tgemm.mm) on gfx950 when M·N ≥ 2^31 (Also skip AITER tuned GEMM when A or B spans >= 4 GiB) and fall back to F.linear (hipBLASLt). This works around an int32 output-offset overflow in AITER's gfx950 FlyDSL A16W16 kernel (fix pending in ROCm/aiter#6853). Since AITER v0.1.26, that overflow crashes amd/MiniMax-M3-MXFP4 at startup with --mm-encoder-tp-mode data.

Claims

  • Fixes the Memory access fault ... Write access to a read-only page crash during the encoder-cache profile run of MiniMax-M3-MXFP4 on MI355X (TP4) with --mm-encoder-tp-mode data.
  • No performance cost: only GEMMs with ≥ 2^31 output elements are rerouted, and hipBLASLt matches the FlyDSL kernel's throughput at those sizes. Normal LLM prefill/decode GEMMs never reach this size.

Validation

Environment: MI355X, vllm/vllm-openai-rocm:nightly, AITER 0.1.26.

Kernel-level repro (tgemm.mm vs F.linear, N=6144, K=1280, bf16, with bias; this matches the tuned minimax_m3_mxfp4_bf16_tuned_gemm.csv rows):

M M·N vs 2^31 tgemm.mm (AITER) F.linear (hipBLASLt)
340,000 below 1221 TFLOP/s 1206 TFLOP/s
360,000 above Memory access fault n/a
768,000 above Memory access fault 1229 TFLOP/s

End-to-end with this patch:

VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=1 VLLM_ROCM_USE_AITER_MOE=1 \
vllm serve amd/MiniMax-M3-MXFP4 -tp 4 --trust-remote-code --block-size 128 \
  --attention-backend TRITON_ATTN --moe-backend aiter --kv-cache-dtype fp8 \
  --mm-encoder-tp-mode data --mm-encoder-attn-backend ROCM_AITER_FA \
  --tool-call-parser minimax_m3 --enable-auto-tool-choice --reasoning-parser minimax_m3 

Before: crashes at startup with the memory access fault. After: startup completes (178 GiB KV cache on TP0), and three chat requests with a 2016×2016 image return 200 with no faults. Confirmed there is no accuracy change.

No unit test is added: reproducing the bug needs gfx950 hardware plus AITER's model-specific tuned CSV, and a mocked test would only restate the condition.

Details

Root cause. With --mm-encoder-tp-mode data, each rank runs the ViT unsharded, so the profile run issues an M=768000, N=6144, K=1280 GEMM with bias. In AITER v0.1.26, getPaddedM maps it to the 8192,6144,1280 FlyDSL row in minimax_m3_mxfp4_bf16_tuned_gemm.csv. That kernel computes global_row * n + global_col in int32, which wraps once M·N ≥ 2^31 and writes out of bounds. In TP mode N is sharded 4 ways, so M·N stays under the limit.

Why route around it here. rocm_unquantized_gemm_impl is the only vLLM call site of tgemm.mm. The guard is limited to gfx950 and to the exact overflow condition, so all other shapes keep AITER's tuned dispatch. Skipping FlyDSL for this call also avoids the FlyDSL 0.4.0 from_dlpack leak described in ROCm/aiter#6853, which pinned about 10.6 GiB after the ViT profile run.

The guard can be removed once vLLM's minimum AITER includes ROCm/aiter#6853.


Pull Request Checklist
  • I used vLLM's /pr-checklist skill. (Mandatory for agents, optional for humans).

  • AI assistance was used during the creation of this PR.

  • Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.

  • Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.

  • Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.

  • Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.

AITER's gfx950 FlyDSL A16W16 kernel addresses C with int32 offsets and
faults once M * N >= 2^31 (ROCm/aiter#6853). With
--mm-encoder-tp-mode data, the MiniMax-M3 ViT profile run issues an
M=768000, N=6144, K=1280 GEMM that AITER 0.1.26 routes to that kernel,
crashing engine startup with a memory access fault.

Fall back to torch (hipBLASLt) for those shapes. They are compute-bound
and hipBLASLt matches the FlyDSL kernel's throughput there.

Signed-off-by: Micah Williamson <micah.williamson@amd.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@mergify mergify Bot added rocm Related to AMD ROCm bug Something isn't working labels Oct 29, 2026
@github-project-automation github-project-automation Bot moved this to Todo in AMD Oct 29, 2026
@micah-wil micah-wil added the ready ONLY add when PR is ready to merge/full CI is needed label Oct 29, 2026
@micah-wil

Copy link
Copy Markdown
Collaborator Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #98431 for commit 025611841ad1.

AITER's gfx950 FlyDSL A16W16 kernel reads A and B through flat buffer
descriptors with i32 offsets, so an operand of 4 GiB or more is read
out of bounds and the kernel silently returns wrong rows. For example,
Llama-405B's TP8 gate_up GEMM (N=13312, K=16384) maps to a FlyDSL row
and returns wrong output at 147456 tokens, while C is still under the
2^31 limit. Route these shapes to torch as well, matching the limit
ROCm/aiter#6853 enforces. Drop the on_gfx950() check, which
is_tgemm_enabled() already implies.

Signed-off-by: Micah Williamson <micah.williamson@amd.com>
@micah-wil

Copy link
Copy Markdown
Collaborator Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #98439 for commit e44957c7fa6f.

@AndreasKaratzas
AndreasKaratzas enabled auto-merge (squash) October 29, 2026 22:03
@AndreasKaratzas

Copy link
Copy Markdown
Member

/ci retry

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #98540 for commit bd01b0b27762, running 1 failed step(s) from Buildkite CI #98439.

@mergify

mergify Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Hi @micah-wil, the pre-commit checks have failed. Please run:

uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-files

Then, commit the changes and push to your branch.

For future commits, pre-commit will run automatically on changed files before each commit.

@mergify mergify Bot added multi-modality Related to multi-modality (#4194) glm labels Oct 30, 2026
@micah-wil
micah-wil force-pushed the mm3-dp-gemm-overflow branch from b50b65f to bd01b0b Compare October 30, 2026 04:12
@micah-wil

Copy link
Copy Markdown
Collaborator Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #98553 for commit dec78774a147.

@AndreasKaratzas
AndreasKaratzas merged commit 6d01893 into vllm-project:main Oct 30, 2026
118 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in AMD Oct 30, 2026
@AndreasKaratzas
AndreasKaratzas deleted the mm3-dp-gemm-overflow branch October 30, 2026 05:39
@khluu khluu added this to the v0.33.0 cherry picks milestone Oct 30, 2026
khluu pushed a commit that referenced this pull request Oct 30, 2026
Signed-off-by: Micah Williamson <micah.williamson@amd.com>
(cherry picked from commit 6d01893)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working glm multi-modality Related to multi-modality (#4194) ready ONLY add when PR is ready to merge/full CI is needed rocm Related to AMD ROCm

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants