Skip to content

C3: ROCm generic synth → HIP lane (emitter + hipcc + on-device runner) - #287

Closed
gstoner wants to merge 1 commit into
c1-x86-plugin-plus-rocm-f4from
c3-rocm-hip-emit
Closed

gstoner wants to merge 1 commit into
c1-x86-plugin-plus-rocm-f4from
c3-rocm-hip-emit

Conversation

@gstoner

@gstoner gstoner commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Gives ROCm a generic compiled kernel lane on gfx1151 — the GPU analogue of the
x86 C plugin — by turning emit/rocm_hip.py from runner-only into a full
three-seam plugin
.

Stacked on #286 (base = c1-x86-plugin-plus-rocm-f4). Retarget to main once #286 merges.

The three seams (C3 generic lane)

  • RocmHipEmitterFusedRegion → HIP source: a one-thread-per-row
    __global__ kernel + a host-pointer C-ABI wrapper (H2D / launch / D2H, same
    shape as the shipped libtessera_rocm_gemm.so symbols). Rejects non-Fused /
    DYNAMIC / non-f32 via EmitError.
  • _rocm_hip_compile_fnhipcc --offload-arch=<gfx> -O3 -shared.so
    (arch via $TESSERA_ROCM_ARCH / runtime._rocm_chip() / gfx1151 default).
  • RocmHipRunner.run_fused_region — dlopen + launch on gfx1151 →
    (out, "rocm_hip"), else numpy reference. Same NULL-buffer guard as x86 (a
    missing bias/residual declines to the reference instead of a null-deref SIGSEGV).
  • run_fused_attention keeps the shipped compiled FA-2 lane (Tier-3 hand-tuned).

Shared scalar body

Extracted emit/_fused_scalar_body.py (pointwise/reduction snippets + the per-row
compute body). x86 refactored onto it, so the x86 C kernel and the ROCm HIP kernel
synthesize the identical body and stay locked to the one fusion_core numpy
reference. x86 emit is behavior-preserving (19/19).

Proven on-device (gfx1151)

The generic HIP kernel compiles with hipcc, runs on the GPU, and passes the F4
oracle
across 7 FusedRegion chains (relu / gelu / silu / bias+softmax / rmsnorm /
layer_norm / prologue), f32-exact.

Lead-safety

The generic scalar HIP kernel is a correctness-first middle-ground candidate,
not a replacement for the crown-jewel WMMA/MFMA GEMM. The C3 tail — wiring
those Generate* MLIR passes through the loop as arbiter candidates — is still
open (tracked in the status table); the D1 arbiter picks per measured latency +
accuracy budget.

Verification

  • ROCm 12/12 (incl. live gfx1151 F4 gates for the 7 chains via hipcc + the
    shipped flash lane + the subprocess NULL-guard); x86 19/19; emit contract
    updated & green.
  • mypy python/tessera 0 (349 files); ruff clean; audit-docs 8/8;
    generated-doc drift gate in sync.

🤖 Generated with Claude Code

Turns emit/rocm_hip.py from a runner-only plugin into a FULL three-seam plugin
(parallel to the x86 C lane), giving ROCm a generic compiled kernel lane for the
fusable middle ground on gfx1151:

- RocmHipEmitter: FusedRegion → HIP source — a one-thread-per-row __global__
  kernel + a host-pointer C-ABI wrapper (H2D/launch/D2H, same shape as the
  shipped libtessera_rocm_gemm.so symbols). Rejects non-Fused / DYNAMIC / non-f32
  via EmitError (Decision #21).
- _rocm_hip_compile_fn: hipcc --offload-arch=<gfx> -O3 -shared → .so (real AOT;
  arch via $TESSERA_ROCM_ARCH / runtime._rocm_chip() / gfx1151 default).
- RocmHipRunner.run_fused_region: dlopen + launch on gfx1151 → (out, "rocm_hip"),
  else numpy reference. Same NULL-buffer guard as x86 (missing bias/residual
  declines to the reference instead of a null-deref SIGSEGV).
- run_fused_attention keeps the shipped compiled FA-2 lane (Tier-3 hand-tuned).

Shared scalar body: extracted emit/_fused_scalar_body.py (pointwise/reduction
snippets + the per-row compute body); x86 refactored onto it so the x86 C kernel
and the ROCm HIP kernel synthesize the IDENTICAL body and stay locked to the one
fusion_core numpy reference. x86 emit is byte-behavior-preserving (19/19).

Lead-safety: the generic scalar HIP kernel is a correctness-first middle-ground
candidate, NOT a replacement for the crown-jewel WMMA/MFMA GEMM (C3 tail = wire
those Generate* passes through the loop as arbiter candidates; still open).

Tests: rocm 12/12 (incl. live gfx1151 F4 gates for 7 FusedRegion chains via
hipcc + the shipped flash lane) + the subprocess NULL-guard; x86 19/19; emit
contract updated (unknown-emitter test now uses a genuinely-unregistered target;
rocm emitter/compile now assert-registered). mypy python/tessera 0 (349); ruff
clean; audit-docs 8/8; drift gate in sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gstoner
gstoner deleted the branch c1-x86-plugin-plus-rocm-f4 July 7, 2026 01:47
@gstoner gstoner closed this Jul 7, 2026

@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: a82cff7810

ℹ️ 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 on lines +207 to +208
M, K = Af.shape
_, N = Bf.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 Validate ROCm input shapes before copying

For calls where B.shape[0] != A.shape[1], this discards B's actual leading dimension and the generated HIP wrapper sizes szB from K (taken from A) and N; if B has fewer than K rows, hipMemcpy reads past the NumPy buffer, and if it has more rows the kernel silently computes a truncated matmul. The previous ROCm path delegated to region.reference, which raises on shape mismatches, so please mirror the Apple runner's K2 != K validation before building/launching the HIP kernel.

Useful? React with 👍 / 👎.

@gstoner
gstoner deleted the c3-rocm-hip-emit branch July 7, 2026 14:16
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