Skip to content

[ck_tile/fmha] Fix sink un-mask under right-window and emit fp8bf16 batch_prefill sink kernels - #3732

Closed
jundaf2 wants to merge 3 commits into
ROCm:developfrom
jundaf2:add_batch_prefill_swa_ck_try
Closed

[ck_tile/fmha] Fix sink un-mask under right-window and emit fp8bf16 batch_prefill sink kernels#3732
jundaf2 wants to merge 3 commits into
ROCm:developfrom
jundaf2:add_batch_prefill_swa_ck_try

Conversation

@jundaf2

@jundaf2 jundaf2 commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Two related fixes to ck_tile FMHA so that StreamLLM-sink + sliding-window
batch-prefill works correctly for fp8 KV / bf16 compute.

Review the commits in this order:

  1. fmha: emit sink kernels for fp8bf16 batch_prefill
    Extends example/ck_tile/01_fmha/codegen/ops/fmha_batch_prefill.py so
    the fp8(KV) / bf16(QO) batch-prefill codegen also emits the
    mask=mask_enum::generic_with_sink variant. Without this the runtime
    could not dispatch to a sink-aware kernel for the fp8bf16 path.

  2. fmha: respect right-window in IsOutOfSinkBound
    The sink un-mask in GenericAttentionMask::IsOutOfSinkBound (local-mask
    branch) used (i_y + x) > 1 as the gate, which conditioned on the row
    index instead of the column index. As a result, queries 1..sink-1
    could attend to future sink positions (violating causal / right-window),
    while query 0 fell back to the plain causal mask. The fix replaces the
    guard with i_x < i_y + x so every query only sees sink columns up to
    its own right-window boundary.

  3. fmha: clarify IsOutOfSinkBound predicate comment
    Doc-only follow-up that rewrites the comment above the predicate as a
    clause-by-clause explanation (i_x < sink, i_x < i_y + x,
    y < y_total, i_y < x_total).

Test plan

  • Repro on aiter op_tests/test_batch_prefill.py (fp8 + bf16_dequant
    modes with sink=4, win_left=1023, softcap=0.0, sal=True)
    now passes for all parametrized shapes.
  • Existing fp16/bf16 batch-prefill paths (no sink) unchanged — codegen
    diff only adds the generic_with_sink variant for fp8bf16; existing
    kernel object lists unaffected.

jundaf2 added 3 commits April 27, 2026 19:27
Add F_sink ∈ {t,f} to the fp8bf16 codegen loop so that fp8bf16 +
kv_blockscale variants also produce kernel instances supporting
StreamLLM sink token. The underlying qr_async pipeline already gates
sink logic via constexpr kHasSink, so this only widens the dispatch
table; non-sink callers keep using the existing _nsink_* blobs.

Made-with: Cursor
The previous sink un-mask predicate ((i_y + x) > 1) gated on the query
row index instead of the key column, with two consequences:

  - For causal masking (x = 1) and sink_size = S, queries 1..S-1
    attended to their own future sink positions (i_x in (i_y, sink)),
    breaking autoregressive correctness.
  - Query 0 was *excluded* from sink un-mask entirely and fell back to
    the plain causal mask, so it could not attend to any sink position
    other than column 0.

Replace the row-side guard with the column-side bound (i_x < i_y + x),
which lets sink un-mask precisely those sink columns that lie inside
the query's causal/right-window past, restoring StreamLLM semantics.

Made-with: Cursor
Replace the historical fix-rationale note above the sink un-mask check
with a clause-by-clause explanation of i_x < sink, i_x < i_y + x,
y < y_total, and i_y < x_total so future readers can map the predicate
to the StreamLLM sink + sliding-window semantics directly.

Co-authored-by: AI Coding Agent
Made-with: Cursor

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.

Pull request overview

Fixes ck_tile FMHA StreamLLM sink behavior for sliding-window batch-prefill with fp8 KV / bf16 compute by aligning codegen + masking logic so sink-aware kernels are emitted and respect the right-window boundary.

Changes:

  • Correct IsOutOfSinkBound sink un-mask gating to respect the per-row right-window bound (i_x < i_y + x) instead of a row-index-based predicate.
  • Update SimplifiedGenericAttentionMask to apply the same corrected sink un-mask condition.
  • Extend fp8bf16 batch-prefill codegen to emit both has_sink variants (F_sink = t/f) so runtime dispatch can select sink-aware kernels.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
include/ck_tile/ops/fmha/block/block_masking.hpp Fixes sink un-mask predicate to respect right-window/causality; updates and expands explanatory comments; mirrors fix in simplified mask.
example/ck_tile/01_fmha/codegen/ops/fmha_batch_prefill.py Emits fp8bf16 batch-prefill pipelines with F_sink variants to enable dispatch to sink-aware kernels.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +250 to +251
// to look at later sink rows than they should under
// causality / right-window.

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

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

In the sink un-mask predicate explanation, the text says queries could look at later "sink rows". Since i_x is the key column index here, this should refer to later sink columns/positions (keys), not rows, to avoid confusion when reasoning about causal/right-window behavior.

Suggested change
// to look at later sink rows than they should under
// causality / right-window.
// to look at later sink columns/positions (keys)
// than they should under causality / right-window.

Copilot uses AI. Check for mistakes.
@DDEle

DDEle commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Reopen as ROCm/rocm-libraries#6914

@DDEle DDEle closed this Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants