Skip to content

feat(rocke): top-left causal and attention band coverage on gfx950 - #13125

Merged
AnaghaRaoAMD merged 3 commits into
developfrom
users/anarao/aick-2505-top-left-causal-coverage
Oct 17, 2026
Merged

AnaghaRaoAMD merged 3 commits into
developfrom
users/anarao/aick-2505-top-left-causal-coverage

Conversation

@AnaghaRaoAMD

@AnaghaRaoAMD AnaghaRaoAMD commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes the gfx950 forward-attention top-left causal gap in rocKE: the unified kernels silently served top-left as bottom-right (and were unconditionally causal), their dispatch candidates over-claimed a mask they did not implement, and dense mishandled cross-length / ragged shapes. The mask is now the cuDNN/hipDNN band (left = sliding_window, right = right_bound, alignment = diagonal_alignment) computed exactly or rejected with a reason. Part of epic AICK-2500.

JIRA ID : AICK-2505

Risk Assessment

High risk. On gfx950 the default request mask (NO_MASK) now means full attention in the unified family instead of being served by a causal kernel, and AttentionRequest gains fields, a band capability feature and new rejections; the kernel changes are large. Default-off IR is pinned byte-identical by the existing platform representative golden (re-run after merging develop), and the new variants' lowered IR is pinned by 26 added cases in that golden. gfx950 hardware parity is green, but no gfx942 / gfx1250 hardware run has been done for the dispatch changes that apply to those arches, and the new bodies are not yet mirrored in the C++ engine (see Known gaps).

ASIC Coverage

Kernel changes are gfx950-only, so gfx950 hardware must pass (done locally, see below). The dispatch-layer changes are arch-wide: SLIDING_WINDOW ordinal handling, the new request fields and band feature, and gating of the gfx942 dense-pipe and gfx942/gfx1250 tiled paths. gfx942 and gfx1250 keep their legacy NO_MASK (causal) body by design, and non-causal bands are rejected there. That behaviour is covered by CPU tests, but a gfx942 GPU-lane run is required before merge to confirm no routing regression.

Testing Summary

  • gfx950 hardware parity (MI355X): unified 2D / 3D / scalar kernels against an explicit PyTorch-style reference for top-left, full attention, non-causal and two-sided windows, lookahead, decode, sinks, softcap, D64/D128/D256, GQA, the tiled-lever matrix, and exactly-zero empty rows; dense band matrix through both the spec and the dispatch path, including persistent and ragged cross-attention.
  • Default-off IR byte-identity at llvm20, llvm22 and llvm23 via the existing platform harness golden (rocke_representative_ir_sha256.json: 32 attention_dense/gfx950 and 10 attention/gfx950 cases). Scalar and tiled window / QQ-bias / D256 variants that golden does not cover were compared once against the base commit (31 cases x 3 flavors, 0 differences); no separate library golden is added.
  • Dispatch wiring tests: distinct kernel names / cache keys for every unified candidate, band normalization, capability features, off-gfx950 gates.
  • Empty-row behaviour cross-checked against PyTorch 2.10 SDPA (fully masked rows return 0).

Testing Checklist

  • rocKE library CPU lane - python library/tests/run_all.py - Status: Passed (2314 passed; 3 failures, all pre-existing and identical on clean develop: test_tiled_2d_shipped_geometries_compile_and_fit_budget and the gfx942 dense llvm23 golden)
  • rocKE library GPU lane - python library/tests/run_all.py --gpu-only - ASICs: gfx950 - Status: Passed (536 passed, on the branch merged with develop)
  • rocKE installed golden gate - python platform/tests/rocke_installed_golden_test.py - Status: Passed (llvm20, llvm22, llvm23), re-run after merging develop (including the fp32 softmax-scale and dispatcher-restructure changes)
  • Pre-commit hooks - git commit - Status: Passed
  • Review fixes validated - GPU lane 544 passed (gfx950); CPU lane 2317 passed with the same 3 failures as clean develop; platform golden gate PASS at llvm20, llvm22, llvm23 with the 26 added cases
  • rocKE library GPU lane on gfx942 - python library/tests/run_all.py --gpu-only - ASICs: gfx942 - Status: Not run
  • PR CI - GitHub PR checks - Status: Pending

Technical Changes

  • Review follow-up: top-left is no longer folded into bottom-right on the unified family when the request's seqlen_q == seqlen_k (batch maxima there; the kernels derive the diagonal per sequence); dense keeps that shortcut. Dense q-blocks entirely past the keys no longer read other batches' tokens (start tile clamped when rows can be empty; the dense band matrix now runs at batch=2). The new variants' IR is pinned in the platform golden, and a GPU case covers request -> dispatch -> launch on a mixed-length cohort.

  • Merged develop (fix(rocke): Expose more knobs of SDPA kernels via updated dispatcher interface gfx942, gfx950  #12719 dispatcher restructure, fix(rocke): apply gfx950 dense softmax scale in fp32 #13122 fp32 softmax scale): the dense band moved into gfx950_dense.py (_dense_band, _is_ragged), the unified AttentionSpec fields into gfx950_unified.py, and right_bound is classified as a dense problem field. Under fix(rocke): apply gfx950 dense softmax scale in fp32 #13122's finite mask sentinel a row with no visible key is no longer NaN but averages V, so the dense kernels now zero such a row at the epilogue when its running max is still at the sentinel.

  • Unified 2D tiled, 3D split-KV and scalar kernels: new causal_top_left and right_bound problem/spec fields. The window anchor stays d - k < W and the upper compare becomes k <= d + R (skipped when unbounded); tile bounds, the sliding-window tile end, the peel split and the mask_limit threshold all follow R. R = 0 lowers byte-identically.

  • Dense kernel (default and persistent grids): right_bound, non-causal windows, lookahead, ragged cross-attention, and a zero-output guard for rows with no visible key (previously stale data from exp2(-inf - -inf)), emitted only when such rows can exist.

  • Dispatch: AttentionRequest.right_bound / diagonal_alignment, a band capability feature, SLIDING_WINDOW read as the band trio (rejected when it names no bound), distinct kernel names (_tl, _rbu / _rb<R>, _sw<W>) and cache keys; unsupported combinations (e.g. ALiBi/QQ-bias with a right bound, dense bottom-right window at sq != sk) are rejected with a reason.

  • Parity harness: ref_paged_attn band reference and --set topleft|nomask|band; gfx950 benchmarks that relied on the default mask now pin bottom-right causal.

  • Known gaps (follow-ups):

    • C++ mirror (tracked follow-up): the causal_top_left / right_bound bodies of the tiled 2D / 3D and unified (scalar) kernels are not yet mirrored in platform/cpp/instances/, and there are no library/tests/parity/*_emit pairs for them (e.g. attention_tiled_2d_ctx_prologue.cpp still hard-codes context_len = seq_len - cur_batch_q_len). The default mask is unchanged, so Python/C++ byte-identity still holds; until the mirror lands the engines diverge on the new variants, whose Python IR is pinned only by the platform golden cases. Dense has no C++ mirror.
    • On arches with no top-left kernel (gfx942 / gfx1250) the legacy equal-length shortcut remains: top-left is served by the bottom-right body, correct only when every sequence has q_len == kv_len. gfx942 / gfx1250 tiled kernels remain causal-only; dense window/lookahead at bottom-right alignment with sq != sk; pre-existing 2D tiled ALiBi + sliding-window NaN at bottom-right.

🤖 Generated with Claude Code

@github-actions github-actions Bot added documentation project: hip-kernel-provider rocke-lib: attention Touches rocKE library attention/FMHA kernels labels Oct 5, 2026
@therock-pr-bot

therock-pr-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

therock-pr-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

@AnaghaRaoAMD
AnaghaRaoAMD requested a review from dlangbe October 7, 2026 19:32
@AnaghaRaoAMD
AnaghaRaoAMD marked this pull request as ready for review October 8, 2026 22:32
@AnaghaRaoAMD
AnaghaRaoAMD requested review from a team as code owners October 8, 2026 22:32

@dlangbe dlangbe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the new mask bodies have no spec→IR coverage. KERNEL_AUTHORING.md "Compliance & hard invariants" (1) requires library attention emission changes to be mirrored in the C++ engine (platform/cpp/instances/ carries the unified and tiled 2D/3D bodies), with .py/.c emit pairs per config. this PR touches nothing under platform/ or library/tests/parity/:

  • grep -rn "causal_top_left\|right_bound" platform/ library/tests/parity/ returns nothing.
  • attention_tiled_2d_ctx_prologue.cpp:334 still hard-codes context_len = seq_len - cur_batch_q_len.

the platform golden only holds default-mask cases, and deeab72 dropped the library golden. so the _tl / _rbu / _rb<R> / non-causal-window IR on 2D, 3D, scalar and dense is pinned by nothing. the next refactor of any mask site can move it, and only a GPU lane would notice. separately, the risk assessment still says default-off IR is "pinned byte-identical by a new golden", which no longer matches the testing section.

either add the C++ mirror plus emit-pair configs (tl, rbu, rb, left-only window) to gfx950_attention_tiled_{2d,3d}_emit and attention_unified_emit, or at minimum add those variants as representative-IR golden cases and list the C++ mirror as an explicit follow-up in the PR body so the divergence between the two engines is tracked.

@AnaghaRaoAMD
AnaghaRaoAMD requested a review from a team as a code owner October 12, 2026 20:32
@github-actions github-actions Bot added the rocke: platform Touches rocKE platform label Oct 12, 2026
@AnaghaRaoAMD
AnaghaRaoAMD force-pushed the users/anarao/aick-2505-top-left-causal-coverage branch 3 times, most recently from 6d15053 to c2bb6b2 Compare October 13, 2026 16:09
@AnaghaRaoAMD
AnaghaRaoAMD requested a review from dlangbe October 13, 2026 16:37
@AnaghaRaoAMD
AnaghaRaoAMD force-pushed the users/anarao/aick-2505-top-left-causal-coverage branch from c2bb6b2 to 0df4cc2 Compare October 14, 2026 17:35
@therock-pr-bot

Copy link
Copy Markdown

Pre-commit check failed

⛔ pre-commit failed

Please run locally:

  • python -m pip install pre-commit
  • pre-commit install
  • pre-commit run --all-files --show-diff-on-failure

This repo uses .pre-commit-config.yaml.

@AnaghaRaoAMD
AnaghaRaoAMD force-pushed the users/anarao/aick-2505-top-left-causal-coverage branch from 4597af4 to e08e170 Compare October 14, 2026 23:51

@cgmillette cgmillette left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR #13125 — top-left causal and attention band coverage on gfx950 (AnaghaRaoAMD, AICK-2505) — 🟢 ACCEPT: thorough; gfx942 lane first

Prior item Status
dlangbe: new mask IR unpinned; C++ mirror required 🟡 PARTIAL — 26 golden cases match ×3 flavors (ran); C++ mirror deferred, no ticket
dlangbe: unified equal-length top-left fold 🟢 FIXED — fold only for dense; gfx950 TL → _tl (ran)
dlangbe: dense empty q-blocks read next batch 🟢 FIXED — start tile clamped + rows zeroed; band matrix at batch=2
dlangbe: stale NO_MASK test comment 🟢 FIXED — scoped to gfx942/gfx1250
yraparti: one normalized band 🟢 FIXED — normalize_band → AttentionBand
yraparti: band index truth tables 🟢 FIXED — unified + dense truth tables (GPU)
yraparti: NO_MASK arch-dependent / silently causal 🟡 PARTIAL — gfx950 exact; gfx942/gfx1250 legacy causal (documented; #13211)
yraparti: RAG_KBOUND missing in window loops ⚪ Unreachable — spec rejects ragged + window (ran); now commented
yraparti: tuning band validity / cache keys 🟡 PARTIAL — identity/keys + gfx942 decline tested; window/tile validity untested
yraparti: d256 names, sw suffix, loose inputs (×8) 🟢 FIXED — suffixes present; bad alignment/window/mixed vocab rejected (ran)
Bots / CI 🟡 Pre-commit green; TheRock green at a7b95c3a, head pending; gfx942 GPU lane unrun
Our checks 🟢 Merge clean; default-off IR identical; no PR regressions (ran)

| # | Sev | file:line | Finding |
| yraparti: d256 names, sw suffix, loose inputs (×8) | 🟢 FIXED — suffixes present; bad alignment/window/mixed vocab rejected (ran) |
| Bots / CI | 🟡 Pre-commit green; TheRock green at a7b95c3a, head pending; gfx942 GPU lane unrun |
| Our checks | 🟢 Merge clean; default-off IR identical; no PR regressions (ran) |

# Sev file:line Finding
N1 🟡 dispatch/attention/common.py:720-729 SLIDING_WINDOW+W, default right: gfx950 now non-causal top-left, gfx942/1250 reject — not in Risk (ran)

Utility: 🟢 Positive — exact cuDNN band semantics on gfx950; rejects instead of mis-masking.


Legend: 🔴 blocking · 🟠 should-fix · 🟡 minor nit · 🟢 info/good

…mily does not serve

#13150 builds a unified problem for the gfx1151 / RDNA launch grid. With the
band normalisation that raised for a SLIDING_WINDOW request that carries its
bounds in window_left / window_right. _attention_band now returns the default
mask for those requests, so the problem is only a geometry carrier.

JIRA ID : AICK-2505

Co-Authored-By: Claude <noreply@anthropic.com>
@AnaghaRaoAMD
AnaghaRaoAMD force-pushed the users/anarao/aick-2505-top-left-causal-coverage branch from 3d871e8 to 996c351 Compare October 16, 2026 22:18
@AnaghaRaoAMD
AnaghaRaoAMD merged commit a150f32 into develop Oct 17, 2026
99 checks passed
@AnaghaRaoAMD
AnaghaRaoAMD deleted the users/anarao/aick-2505-top-left-causal-coverage branch October 17, 2026 01:44
BrianHarrisonAMD added a commit that referenced this pull request Oct 17, 2026
…pes report test

Develop's gfx950 band coverage (#13125) makes the registry accept seqlen_q=100, seqlen_k=77. The other declined cases still cover the category.
BrianHarrisonAMD added a commit that referenced this pull request Oct 17, 2026
The tests pinned rocKE's admission decisions, decline text and exact category counts, so a rocKE coverage change (develop #13125) failed them. A small synthetic registry now states the behaviour each case needs; one live-registry smoke checks only tool-owned facts.
BrianHarrisonAMD added a commit that referenced this pull request Oct 17, 2026
… for the gfx950 dense-attention ingestor catalog (#13024)

## Summary

Makes the rocKE dispatcher registry the single source of truth for the
gfx950 dense-attention ingestor catalog
(`hipkernel:Gfx950AttentionDense`, 840 kernels, unchanged), so drift
between the registry and the shipped catalog fails a test. The
IngestorGenerator gates used to maintain the catalog now refuse input
they cannot verify. Builds on #13593.

JIRA ID : AICK-2513

## Risk Assessment

Risk 3. Most of the change is developer tooling plus a build-time
`hkp_pack` pre-flight; the shipped catalog regenerates with no
differences and no engine C++ changes. The rocKE gfx950 dense predicate
gains an LDS-capacity gate and a `block_n=256` tile. The branch is
merged with current develop, whose gfx950 dense kernel changes (#13125)
are packed into this engine, so this PR also carries a gfx950 hardware
run (below).

## ASIC Coverage

gfx950 only. The predicate and tile changes affect the gfx950 dense
catalog; everything else is host-only. Required before merge: PR CI and
one gfx950 run of the dense engine (done at `75c5a107cb`; later commits
change tests only). Other architectures are covered by PR CI: their
catalogs do not change, and CI packs them through the same pre-flight.

## Testing Summary

- **Host (Python):** IngestorGenerator, descriptor-packaging and rocKE
attention suites; dense catalog regeneration from the selection and from
the manifest.
- **Host (C++ and CTest):** superbuild with the CI flags
(`GPU_TARGETS=gfx950`, ROCKE, kernel ingestor, SDPA, packaging probes
ON), provider unit tests with the GPU hidden, and the pack, probe,
census and test-name lanes.
- **gfx950 (MI355X):** dense `SdpaFwd` integration (`quick`, `standard`,
GPU reference) with support claims enforced, gfx950 attention unit
tests, census.

## Testing Checklist

All at this head unless noted, Linux, host tests with
`HIP_VISIBLE_DEVICES=-1`.

- [x] Superbuild, CI flags - `ninja` - 0 warnings - Status: Passed
- [x] IngestorGenerator - `pytest tests` - 1,150 passed, 9 skipped
(flatbuffers headers absent) - Status: Passed
- [x] Descriptor packaging - `pytest descriptor-packaging/tests` - 697
passed, 1 skipped; `TestRealArchiveReaders` also passes without PyYAML -
Status: Passed
- [x] rocKE attention - `pytest tests/test_attention_dense_gfx950_lds.py
tests/test_attention_spec_predicate_parity.py tests/dispatch/attention`
- 623 passed - Status: Passed
- [x] Provider unit tests - `hip_kernel_provider_tests` - 1,087 passed;
`*Gfx950Attention*` 167 of 167 - Status: Passed
- [x] CTest - `ctest -R
'hkp-pack|hkp-probe-|hkp-census-|_test_name_validation'` - 29 of 29 -
Status: Passed
- [x] Dense catalog regeneration - `catalog_diff --strict-spec`
(selection) and `--subset` (manifest) - no differences - Status: Passed
- [x] Installed tree - `rocke_library_attention_cpu_pytest`,
`rocke_library_attention_pytest` - 35 passed; 600 passed - Status:
Passed
- [x] gfx950 hardware - dense `SdpaFwd` `quick` 8, `standard` 45, GPU
reference 45 (0 broken, 0 unclaimed), `*Gfx950Attention*` 167,
`hip_kernel_provider_tests` 1,148, census 10 of 10 - Devices: MI355X -
Status: Passed (at `75c5a107cb`; later commits change tests only)
- [ ] PR CI - GitHub PR checks - Status: Pending

Not covered: the rocKE gfx950 numeric tests
(`rocke_library_attention_gpu_pytest`) need a ROCm torch that no CI
image has; the IngestorGenerator suite runs in no CI job yet.

## Technical Changes

- **Registry as source of truth.**
`configs/gfx950_attention_dense.engine.yaml` (manifest) and
`configs/gfx950_attention_dense.yaml` (selection) replace the
hand-authored profile. `registry_enumerator.py` expands the manifest
through the dispatcher; `test_registry_regeneration.py` fails on drift.
- **Gates refuse what they cannot verify.** `catalog_diff`,
`variant_reduce`, `ground_truth`, `coverage_gate`, `registry_enumerator`
and `generate.py` use exit 0 for pass, 1 for a refusal and 2 for
unusable input (`variant_reduce` adds 3 for an incomplete sweep).
Malformed input, duplicate keys and unmapped spellings exit 2 instead of
passing or tracebacking.
- **gfx950 LDS gate in Python.** `supports_attention_dense` rejects
tiles over the 160 KiB LDS budget, ported from
`Gfx950AttentionDenseGeometry.hpp`; a census test checks that every
shipped kernel's tile passes the engine's C++ check.
- **`hkp_pack` pre-flight.** Every packed rocKE spec is checked by its
builder's support predicate. A builder with no predicate, or a predicate
that raises, fails the pack.
- **Tests guard contracts, not rocKE internals.** Tests outside rocKE
read the shipped catalogs or a synthetic registry instead of rocKE
private names, C++ source text, or rocKE kernel counts and messages, so
rocKE refactors do not break them.
- **Spec-first tiled predicates** (gfx942, gfx950) so `hkp_pack` can
validate tiled specs.

### Breaking changes (IngestorGenerator tooling; see its README)

- `verify_variant_sets.py` and `coverage_gate.py` take `--manifest`
instead of `--profile`; `HIPDNN_INGESTOR_PROFILE*` is renamed
`HIPDNN_INGESTOR_MANIFEST*`.
- `dispatch_parity.py`, `knob_sweep.py`, `reconcile_applicability.py`
and `variant_reachability.py` are removed; the README's *Retired tools*
table lists their replacements.
- The engine manifest uses a new `enumerate:` schema, with `reduction:`
and optional `ground_truth:` sections. Enum values in `enumerate.cells`
must be member names.
- Gates that passed silently now refuse: see the exit codes above.
Ground-truth graph maps written before this change must be regenerated
with `ground_truth.py graphs`.
- `hkp_pack` fails the pack for a rocKE builder with no resolvable
support predicate.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Yaswanth Raparti <yraparti@amd.com>
Co-authored-by: BrianHarrisonAMD <169072757+BrianHarrisonAMD@users.noreply.github.com>
Co-authored-by: Garby Gilbert <ggilbert@amd.com>
Co-authored-by: Brian Harrison <brian.harrison@amd.com>
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

ex-rzr added a commit that referenced this pull request Oct 19, 2026
…-cache-locality

Resolve the gfx950 dense conflicts with #13125: the gqa_pair checks and the
persistent auto rule live in kernels/common here, so develop's right_bound
exclusions move there; keep develop's empty-row guard before the epilogue
decode. Re-bless the three persistent band goldens: two keep develop's
machine code, the lookahead one gets the causal qb_major fold.

#13024 makes the dispatcher registry the source of the gfx950 ingestor
catalog. The C++ geometry launches only the qb_minor grid, so the manifest
now pins the new opt-in candidate gfx950_dense_qbminor; the catalog is
unchanged.
AnaghaRaoAMD added a commit that referenced this pull request Oct 19, 2026
Port the #13125 gfx950 band to the gfx942 tiled bodies so they no longer
serve only the bottom-right causal diagonal:

- causal_top_left: context_len = 0 (top-left diagonal); ALiBi / qq-bias
  offsets follow it, as on gfx950. Mirrored in the C++ twins.
- right_bound: 0 causal, R > 0 lookahead, -1 unbounded, applied at the
  per-score compares, the KV-loop prefix bound, the sliding-window range,
  valid_tail and the causal phase split. Python-only, as on gfx950; the
  pybind 2D/fastkv builders reject it instead of dropping it.
- Name tokens tl / rbu / rb<R>; rejects right_bound with ALiBi / qq-bias.
- The 4-warp GQA bodies take top-left but raise on right_bound != 0.
- gfx950 C++ tiled 2D / fastkv / 3D entry points reject causal_top_left,
  which only their Python bodies implement.
- New top-left parity configs (2D cfg7-9, 3D cfg5-6) gate both engines.

Default-mask names and IR are unchanged. Not routed to yet: the host and
dispatch still gate non-default masks off gfx942.

Gate: gfx942_attention_tiled (2d, 2d_stress, 3d) and gfx950_attention_tiled
(2d, fastkv_regp, 3d) GREEN at llvm20/llvm22/llvm23.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 19, 2026
Mirror the #13125 gfx950 dense changes on gfx942, in both the default and
persistent grids: right_bound (lookahead), non-causal left-only and two-
sided windows, full attention including ragged cross-attention
(seqlen_q != seqlen_kv), and a zero-output guard for rows with no visible
key, emitted only when such rows can exist. Kernel names _full / _causal /
_swa<W> / _rb<R> as on gfx950. A moving bottom-right diagonal, and a window
or lookahead at bottom-right with seqlen_q != seqlen_kv, stay rejected with
a reason. Default dense IR is unchanged (gfx942 dense golden test green).

GPU (gfx942): test_attention_dense_gfx942_numeric 105 passed, including the
band matrix through the spec, persistent and ragged cross-attention.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 19, 2026
Closes the gfx942 known gap left by #13125: gfx942 now implements the same
band as gfx950 (the kernels landed in the previous commits).

- _has_no_mask_kernel covers gfx942: NO_MASK is full attention there (no
  longer the legacy causal body); non-causal bands are admitted instead of
  rejected. gfx1250 remains the known gap.
- Host: gfx942 tiled 2D/3D accept non-default masks; the 4-warp GQA cohorts
  decline right_bound != 0 so those problems take the generic tiled body.
  The spec builder threads causal_top_left / right_bound into every gfx942
  2D (bf16/fp16 flash, generic, 4-warp) and 3D spec.
- dense_pipe serves the band; the gfx942 attention_dense candidate declares
  the dense band features.
- gfx942 live benchmarks and attention_sweep pin BOTTOM_RIGHT_CAUSAL, which
  they relied on the NO_MASK default to mean.
- Parity harness: band reference and --set topleft|nomask|band for gfx942;
  the dense prefill builder takes --right-bound.
- Tests: gfx942 rows in test_unified_mask_wiring flipped to the gfx950
  expectations plus band routing rows; new
  test_attention_unified_mask_gfx942_numeric.py. Docs updated.

Dispatch suite: 359 passed. GPU (gfx942): unified mask numeric green,
including the 4-warp empty-row and D256 rows.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 20, 2026
…-key set

Review follow-up from #13125, where the gfx950 dense kernel read the next
batch's tokens for q-blocks past the keys. gfx942 is not affected: both
grids enter the KV loop through a bounds-checked loop header, so such a
block runs zero tiles (comment added at the start tile; IR unchanged).

- Band rows (direct, D64, dispatched, sinks/LSE) run at batch=2 and require
  rows with no visible key to be exactly 0 in every batch.
- TestDenseBandIndexTruthTable: q = 0, V[k] = e_k, so each output row is
  1/n at exactly the visible keys; 6 bands x aligned / past-the-keys /
  ragged x grid and persistent.

A deliberately injected over-read fails every -empty row and the
past-the-keys truth-table rows, so the tests cover the #13125 bug.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 20, 2026
…overread

Review follow-ups from #13125, for gfx942:
- TestBandIndexTruthTable (2D and 3D): the visible-key set equals the
  literal definition d - k < left and k <= d + right, for causal, windows,
  left-only, two-sided, lookahead and full, both alignments, including rows
  with no visible key.
- TestDispatchedMixedCohort: request -> dispatch -> launch on
  [(512,512),(700,200),(200,700),(64,64)] for top-left causal, a top-left
  window and NO_MASK bands, fp16/bf16, tiled and auto; checks the spec
  carries the band and that the bottom-right body would not match.
- TestBlockTableOverread: the 4-warp bodies stay in-bounds on a padded-free
  block table (child process, since a fault poisons the GPU context).

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 20, 2026
…overage

Review follow-up on #13211: test_attention_unified_mask_gfx942_numeric.py
joins the installed library GPU CTest list and its gfx950 twin from #13125
joins the attention GPU list next to gfx950 dense. The GPU attention
coverage map gains explicit rows for both unified suites and for the
gfx942 dense band additions (batch=2 band matrix, ragged cross-attention,
empty rows, sinks/LSE band, truth table), updated counts, and the
unequal-length gap row now lists the gfx942 cohorts. These suites are
Torch-gated and skip in CI without Torch.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
Port the #13125 gfx950 band to the gfx942 tiled bodies so they no longer
serve only the bottom-right causal diagonal:

- causal_top_left: context_len = 0 (top-left diagonal); ALiBi / qq-bias
  offsets follow it, as on gfx950. Mirrored in the C++ twins.
- right_bound: 0 causal, R > 0 lookahead, -1 unbounded, applied at the
  per-score compares, the KV-loop prefix bound, the sliding-window range,
  valid_tail and the causal phase split. Python-only, as on gfx950; the
  pybind 2D/fastkv builders reject it instead of dropping it.
- Name tokens tl / rbu / rb<R>; rejects right_bound with ALiBi / qq-bias.
- The 4-warp GQA bodies take top-left but raise on right_bound != 0.
- gfx950 C++ tiled 2D / fastkv / 3D entry points reject causal_top_left,
  which only their Python bodies implement.
- New top-left parity configs (2D cfg7-9, 3D cfg5-6) gate both engines.

Default-mask names and IR are unchanged. Not routed to yet: the host and
dispatch still gate non-default masks off gfx942.

Gate: gfx942_attention_tiled (2d, 2d_stress, 3d) and gfx950_attention_tiled
(2d, fastkv_regp, 3d) GREEN at llvm20/llvm22/llvm23.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
Mirror the #13125 gfx950 dense changes on gfx942, in both the default and
persistent grids: right_bound (lookahead), non-causal left-only and two-
sided windows, full attention including ragged cross-attention
(seqlen_q != seqlen_kv), and a zero-output guard for rows with no visible
key, emitted only when such rows can exist. Kernel names _full / _causal /
_swa<W> / _rb<R> as on gfx950. A moving bottom-right diagonal, and a window
or lookahead at bottom-right with seqlen_q != seqlen_kv, stay rejected with
a reason. Default dense IR is unchanged (gfx942 dense golden test green).

GPU (gfx942): test_attention_dense_gfx942_numeric 105 passed, including the
band matrix through the spec, persistent and ragged cross-attention.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
Closes the gfx942 known gap left by #13125: gfx942 now implements the same
band as gfx950 (the kernels landed in the previous commits).

- _has_no_mask_kernel covers gfx942: NO_MASK is full attention there (no
  longer the legacy causal body); non-causal bands are admitted instead of
  rejected. gfx1250 remains the known gap.
- Host: gfx942 tiled 2D/3D accept non-default masks; the 4-warp GQA cohorts
  decline right_bound != 0 so those problems take the generic tiled body.
  The spec builder threads causal_top_left / right_bound into every gfx942
  2D (bf16/fp16 flash, generic, 4-warp) and 3D spec.
- dense_pipe serves the band; the gfx942 attention_dense candidate declares
  the dense band features.
- gfx942 live benchmarks and attention_sweep pin BOTTOM_RIGHT_CAUSAL, which
  they relied on the NO_MASK default to mean.
- Parity harness: band reference and --set topleft|nomask|band for gfx942;
  the dense prefill builder takes --right-bound.
- Tests: gfx942 rows in test_unified_mask_wiring flipped to the gfx950
  expectations plus band routing rows; new
  test_attention_unified_mask_gfx942_numeric.py. Docs updated.

Dispatch suite: 359 passed. GPU (gfx942): unified mask numeric green,
including the 4-warp empty-row and D256 rows.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
…-key set

Review follow-up from #13125, where the gfx950 dense kernel read the next
batch's tokens for q-blocks past the keys. gfx942 is not affected: both
grids enter the KV loop through a bounds-checked loop header, so such a
block runs zero tiles (comment added at the start tile; IR unchanged).

- Band rows (direct, D64, dispatched, sinks/LSE) run at batch=2 and require
  rows with no visible key to be exactly 0 in every batch.
- TestDenseBandIndexTruthTable: q = 0, V[k] = e_k, so each output row is
  1/n at exactly the visible keys; 6 bands x aligned / past-the-keys /
  ragged x grid and persistent.

A deliberately injected over-read fails every -empty row and the
past-the-keys truth-table rows, so the tests cover the #13125 bug.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
…overread

Review follow-ups from #13125, for gfx942:
- TestBandIndexTruthTable (2D and 3D): the visible-key set equals the
  literal definition d - k < left and k <= d + right, for causal, windows,
  left-only, two-sided, lookahead and full, both alignments, including rows
  with no visible key.
- TestDispatchedMixedCohort: request -> dispatch -> launch on
  [(512,512),(700,200),(200,700),(64,64)] for top-left causal, a top-left
  window and NO_MASK bands, fp16/bf16, tiled and auto; checks the spec
  carries the band and that the bottom-right body would not match.
- TestBlockTableOverread: the 4-warp bodies stay in-bounds on a padded-free
  block table (child process, since a fault poisons the GPU context).

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 22, 2026
…overage

Review follow-up on #13211: test_attention_unified_mask_gfx942_numeric.py
joins the installed library GPU CTest list and its gfx950 twin from #13125
joins the attention GPU list next to gfx950 dense. The GPU attention
coverage map gains explicit rows for both unified suites and for the
gfx942 dense band additions (batch=2 band matrix, ragged cross-attention,
empty rows, sinks/LSE band, truth table), updated counts, and the
unequal-length gap row now lists the gfx942 cohorts. These suites are
Torch-gated and skip in CI without Torch.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
Port the #13125 gfx950 band to the gfx942 tiled bodies so they no longer
serve only the bottom-right causal diagonal:

- causal_top_left: context_len = 0 (top-left diagonal); ALiBi / qq-bias
  offsets follow it, as on gfx950. Mirrored in the C++ twins.
- right_bound: 0 causal, R > 0 lookahead, -1 unbounded, applied at the
  per-score compares, the KV-loop prefix bound, the sliding-window range,
  valid_tail and the causal phase split. Python-only, as on gfx950; the
  pybind 2D/fastkv builders reject it instead of dropping it.
- Name tokens tl / rbu / rb<R>; rejects right_bound with ALiBi / qq-bias.
- The 4-warp GQA bodies take top-left but raise on right_bound != 0.
- gfx950 C++ tiled 2D / fastkv / 3D entry points reject causal_top_left,
  which only their Python bodies implement.
- New top-left parity configs (2D cfg11-13, 3D cfg18) gate both engines.
- test_unified_lse_dispatch: re-pin gfx942's pre-LSE split-KV identity; its
  config_key / spec_hash move with the band fields the tiled specs gain.

Default-mask names and IR are unchanged. Not routed to yet: the host and
dispatch still gate non-default masks off gfx942.

Gate: gfx942_attention_tiled (2d, 2d_stress, 3d) and gfx950_attention_tiled
(2d, fastkv_regp, 3d) GREEN at llvm20/llvm22/llvm23.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
Mirror the #13125 gfx950 dense changes on gfx942, in both the default and
persistent grids: right_bound (lookahead), non-causal left-only and two-
sided windows, full attention including ragged cross-attention
(seqlen_q != seqlen_kv), and a zero-output guard for rows with no visible
key, emitted only when such rows can exist. Kernel names _full / _causal /
_swa<W> / _rb<R> as on gfx950. A moving bottom-right diagonal, and a window
or lookahead at bottom-right with seqlen_q != seqlen_kv, stay rejected with
a reason. Default dense IR is unchanged (gfx942 dense golden test green).

GPU (gfx942): test_attention_dense_gfx942_numeric 105 passed, including the
band matrix through the spec, persistent and ragged cross-attention.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
Closes the gfx942 known gap left by #13125: gfx942 now implements the same
band as gfx950 (the kernels landed in the previous commits).

- _has_no_mask_kernel covers gfx942: NO_MASK is full attention there (no
  longer the legacy causal body); non-causal bands are admitted instead of
  rejected. gfx1250 remains the known gap.
- Host: gfx942 tiled 2D/3D accept non-default masks; the 4-warp GQA cohorts
  decline right_bound != 0 so those problems take the generic tiled body.
  The spec builder threads causal_top_left / right_bound into every gfx942
  2D (bf16/fp16 flash, generic, 4-warp) and 3D spec.
- dense_pipe serves the band; the gfx942 attention_dense candidate declares
  the dense band features.
- gfx942 live benchmarks and attention_sweep pin BOTTOM_RIGHT_CAUSAL, which
  they relied on the NO_MASK default to mean.
- Parity harness: band reference and --set topleft|nomask|band for gfx942;
  the dense prefill builder takes --right-bound.
- Tests: gfx942 rows in test_unified_mask_wiring flipped to the gfx950
  expectations plus band routing rows; new
  test_attention_unified_mask_gfx942_numeric.py. Docs updated.

Dispatch suite: 359 passed. GPU (gfx942): unified mask numeric green,
including the 4-warp empty-row and D256 rows.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
…-key set

Review follow-up from #13125, where the gfx950 dense kernel read the next
batch's tokens for q-blocks past the keys. gfx942 is not affected: both
grids enter the KV loop through a bounds-checked loop header, so such a
block runs zero tiles (comment added at the start tile; IR unchanged).

- Band rows (direct, D64, dispatched, sinks/LSE) run at batch=2 and require
  rows with no visible key to be exactly 0 in every batch.
- TestDenseBandIndexTruthTable: q = 0, V[k] = e_k, so each output row is
  1/n at exactly the visible keys; 6 bands x aligned / past-the-keys /
  ragged x grid and persistent.

A deliberately injected over-read fails every -empty row and the
past-the-keys truth-table rows, so the tests cover the #13125 bug.

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
…overread

Review follow-ups from #13125, for gfx942:
- TestBandIndexTruthTable (2D and 3D): the visible-key set equals the
  literal definition d - k < left and k <= d + right, for causal, windows,
  left-only, two-sided, lookahead and full, both alignments, including rows
  with no visible key.
- TestDispatchedMixedCohort: request -> dispatch -> launch on
  [(512,512),(700,200),(200,700),(64,64)] for top-left causal, a top-left
  window and NO_MASK bands, fp16/bf16, tiled and auto; checks the spec
  carries the band and that the bottom-right body would not match.
- TestBlockTableOverread: the 4-warp bodies stay in-bounds on a padded-free
  block table (child process, since a fault poisons the GPU context).

Co-Authored-By: Claude <noreply@anthropic.com>
AnaghaRaoAMD added a commit that referenced this pull request Oct 28, 2026
…overage

Review follow-up on #13211: test_attention_unified_mask_gfx942_numeric.py
joins the installed library GPU CTest list and its gfx950 twin from #13125
joins the attention GPU list next to gfx950 dense. The GPU attention
coverage map gains explicit rows for both unified suites and for the
gfx942 dense band additions (batch=2 band matrix, ragged cross-attention,
empty rows, sinks/LSE band, truth table), updated counts, and the
unequal-length gap row now lists the gfx942 cohorts. These suites are
Torch-gated and skip in CI without Torch.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants