Skip to content

fix(rocke): name seqlen and tile when dense attention rejects a partial tile - #14335

Merged
cgmillette merged 6 commits into
developfrom
users/ysoliman/rocke/dense-partial-tile-reason
Nov 4, 2026
Merged

cgmillette merged 6 commits into
developfrom
users/ysoliman/rocke/dense-partial-tile-reason

Conversation

@yassinsolim

@yassinsolim yassinsolim commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Replaces #13681 with the same commit (1b17bab). GitHub closed #13681 when its branch moved to users/ysoliman/rocke/ for the rocKE branch-naming rule, and a PR cannot be reopened once its branch is renamed. The review history, including the rocKE checklist reviews, stays on #13681.

Carved out of #12928, which is closed. The rest of that PR is already on develop (#12710 landed the nhead_k guard, #12719 replaced the factories this touched and routes _request_errors through every dense candidate).

Motivation

The dense _base_spec factories set ragged=True for any self-attention length that is not a tile multiple, so Sq = Skv = 384 or 1152 at block_m 256 is an ordinary graph taking the on-chip ragged path. The gfx942 predicate then declined with "gfx942 attention_dense: ragged not yet supported" and the shared spec validator with "ragged is not supported with sliding_window". Both read as a varlen problem and name nothing the caller can act on. Found while running the hipDNN kernel-integration runbook on gfx942.

Technical details

  • kernels/common/attention_dense_spec.py: new partial_tile_reason(spec) names the length and the tile, for example "seqlen_q 384 is not a multiple of block_m 256". The sliding-window branch of __post_init__ now says "sliding_window needs whole tiles: (the partial-tile path has no window mask)".
  • kernels/gfx942/attention_dense.py: supports_attention_dense says "gfx942 attention_dense needs whole tiles: (the partial-tile path is not yet supported)".
  • Varlen messages are unchanged.

What could break: anything matching the old "ragged not yet supported" or "ragged is not supported with sliding_window" text. A repo grep for those two strings finds only the two lines this PR rewrites, and that was not enough. One test matched on less than the whole string: tests/dispatch/attention/test_unified_mask_wiring.py asserted the substring "ragged" in the gfx950 window refusal, and this branch broke it. It is now test_partial_tile_window_is_declined_not_served and checks the length, the tile and the window, the same way the gfx942 and gfx950 wiring tests do. Anything outside this repo that keys on the word "ragged" has the same exposure.

Test plan and result

Host only, no GPU, Windows Python 3.12, from dnn-providers/hip-kernel-provider/rocke/library with library and platform/python on PYTHONPATH.

  • tests/dispatch/attention plus tests/test_attention_dense_gfx942.py at head 1b17babac3: 882 passed, 121 skipped, 3296 subtests passed. The merge base, develop at 28af48c, gives 882 passed, 121 skipped, 3293 subtests; the 3 extra subtests are the new 384 / 1152 / 1000 cases.
  • Negative control: with the two messages reverted, test_rejects_a_partial_tile_and_names_the_length, test_sliding_window_with_partial_tile_rejected_at_dispatch and the gfx942 supports marker all fail.
  • black 25.12.0 --check is clean on the changed files.

Refs #12920.

Submission checklist

Merged develop 3f51737 and updated the three rocke attention wiring tests to match the new refusal message.

yassinsolim and others added 4 commits October 14, 2026 12:19
…clines a partial tile

The dense _base_spec factories set ragged=True for any self-attention length
that is not a tile multiple, so Sq = Skv = 384 or 1152 at block_m 256 is an
ordinary graph that takes the on-chip ragged path. The gfx942 predicate then
declined with "ragged not yet supported" and the shared spec validator with
"ragged is not supported with sliding_window", both of which read as a varlen
problem and name nothing the caller can act on.

partial_tile_reason(spec) names the length and the tile. The gfx942 predicate
now says "gfx942 attention_dense needs whole tiles: seqlen_q 384 is not a
multiple of block_m 256 (the partial-tile path is not yet supported)" and the
sliding-window check says "sliding_window needs whole tiles: <reason> (the
partial-tile path has no window mask)". Varlen messages are unchanged.

What could break: anything matching the old "ragged not yet supported" or
"ragged is not supported with sliding_window" text. No other caller in the
repo matches either string.

Checked host only, no GPU: tests/dispatch/attention plus
tests/test_attention_dense_gfx942.py give 752 passed, 75 skipped, 2600
subtests passed. With the two messages reverted, the three updated tests fail.
black 25.12.0 --check is clean on the changed files.
…in the unified mask tests

The sliding_window branch of AttentionDenseSpec.__post_init__ no longer says
"ragged", so test_ragged_window_is_declined_not_served asserted text that this
branch removed. It now checks the same three parts the gfx950 and gfx942 wiring
tests check: the query length against block_m, the key length against block_n,
and that the reason still names sliding_window and no longer says ragged.
@therock-pr-bot

therock-pr-bot Bot commented Oct 23, 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

Copy link
Copy Markdown

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

Copilot AI 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.

🟢 Approval recommended

The diagnostic-only changes preserve rejection behavior and include focused regression coverage, with no unresolved blocking issues.

No open issues 🎉

What changed in this PR

This PR makes rocKE dense-attention rejection messages actionable by naming sequence lengths and tile sizes instead of describing ordinary partial-tile inputs as “ragged.” Existing rejection conditions and varlen messages remain unchanged.

Changes:

  • Adds a shared helper that explains which sequence lengths are not tile multiples.
  • Updates gfx942 and sliding-window rejection messages to use that explanation.
  • Expands regression assertions for partial-tile diagnostics through dispatch and kernel support checks.
File Description
dnn-providers/​hip-kernel-provider/​rocke/​library/​tests/​test_attention_dense_gfx942.py Checks the specific length-and-tile rejection message.
dnn-providers/​hip-kernel-provider/​rocke/​library/​tests/​dispatch/​attention/​test_unified_mask_wiring.py Verifies partial-tile window refusals identify both lengths and tiles.
dnn-providers/​hip-kernel-provider/​rocke/​library/​tests/​dispatch/​attention/​test_gfx950_dense_wiring.py Updates sliding-window diagnostic assertions.
dnn-providers/​hip-kernel-provider/​rocke/​library/​tests/​dispatch/​attention/​test_gfx942_dense_wiring.py Covers multiple partial-tile lengths and omits aligned dimensions from diagnostics.
dnn-providers/​hip-kernel-provider/​rocke/​library/​kernels/​gfx942/​attention_dense.py Uses the shared explanation for partial-tile rejection.
dnn-providers/​hip-kernel-provider/​rocke/​library/​kernels/​common/​attention_dense_spec.py Adds the diagnostic helper and updates sliding-window validation wording.

Review effort: Balanced

@cgmillette

Copy link
Copy Markdown
Contributor

Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max

PR #14335 — name seqlen and tile when dense attention rejects a partial tile (yassinsolim) — 🟢 First-round: no closer look needed — wording-only; every verdict matches develop; the red summaries are cancelled duplicate runs

Prior item Status
Copilot (10-14 on #13681 at 938a7683; 10-23 here at 1b17baba): overviews only, no findings; "rejection conditions and varlen messages remain unchanged" 🟢 Confirmed — a probe over 376 cases gives the same accept/reject on develop and on the merge; only the two rewritten messages change (ran; see Our checks). This is the only review on this PR
yraparti (10-19 at 7d9983a5, re-review 10-20 at 1b17baba, on #13681) rocKE checklist §F.2 HIGH: move the branch onto a name with a rocke segment 🟢 FIXED — the head branch is now users/ysoliman/rocke/dense-partial-tile-reason. That rename closed #13681 and opened this PR with the same commit (read)
yraparti §F.3 MEDIUM: retitle as type(scope): summary, 10–80 characters, scope [a-z0-9-]+ 🟢 FIXED — #13681 was retitled on 10-23, before the move here, from a 90-character title to today's fix(rocke): name seqlen and tile …, 76 characters, scope rocke. The checklist's NEEDS-INFO rows are verdicts it could not tie to a diff line, or context it lacked; none asks for a change (read)
Bots / CI 🟢 Policy bot pass. CI ran at 1b17baba on 10-23, 409 commits behind today's develop. Every run that went to completion passed: TheRock Multi-Arch CI (29 jobs passed, none failed), hipDNN Superbuild (Linux and Windows), Component CI, pre-commit and clang-tidy; the ASAN workflow selected no jobs. hipkernelprovider ran on Linux gfx94X and Windows gfx110X, 2 shards each, 41/41 ctests, and the three changed dispatch wiring tests PASSED in every shard (rocke_library_attention_pytest).
• The two red checks, Multi-Arch CI Summary and Multi-Arch CI ASAN Summary, come from duplicate runs that started with the PR and were cancelled within two seconds. Their summary jobs failed only because ci-env / configure and setup were cancelled; the surviving runs' summaries passed → unrelated to this PR.
• The same commit's 10-20 run under #13681 passed on its second attempt. Attempt 1 hit a Windows rocke_pytest timeout in test_hip_device_properties_layout and a gfx94X packaging test, both outside this PR.
• test_attention_dense_gfx942.py is in no CTest lane (pre-existing), so its one changed assertion runs only locally; test_rejects_a_partial_tile_and_names_the_length pins the same gfx942 message in CI (read)
Our checks 🟢
• Clean merge with develop f22bed43 (409 behind, 4 ahead). Develop edited five of the six files since the base (#12714, #13802), and all five auto-merged. Native build and 33 ctests OK (1 skip, the arch-domain reproduction gate); C++/Python library parity passes at llvm20/22/23; differential golden OK at llvm20/22/23/24 and canonical, with 0 unblessed changes and 0 missing (the NEW configs are develop's, as no emitter changes here); the PR's four test files on the merge: 476 passed, 214 subtests (ran).
• Only the wording changes. A probe ran 376 cases on develop and on the merge: 176 shared-spec constructions, 60 gfx942 predicate calls, and 140 pinned admits calls across all five attention_dense* candidates on gfx942 and gfx950, through the spec factories and _request_errors. Accept/reject is identical in all 376, and the 132 changed messages all come from the two rewritten sites. A query-only, KV-only or two-length partial tile names exactly the failing length(s), and a hand-set ragged=True on whole tiles says so. The non-ragged messages (seqlen_q must be a multiple of block_m=…) are unchanged (ran); the varlen ones are untouched (read).
• No semantic drift since the base. gfx942 still has no partial-tile path on develop (supports_attention_dense rejects ragged, and its docstring still lists ragged as a later follow-up), and the shared validator still rejects a partial tile with a window on every arch, so both new messages hold. On develop the old strings occur only at the two lines rewritten here. The only rocKE tests on develop keyed on "ragged" are the three this PR updates and test_attention_dense_bwd.py:260, which checks the separate backward spec (read).
• Rules 1–3 clean (ran); no links added (read)

Net-new: none.

Utility: 🟢 Positive — refusals name the failing length and tile, not "ragged"; verdicts unchanged.


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

First-round review: a local qwen3.6 model made the independent first pass. The orchestrator (Claude Opus 5.5) verified it. On a clean merge with today's develop, it ran the native build and ctests, the C++/Python library parity, the differential goldens and the PR's four test files, plus a probe that compares every accept/reject verdict and message with develop's. It also checked develop's changes since the PR's base for drift, read the predecessor #13681's reviews, and read the CI jobs at head, including the two cancelled duplicate runs. The orchestrator owns this merge-worthiness call. It flags whether a closer look is needed; it is not an approval or a rejection.

@AnaghaRaoAMD AnaghaRaoAMD 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.

Merged into current develop (43e2cb7aa47), this branch fails 14 tests in the files it touches, while develop alone passes all 558. #14367 merged after this branch's base (28af48c) and made the dense block_m depend on the shape, so some shapes now build at 128. Because of that, the hardcoded block_m 256 expectations no longer hold, and gfx942 now accepts Sq = Skv = 384. CI here is green because it ran on the old base. The source change still applies cleanly and is still needed, since both old messages are still on develop. It needs a develop merge and test updates (details inline).

…l-tile tests

Develop now builds these requests at block_m 128 instead of 256, so the
hardcoded 256 and the Sq = Skv = 384 case no longer hold. The gfx942 test reads
block_m and block_n from the default spec, the gfx950 tests parse them from the
refusal message, and the 384 case is dropped since a 128-row tile accepts it.
@cgmillette
cgmillette enabled auto-merge (squash) November 4, 2026 15:55
@cgmillette

Copy link
Copy Markdown
Contributor

Automated review: Model - qwen3.6:35b-a3b-coding-mtp-q4_K_M, effort: max

PR #14335 — name seqlen and tile when dense attention rejects a partial tile (yassinsolim) — 🟠 Follow-up: no test pins the tile

Prior item Status
AnaghaRaoAMD (11-04) 12 gfx950 window subtests fail since #14367 🟢 FIXED a630f00a83
• all 12 pass on today's develop; no hard-coded 256 (ran)
• tile now read from the refusal itself: N1
• AnaghaRaoAMD caught this before our checks; resolved by cgmillette
AnaghaRaoAMD (11-04) gfx950 dense block_m 256 assert fails 🟢 FIXED a630f00a83
• passes on today's develop; no hard-coded 256 (ran)
• same refusal-read tile: N1
• resolved by cgmillette
AnaghaRaoAMD (11-04) gfx942 accepts 384; 1152/1000 hard-code 256 🟢 FIXED a630f00a83
• 384 dropped; tile read from _base_spec; passes (ran)
• 1152 = 9 × 128: breaks again at a 128-row pick (ran)
• resolved by cgmillette
cgmillette (10-29), BrianHarrisonAMD (11-04) approvals 🟢 APPROVED 1b17babac3
• older head; still counts on develop
• not the a630f00a83 test rewrite; source unchanged (read)
Copilot (10-23), ours (10-29): wording only, verdicts unchanged 🟢 Confirmed a630f00a83
• source patch identical to 1b17babac3 (read)
• only the tests' hard-coded 256 broke when develop moved
yraparti (on #13681) §F.2 branch name, §F.3 title 🟢 FIXED
• both still hold at head (read)
Bots / CI 🟢 Green
• 46 ✓ · 51 skipped; 4 required ✓ (read)
• 3 changed wiring files ran in all 4 rocKE shards: 170 ✓ (read)
• merge: blocked on rocke-lib code-owner review; squash auto-merge armed
Our checks 🟢 Clean
• merge vs today's fccc13fa33 clean; PR tests 558 ✓, 228 subtests (ran)
• 961dd76390 merge: build + 46 ctests, parity 2 ✓ ×4, goldens OK (ran)
• installed: 3 of 4 files, 170 ✓; test_attention_dense_gfx942.py in no CTest entry, as on develop (ran)
• rules 1–3 clean (ran); body and armed squash message still cite 1b17babac3 and 384 (read)
Code quality 🟠 Should-fix
• a constant 256x64 tile passes all 558 tests: N1 (ran)
• exported helper misreports a non-ragged spec: N2 (ran)
• test_attention_dense_gfx942.py:853 restates the imported _BLOCK_M (read)
• tile parse copied at test_unified_mask_wiring.py:382; pairs come from the catalogue (read)
# Sev file:line Finding
N1 🟠 library/tests/dispatch/attention/test_gfx950_dense_wiring.py:634 No test checks which tile the refusal names
• impact: a helper always naming 256x64 passes all 558 (ran); here and test_unified_mask_wiring.py:382 the tile comes from the refusal
• fix: gfx950: expect the refused spec's tile (spy on partial_tile_reason); gfx942 :220: add 500 (128 rows), 1088 for 1152 (ran)
N2 🟡 library/kernels/common/attention_dense_spec.py:69 Exported helper says ragged=True for a non-ragged spec
• impact: a whole-tile 2048 spec gets "ragged=True at seqlen_q 2048 …"; no test covers this text (ran)
• fix: raise ValueError unless spec.ragged (breaks no test, ran); test a hand-set ragged=True on whole tiles

Utility: 🟢 Positive — refusals name the failing length and tile; tests follow develop's picks


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

Follow-up review: first pass by a local qwen3.6 model, verified by the orchestrator (Claude Opus 5.5). Checks: merge with today's develop, build and ctest, library parity, differential goldens, changed tests (source and installed), refusal-tile mutation, CI shard logs, code quality. Flags whether a closer look is needed; not an approval or rejection.

@cgmillette
cgmillette merged commit c6bca3b into develop Nov 4, 2026
99 checks passed
@cgmillette
cgmillette deleted the users/ysoliman/rocke/dense-partial-tile-reason branch November 4, 2026 16:26
JohnUzoka added a commit that referenced this pull request Nov 4, 2026
… spec helpers

Merges origin/develop.

N1. #14335 rewrote the ragged + sliding_window reject: it now names the
length and tile that leave a partial tile (partial_tile_reason). The C port
still said "ragged is not supported with sliding_window", so on develop the
vectors test failed, and a regenerate would have failed the C ctest. Ported
partial_tile_reason and the new text; three cases cover its seqlen_kv-only,
both and whole-tile branches (only seqlen_q was recorded). Vectors
regenerated; the C ctest matches all four.

N2. #14835 added rocke_spec_set_reasonf / ROCKE_SPEC_FAIL and rocke_floor_div
to helpers/spec. The port's local reject() and py_floordiv() are gone: 58
rejects use ROCKE_SPEC_FAIL and the three floor divisions rocke_floor_div.
rocke_spec_set_reasonf now marks a cut reason with "..." like
rocke_spec_set_reason, as its header already promised ("same truncation").

Nit: the header's ZeroDivisionError note no longer quotes one CPython 3.12
text for both operators.
cycheng pushed a commit that referenced this pull request Nov 6, 2026
…al tile (#14335)

Replaces #13681 with the same commit (1b17bab). GitHub closed #13681
when its branch moved to `users/ysoliman/rocke/` for the rocKE
branch-naming rule, and a PR cannot be reopened once its branch is
renamed. The review history, including the rocKE checklist reviews,
stays on #13681.

Carved out of #12928, which is closed. The rest of that PR is already on
develop (#12710 landed the nhead_k guard, #12719 replaced the factories
this touched and routes `_request_errors` through every dense
candidate).

## Motivation

The dense `_base_spec` factories set `ragged=True` for any
self-attention length that is not a tile multiple, so Sq = Skv = 384 or
1152 at block_m 256 is an ordinary graph taking the on-chip ragged path.
The gfx942 predicate then declined with "gfx942 attention_dense: ragged
not yet supported" and the shared spec validator with "ragged is not
supported with sliding_window". Both read as a varlen problem and name
nothing the caller can act on. Found while running the hipDNN
kernel-integration runbook on gfx942.

## Technical details

- `kernels/common/attention_dense_spec.py`: new
`partial_tile_reason(spec)` names the length and the tile, for example
"seqlen_q 384 is not a multiple of block_m 256". The sliding-window
branch of `__post_init__` now says "sliding_window needs whole tiles:
<reason> (the partial-tile path has no window mask)".
- `kernels/gfx942/attention_dense.py`: `supports_attention_dense` says
"gfx942 attention_dense needs whole tiles: <reason> (the partial-tile
path is not yet supported)".
- Varlen messages are unchanged.

What could break: anything matching the old "ragged not yet supported"
or "ragged is not supported with sliding_window" text. A repo grep for
those two strings finds only the two lines this PR rewrites, and that
was not enough. One test matched on less than the whole string:
`tests/dispatch/attention/test_unified_mask_wiring.py` asserted the
substring "ragged" in the gfx950 window refusal, and this branch broke
it. It is now `test_partial_tile_window_is_declined_not_served` and
checks the length, the tile and the window, the same way the gfx942 and
gfx950 wiring tests do. Anything outside this repo that keys on the word
"ragged" has the same exposure.

## Test plan and result

Host only, no GPU, Windows Python 3.12, from
`dnn-providers/hip-kernel-provider/rocke/library` with `library` and
`platform/python` on PYTHONPATH.

- `tests/dispatch/attention` plus `tests/test_attention_dense_gfx942.py`
at head `1b17babac3`: 882 passed, 121 skipped, 3296 subtests passed. The
merge base, develop at 28af48c, gives 882 passed, 121 skipped, 3293
subtests; the 3 extra subtests are the new 384 / 1152 / 1000 cases.
- Negative control: with the two messages reverted,
`test_rejects_a_partial_tile_and_names_the_length`,
`test_sliding_window_with_partial_tile_rejected_at_dispatch` and the
gfx942 `supports` marker all fail.
- black 25.12.0 `--check` is clean on the changed files.

Refs #12920.

## Submission checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.


Merged develop 3f51737 and updated the three rocke attention wiring
tests to match the new refusal message.
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

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.

5 participants