Skip to content

feat(rocm): matmul-family compiled lane (batched_gemm/linear_general/qkv_projection/factorized_matmul/einsum) — gfx1151 - #129

Merged
gstoner merged 1 commit into
mainfrom
rocm/matmul-family-r
Jun 26, 2026
Merged

gstoner merged 1 commit into
mainfrom
rocm/matmul-family-r

Conversation

@gstoner

@gstoner gstoner commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Replacement for #126 (GitHub closed the original when its stacked base branch rocm/silu-mul-alibi was deleted after #125 merged). Rebuilt clean onto post-#125 main — identical content, base main.

All five matmul-family ops execute on the same compiler-generated WMMA GEMM kernel (the rocm_compiled spine), reshaped/batched/split in the runtime — no new MLIR pass:

op how
batched_gemm loop the gemm over leading batch dims
linear_general axis=-1 reshape + gemm + optional bias
qkv_projection packed x@W_qkv (3-way split is a host view)
factorized_matmul GPU matmul + exact host rank-r SVD-truncate
einsum single-contraction specs → (batched) gemm; else stable unsupported diagnostic

Shared lane rocm_matmul_family_compiled; GEMM-family compiled entries keep the unified MMA descriptor (fixes the test_backend_manifest_rocm_gemm_carries_mma_descriptor regression). f16/bf16, f32 accumulate. 32 tests pass on gfx1151 + AMD-wiring; mypy clean; 17 dashboards in sync.

🤖 Generated with Claude Code

…/qkv_projection/factorized_matmul/einsum on gfx1151

All five matmul-family ops execute on the SAME compiler-generated WMMA GEMM
kernel (the rocm_compiled spine), reshaped/batched/split in the runtime — no new
MLIR pass:

- batched_gemm   — loop the gemm over leading batch dims (np.matmul semantics)
- linear_general — axis=-1 reshape [...,K]→[M,K] + gemm + optional bias
- qkv_projection — packed x@W_qkv projection (the 3-way split is a host view)
- factorized_matmul — GPU matmul + exact host rank-r SVD-truncate epilogue
- einsum         — single-contraction two-operand specs → (batched) gemm;
                   other specs emit a stable "unsupported" diagnostic (#21)

Shared lane rocm_matmul_family_compiled; GEMM-family compiled entries keep the
unified MMA descriptor. f16/bf16, f32 accumulate. Validated on gfx1151 vs numpy.

(Rebuilt clean onto post-#125 main; supersedes the original #126 branch which
GitHub closed when its stacked base branch was deleted during the merge.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gstoner
gstoner merged commit 6cdb726 into main Jun 26, 2026
13 checks passed
gstoner added a commit that referenced this pull request Jun 26, 2026
…e/mla_decode_fused on gfx1151 (#130)

The attention analog of the matmul-family lane — each op composes
already-compiled kernels (the WMMA flash_attn kernel + the WMMA GEMM kernel for
MLA's latent projections + an elementwise gate), no new MLIR pass:

- gated_attention   — flash_attn × elementwise sigmoid-gate
- mla_decode        — latent K/V projections (WMMA GEMM) + flash_attn
- mla_decode_fused  — down/up projections (c=x@w_dkv; K=c@w_uk; V=c@w_uv) + flash_attn

Shared lane rocm_exotic_attn_compiled. f16/bf16, f32 softmax+accumulate.
Validated on gfx1151 vs the numpy attention reference. The recurrent DeltaNet
variants + block-sparse deepseek stay artifact_only with their technical
blockers documented in ROCM_AUDIT (Decision #25 — not marked compiled).

(Rebuilt clean onto post-#129 main; supersedes the original #127 branch which
GitHub closed when its stacked base chain was deleted during the merge.)

Co-authored-by: gstoner <angstroms01@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8ed73aef1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread python/tessera/runtime.py
y = _rocm_wmma_gemm_2d(x2, w).reshape(*x.shape[:-1], n3)
# The op returns (Q, K, V); the runtime returns the packed projection and
# the 3-way last-axis split is a trivial host view.
return y

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Return QKV as a tuple

When a tessera.qkv_projection artifact is launched through this new ROCm executor, the public API/CPU and Apple lanes return (Q, K, V), but this path returns the packed [..., 3N] array. Any caller that unpacks q, k, v = rt.launch(...)["output"] will either fail or read slices along the wrong axis when the leading dimension happens to be 3, so the lane is not semantically equivalent to the op it advertises; split y before returning and reject non-3-way widths.

Useful? React with 👍 / 👎.

Comment thread python/tessera/runtime.py
Comment on lines +1931 to +1933
if b_batch.shape[0] != nb_a:
raise ValueError(
f"batched_gemm batch mismatch; got {a.shape} @ {b.shape}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve batch broadcasting

For broadcastable batch operands such as A.shape == (5, M, K) and B.shape == (1, K, N), tessera.ops.batched_gemm is defined as the np.matmul reference and should broadcast B across the batch. This branch flattens B and requires the flattened batch count to equal A's unless B is rank-2, so valid inputs raise batched_gemm batch mismatch; the same issue affects einsum specs that rely on NumPy batch broadcasting.

Useful? React with 👍 / 👎.

Comment thread python/tessera/runtime.py
a2 = lhs_t.reshape(int(np.prod(bsh or [1])), int(np.prod(msh or [1])), kdim)
b2 = rhs_t.reshape(int(np.prod(bsh or [1])), kdim, int(np.prod(nsh or [1])))
prod = _rocm_batched_gemm(a2, b2) # [B, M, N]
canon = prod.reshape(*(bsh + msh + nsh)) # batch + free_l + free_r

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle scalar-output einsums

A vector dot such as i,i-> is a two-operand single-contraction einsum that maps cleanly to a 1xK @ Kx1 GEMM, but here bsh + msh + nsh is empty, so this expands to prod.reshape() and raises TypeError instead of returning the scalar result. Use an explicit empty shape, e.g. reshape(()), for the no-free-index case.

Useful? React with 👍 / 👎.

@gstoner
gstoner deleted the rocm/matmul-family-r branch June 26, 2026 00:05
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