Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1c4e5d8
feat(rocke/attention): deterministic LDS-budget resolver for 2D prefill
AviralGoelAMD Jul 3, 2026
3738343
feat(rocke/attention): mirror LDS-budget resolver in the C++ engine +…
AviralGoelAMD Jul 7, 2026
4fe8ddc
Merge remote-tracking branch 'origin/develop' into users/avirgoel/ck/…
AviralGoelAMD Jul 9, 2026
53824f8
style(rocke/attention): black-format merged _tiled_spec_from_problem
AviralGoelAMD Jul 9, 2026
a7c8fb2
fix(rocke/attention): recognize fp8e4m3/bf8e5m2 in shared LDS kv-elem…
AviralGoelAMD Jul 9, 2026
bf086c1
feat(rocke/attention): D256 gfx950 bf16 prefill 32x32 + softmax-MFMA …
AviralGoelAMD Jul 9, 2026
2dff7af
docs(runbook): Step 0 caveat — the preset bench is not the exhaustive…
AviralGoelAMD Jul 9, 2026
642e5dc
fix(rocke/attention): key the D256 fast-path override in the tiled ca…
AviralGoelAMD Jul 10, 2026
2f4dc93
feat(rocke): gfx950 slab-granularity K_lds pad bank conflict fix (#9260)
yraparti Jul 10, 2026
6036857
Merge remote-tracking branch 'origin/develop' into conflict-resolve/d…
AviralGoelAMD Jul 10, 2026
35dd100
refactor(rocke): author D256 gfx950 winning spec in the builder (#9336)
AviralGoelAMD Jul 13, 2026
6d76dc8
test(rocke): wire D256 gfx950 prefill into parity + benchmark harness…
AviralGoelAMD Jul 13, 2026
b306afa
style(rocke/attention): black-format attention_spec_builder.py
AviralGoelAMD Jul 13, 2026
beaaecb
fix(rocke/attention): address review comments (D256 gfx950 prefill)
AviralGoelAMD Jul 13, 2026
01db86a
feat(rocke): register gfx950 D256 bf16 prefill in the attention dispa…
AviralGoelAMD Jul 14, 2026
70c4a7b
refactor(rocke/attention): hoist torch-flash + occupancy probe to bui…
AviralGoelAMD Jul 15, 2026
56431d8
refactor(rocke/attention): move measurement-only KQ XOR swizzle to a …
AviralGoelAMD Jul 15, 2026
23d7e02
fix(rocke/attention): disable K_lds slab pad under fp8 (write/read as…
AviralGoelAMD Jul 15, 2026
5fca593
test(rocke/attention): add bs=32 D256 gfx950 parity scenario (2 block…
AviralGoelAMD Jul 15, 2026
d61156a
test(rocke/attention): pin D256 gfx950 fast-spec IR in the golden
AviralGoelAMD Jul 15, 2026
6849491
fix(rocke/attention): guard run_torch_flash against all-empty query_lens
AviralGoelAMD Jul 15, 2026
75796c0
test(rocke): move D256 fast-spec IR golden to the library test layer
AviralGoelAMD Jul 15, 2026
ba6b81b
Merge remote-tracking branch 'origin/develop' into users/avirgoel/ck/…
AviralGoelAMD Jul 15, 2026
3839cd1
style(rocke): apply black to changed files
AviralGoelAMD Jul 15, 2026
8dbf76a
Merge branch 'develop' into users/avirgoel/ck/d256-gfx950-opt
AviralGoelAMD Jul 15, 2026
177183b
Merge origin/develop into users/avirgoel/ck/d256-gfx950-opt
AviralGoelAMD Jul 21, 2026
377f9b3
Merge origin/develop into users/avirgoel/ck/d256-gfx950-opt
AviralGoelAMD Jul 21, 2026
922a8b3
fix(rocke/attention): gfx950 d64 combo forces T=64 so fast_paged_kv_d…
AviralGoelAMD Jul 21, 2026
c24e8ec
style(rocke/attention): black-format the d64 tile-fix conditional
AviralGoelAMD Jul 21, 2026
c339555
feat(rocke): gfx942 D256 bf16 prefill 4-warp GQA fast path
AviralGoelAMD Jul 11, 2026
9354c79
docs(rocke): replace D256 gfx942 perf note with measured OURS-vs-AITER
AviralGoelAMD Jul 11, 2026
6bcf26a
docs(rocke): correct D256 gfx942 geometry claim (spec identity vs lau…
AviralGoelAMD Jul 11, 2026
546ef16
fix(rocke/attention): address review comments (D256 gfx942 4-warp)
AviralGoelAMD Jul 13, 2026
9c4fcef
test(rocke): benchmark coverage for D256 gfx942 4-warp prefill
AviralGoelAMD Jul 14, 2026
e34ee98
test(rocke/attention): pin D256 gfx942 4-warp GQA fast-path IR in the…
AviralGoelAMD Jul 21, 2026
842e24e
Merge origin/develop into users/avirgoel/ck/d256-gfx942-4wgqa
AviralGoelAMD Jul 22, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"call_idx": 0, "kind": "2d", "ALL_DECODE": false, "num_seqs": 1, "num_query_heads": 16, "num_kv_heads": 2, "num_queries_per_kv": 8, "head_size": 256, "block_size": 16, "max_seqlen_q": 4096, "max_seqlen_k": 4096, "softmax_scale": 0.0625, "softcap": 0.0, "has_sinks": false, "has_alibi": false, "has_output_scale": false, "window_size": [-1, -1], "q_dtype": "torch.bfloat16", "k_dtype": "torch.bfloat16", "v_dtype": "torch.bfloat16", "out_dtype": "torch.bfloat16", "q_shape": [4096, 16, 256], "k_shape": [256, 16, 2, 256], "v_shape": [256, 16, 2, 256], "out_shape": [4096, 16, 256], "block_table_shape": [1, 256], "cu_seqlens_q_shape": [2], "seqused_k_shape": [1]}
{"call_idx": 1, "kind": "2d", "ALL_DECODE": false, "num_seqs": 1, "num_query_heads": 16, "num_kv_heads": 2, "num_queries_per_kv": 8, "head_size": 256, "block_size": 16, "max_seqlen_q": 8192, "max_seqlen_k": 8192, "softmax_scale": 0.0625, "softcap": 0.0, "has_sinks": false, "has_alibi": false, "has_output_scale": false, "window_size": [-1, -1], "q_dtype": "torch.bfloat16", "k_dtype": "torch.bfloat16", "v_dtype": "torch.bfloat16", "out_dtype": "torch.bfloat16", "q_shape": [8192, 16, 256], "k_shape": [512, 16, 2, 256], "v_shape": [512, 16, 2, 256], "out_shape": [8192, 16, 256], "block_table_shape": [1, 512], "cu_seqlens_q_shape": [2], "seqused_k_shape": [1]}
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ def supports_native_unified_attention_tiled(
use_k_single_buffer=gfx942_flash and _gfx942_flash_use_single_buffer(problem),
use_conflict_free_v_store=gfx942_flash and _gfx942_flash_use_cfvst(problem),
use_k_sliced_ring=_enable_gfx942_flash_k_sliced_ring(problem),
use_d256_gfx942_fast=_d256_gfx942_fast(problem),
)


Expand Down Expand Up @@ -732,6 +733,49 @@ def _enable_softmax_mfma_interleave(problem: UnifiedAttentionProblem) -> bool:
)


def _d256_gfx942_fast(problem: "UnifiedAttentionProblem") -> bool:
"""Route the D256 gfx942 bf16 prefill cohort to the natural-QK
(``S = Q @ K^T``) paged fast path (``build_gfx942_4warp_gqa``).

gfx942 has no fast D256 route on the default builder: the wide-flash gate
(``_enable_gfx942_bf16_flash``) excludes head_size==256 and the narrow
16x16x16 fallback overflows the 64 KB LDS at a competitive tile. This gate
picks a distinct, LDS-light 32x32x8 natural-QK builder instead. The spec +
``_tiled_cache_key`` carry num_warps=1 / tile_size=32 / block_m_per_warp=32
purely as the cohort *discriminator* (a distinct HSACO cache slot; every
other shape stays byte-identical) -- the builder itself is the 4-wave64 /
BLOCK_M=128 ``build_gfx942_4warp_gqa`` (selected in ``_get_2d_launcher``),
which ``_get_2d_launch_meta`` deliberately launches with block=(256,1,1) /
BLOCK_M=128, NOT the spec's 1-warp/32 geometry. Narrow + arch/feature-
guarded: every other shape is byte-identical.

Perf (gfx942, same-run vs AITER ``unified_attention``, D256 bf16 causal
prefill GQA 16/2 bs=16): OURS/AITER ~= 0.98x @ Sq4096 (parity), ~= 0.94x @
Sq8192 (OURS ~6% faster). Measured on MI300A 2026-07-11 (MI300X prototype
run: 0.97x / 0.94x); OURS matches the fp32 reference + AITER within bf16 tol.
"""
return (
_resolve_attention_arch() == "gfx942"
and problem.head_size == 256
and problem.dtype == "bf16"
and not problem.use_fp8
and problem.sliding_window == 0
and problem.softcap == 0
and not problem.use_sinks
and not problem.use_alibi
and not problem.use_qq_bias
and problem.max_seqlen_q > 1
# tile_size==32 requires block_size in {16, 32} (tile % block == 0). The
# ticket pins gfx942 D256 to block_size=16 (block_size=64 is too large
# for the tiled kernel here,); 64 cleanly falls back.
and problem.block_size in (16, 32)
# The natural-QK builder uses i32 paged element addressing (like the
# shipped builder's default). Exclude caches > 2 GiB, which need the
# i64 path -- they fall back to the correct default builder.
and not _enable_i64_kv_addr(problem)
)


def _select_2d_tile_size(problem: UnifiedAttentionProblem) -> int:
"""Choose ``tile_size`` (T) for the tiled 2D kernel.

Expand Down Expand Up @@ -761,6 +805,8 @@ def _select_2d_tile_size(problem: UnifiedAttentionProblem) -> int:
"""
if _d256_gfx950_fast(problem):
return 64
if _d256_gfx942_fast(problem):
return 32 # BLOCK_N of the natural-QK paged kernel
if _resolve_attention_arch() == "gfx1250":
# gfx1250 v1 consumes exactly one 32-token paged-KV block per WMMA
# iteration; wider T needs separate multi-block block-table handling.
Expand Down Expand Up @@ -916,6 +962,8 @@ def _select_2d_num_warps(problem: UnifiedAttentionProblem) -> int:
"""
if _d256_gfx950_fast(problem):
return 2
if _d256_gfx942_fast(problem):
return 1 # cache-key discriminator only; the 4-warp kernel launches block=(256,1,1) / BLOCK_M=128 via _get_2d_launch_meta
if _resolve_attention_arch() == "gfx1250":
# A gfx1250 workgroup is one wave32 in the v1 WMMA tiled path.
return 1
Expand Down Expand Up @@ -1171,6 +1219,10 @@ def _tiled_cache_key(problem: UnifiedAttentionProblem) -> Tuple:
# deliberately lives ABOVE the autotuner-regenerable `_enable_*` helpers
# below; keying on the predicate (not the flags) keeps that layering.
_d256_gfx950_fast(problem),
# Selects the distinct natural-QK 4-warp GQA builder (build_gfx942_4warp_gqa)
# in `_get_2d_launcher`; keyed so its HSACO never shares a cache slot with
# the default gfx942 builder for the same geometry.
_d256_gfx942_fast(problem),
_enable_mfma_32x32(problem),
_enable_transposed_qk_32x32(problem),
_enable_transposed_half_local_pv(problem),
Expand Down Expand Up @@ -2300,6 +2352,8 @@ def _select_2d_block_m_per_warp(problem: UnifiedAttentionProblem) -> int:
"""
if _d256_gfx950_fast(problem):
return 32
if _d256_gfx942_fast(problem):
return 32 # cache-key discriminator only; the dedicated 4-warp kernel uses BLOCK_M=128
if _resolve_attention_arch() == "gfx1250":
return 16
# mw=32 (BLOCK_M = 32 * num_warps) only pays off when a path actually
Expand Down Expand Up @@ -3479,7 +3533,16 @@ def _get_2d_launcher(
arch = _resolve_attention_arch()
_, build_unified_attention_2d_tiled, _ = _tiled_2d_impl(arch)
spec = _tiled_spec_from_problem(problem)
kernel = build_unified_attention_2d_tiled(spec, arch=arch)
if _d256_gfx942_fast(problem):
# Distinct 4-warp GQA paged builder for the D256 gfx942 cohort
# (keyed separately in `_tiled_cache_key`; grid in
# `_get_2d_launch_meta`). Same paged ABI as the default builder.
# Parity+ with AITER @Sq4096/8192 (vs the 1-warp std-QK's 0.55x).
from ..gfx942.attention_tiled_2d import build_gfx942_4warp_gqa

kernel = build_gfx942_4warp_gqa(spec, arch=arch)
else:
kernel = build_unified_attention_2d_tiled(spec, arch=arch)
backend = _select_2d_compile_backend(problem)
if backend == "hipcc":
from rocke.helpers.compile import compile_kernel_via_hipcc
Expand Down Expand Up @@ -3512,6 +3575,17 @@ def _get_2d_launch_meta(
if meta_key in _2D_LAUNCH_META:
return _2D_LAUNCH_META[meta_key]
arch = _resolve_attention_arch()
if _d256_gfx942_fast(problem):
# 4-warp GQA paged kernel: 4 wave64/CTA own BLOCK_M=128 q-tokens for ONE
# query head. grid = (num_query_heads, q-token-blocks + per-seq padding).
# block_q == BLOCK_M == 128, matching the kernel's binary_search_seq_idx.
total_num_q_blocks = problem.total_q // 128 + problem.num_seqs
meta = _Attention2DLaunchMeta(
grid=(int(problem.num_query_heads), int(total_num_q_blocks), 1),
block=(256, 1, 1),
)
_2D_LAUNCH_META[meta_key] = meta
return meta
if _enable_gfx942_bf16_flash(problem):
# _select_gfx942_flash_num_warps mirrors the spec builder for BOTH dtypes:
# ring-active -> fp16-flash wide geometry; bf16 non-ring -> bf16-wide nw.
Expand Down
Loading
Loading