HIP : add shared-memory tiled transpose fast path for F32 concat on RDNA3.5 - #28303
Open
Casten-Wang wants to merge 1 commit into
Open
HIP : add shared-memory tiled transpose fast path for F32 concat on RDNA3.5#28303Casten-Wang wants to merge 1 commit into
Casten-Wang wants to merge 1 commit into
Conversation
Assisted-by: Codex
Casten-Wang
marked this pull request as draft
September 3, 2026 07:18
|
Hi @Casten-Wang, thanks for your contribution! Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:
Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below. |
Casten-Wang
marked this pull request as ready for review
September 3, 2026 07:36
Member
|
What is "model" in this case? :) |
Author
|
Qwen3.6-35B-A3B (MoE, 35B total / 3B activated) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
On AMD RDNA3.5 (gfx1151, HIP backend),
concaton dim 0 with a transposed F32src1view falls back to the generic non-contiguous, per-element copy path. Theconcrete shape seen during transformer prefill input processing is:
Because
src1is a transposed view, logically adjacent elements are notphysically adjacent, so global-memory access is poorly coalesced — the result is
correct, only slow.
This PR adds a dedicated kernel
concat_f32_transposefor exactly this case:32 × 8), one logical32×32tile perblock.
src1is staged through__shared__ float tile[32][33], transposed inshared memory, then written out coalesced. The
[32][33]padding (one extracolumn) shifts each row's start so transposed reads don't collide on the same
shared-memory bank — the standard fix for transpose bank conflicts.
src0iscontiguous and copied into the first
ne00elements of each channel only whenblockIdx.y == 0, avoiding redundant copies across vertical tiles.concat_try_f32_transpose. Triggers only whendim == 0;src0/src1/dstare all F32; the device is RDNA3.5;src1->ne[0]is512/1024/2048;
src0/dstare contiguous;src1has strict transposestrides; and
dst->ne[2] * dst->ne[3] <= 65535. Otherwise it returns false andthe original implementation runs unchanged — no existing path is deleted or
rewritten.
Only two files change:
ggml/src/ggml-cuda/concat.cuandtests/test-backend-ops.cpp(+132 / -1). Related to #21284.Additional information
Why only prefill. The matching shape (
ne00=3, ne10=2048, ne1=8192, ne2=1, ne3=1) only appears in prefill input processing; decode never matches andfalls back:
Tests (
test-backend-ops.cpp). Newtransposed blayout (1 << 4, i.e.v & 16) built with a realggml_transpose, matching the model's layout.Transposed cases are checked with
std::memcmpfor bit-identical output (thekernel only copies/reorders F32 — no arithmetic or conversion). Fast-path shapes:
widths 512/1024/2048 × channel counts 31/32/33/64 (tile boundaries) plus a
ne2 = 2case. Fallback shapes: non-whitelisted widths 1/31/32/511/513/1537, acontiguous F32 case, and a transposed F16 case. Result: concat
198/198pass;transposed F32 output bit-identical.
Performance (Windows 11, ROCm 7.1, Radeon 8060S / gfx1151). A = upstream
master, B = master + this change; A/B build artifacts differ only in
ggml-hip.dll. Full GPU offload, Flash Attention, HIP Graph,p2048,b4096,t16. Order A/B/B/A then extended; 10 samples per version per scenario; medians:All prefill scenarios improve in the same direction (+4.08% .. +12.22%); decode
changes are < 1% (run-to-run noise, not a regression). No thermal throttling; A/B
GPU clock, memory clock, power and temperature ranges overlap. Fixed-input output
hashes match A/B (Q4_K_M
5A2BC481...A45867F846, BF16E8524416...EBB75C683).Known limitation. The gate restricts width but not channel count
(
dst->ne[1]), so some small-channel shapes can still enter the fast path andregress. At width 2048,
ne1 = 33regresses ~ -4.25% and it turns positive fromne1 = 64(the real model widthne1 = 8192improves clearly), because for verysmall workloads the kernel's launch/sync/tiling overhead can exceed the generic
kernel. This first PR deliberately keeps the narrow 512/1024/2048 whitelist —
those widths are directly validated by the real model with minimal code surface.
A workload/channel gate to widen the range can be added separately if maintainers
prefer.
Requirements
assistance (code analysis, implementation drafting, and test/benchmark
automation). I have reviewed the diff and understand the transpose indexing,
the
[32][33]shared-memory tiling, theblockIdx.y == 0single copy ofsrc0, the tail-block bounds checks, the fallback gating, and the knownsmall-channel regression; I take responsibility for maintaining this change.