Skip to content

feat: lower SDPA-with-sinks blocks in the native Expr compiler - #194

Merged
ausimian merged 1 commit into
feat/expr-compilerfrom
feat/expr-compiler-sdpa-sinks
Jun 6, 2026
Merged

feat: lower SDPA-with-sinks blocks in the native Expr compiler#194
ausimian merged 1 commit into
feat/expr-compilerfrom
feat/expr-compiler-sdpa-sinks

Conversation

@ausimian

@ausimian ausimian commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the final cluster on #188 — the two gpt-oss attention-sink blocks reachable from Emily.Fast.attention_with_sinks.

Two new opcodes:

  • FastSDPASinks (121) — operands [q, k, v, sinks]; iattrs [[scale_bits], [causal]]. Dispatches mx::fast::scaled_dot_product_attention(q, k, v, scale, mask_mode, nullopt, optional(sinks), s) with mask_mode toggled between "causal" and "" by the iattr — same shape as Emily.Backend.fast_scaled_dot_product_attention_with_sinks/6.
  • FastSDPAMaskSinks (122) — operands [q, k, v, mask, sinks]; iattrs [[scale_bits]]; mask_mode = "array". Mirrors Emily.Backend.fast_scaled_dot_product_attention_with_mask_and_sinks/7.

Both reuse the existing mx::fast::scaled_dot_product_attention entry point — the same kernel FastSDPA / FastSDPAMask already use — so the native and evaluator paths land on the same bits.

Probe (scripts/expr_op_coverage.exs) is unchanged at 2 misses — those are the unlowerable-by-design count_leading_zeros / population_count. The sinks blocks aren't Nx-public ops so the probe doesn't surface them, but with this PR every cluster on #188 is empty.

Test plan

  • mix precommit clean (730 tests, 79 properties, 40 doctests, 0 failures — 3 new equivalence tests).

  • New equivalence tests in compiler_equivalence_test.exs cover the three reachable combinations:

    • Sinks-only, non-causalEmily.Fast.scaled_dot_product_attention(q, k, v, sinks: s).
    • Sinks-only, causal — adds causal: true.
    • Mask + sinksEmily.Fast.scaled_dot_product_attention_with_mask(q, k, v, mask, sinks: s).

    Each asserts bit-identical to the evaluator (same assert_equiv helper the other SDPA-block tests use). sinks is the standard per-head 1-D shape {n_heads} the existing SDPA tests use.

  • Opcode parity test green — kOpcodeCount bumped 121 → 123 in lockstep with @opcodes.

Follows the same pattern as #189 / #190 / #191 / #192 / #193.

Closes the final cluster on the Expr op-coverage checklist (#188) —
the two gpt-oss attention-sink blocks reachable from
Emily.Fast.attention_with_sinks.

Two new opcodes (FastSDPASinks=121, FastSDPAMaskSinks=122) dispatch
through the same mx::fast::scaled_dot_product_attention entry point
the existing FastSDPA / FastSDPAMask opcodes use, with the extra
`sinks` operand wired into the kernel's `sinks` arg and the mask_mode
discriminator preserved ("causal"/"" for the sinks-only variant,
"array" for the masked-with-sinks variant) — same shape as
Emily.Backend.fast_scaled_dot_product_attention_with{,_mask_and}_sinks.

Tests in compiler_equivalence_test.exs cover the three reachable
combinations: sinks-only non-causal, sinks-only causal, and
mask+sinks. Each asserts bit-identical to the evaluator.
@ausimian
ausimian merged commit aebbdae into feat/expr-compiler Jun 6, 2026
3 checks passed
@ausimian
ausimian deleted the feat/expr-compiler-sdpa-sinks branch June 6, 2026 11:36
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.

1 participant