Skip to content

C3 tail + C1b + D1-core: WMMA/AOCL-DLP Tier-3 candidates + arbiter - #289

Merged
gstoner merged 2 commits into
mainfrom
c3-tail-wmma-candidates
Jul 7, 2026
Merged

gstoner merged 2 commits into
mainfrom
c3-tail-wmma-candidates

Conversation

@gstoner

@gstoner gstoner commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Wires Decision #28's three-tier / measured-arbiter model into the compiler: a D1 candidate registry (emit/candidate.py) plus the crown-jewel hand-tuned kernels registered through it as first-class, F4-gated Tier-3 candidates. Additive and opt-in — nothing routes through the arbiter until a caller invokes it.

Proven on this box (Strix Halo: Zen 5 + gfx1151). NVIDIA (C2) is a separate phase that needs the NR2 Pro box.

D1 core — emit/candidate.py

  • Candidate ABC (tier/target/op/available()/applies_to()/run()) + registry keyed per (target, op); Tier = {SYNTHESIZED, EMITTED, HAND_TUNED}.
  • arbitrate() / run_arbitrated(): filter by applicability + availability, F4-gate each candidate through the same universal oracle (a KernelRunner adapter reuses fusion_core.verify_synthesized_*), then select by tier priority (crown-jewel first — lead-safe) with a measure hook (the D2 seam) and a force escape hatch (E3).

C3 tail (ROCm) — live-proven gfx1151

  • runtime._rocm_wmma_fused_2d: direct fused WMMA GEMM+bias+{relu,gelu,silu} via the generate-wmma-gemm-kernel Generate* pass (f16 storage / f32 accum).
  • emit/rocm_hip.py registers RocmWmmaGemmCandidate (Tier-3), RocmGenericHipCandidate (Tier-1), RocmFlashAttnCandidate (Tier-3).
  • MFMA stays analytical — gfx1151 is RDNA3.5/WMMA; MFMA needs CDNA silicon.

C1b (x86) — opt-in

  • emit/x86_aocl_dlp.py registers X86AoclDlpCandidate (Tier-3), availability-gated on $TESSERA_AOCL_DLP_LIB/$TESSERA_AOCL_DLP_SGEMM. The concrete post-op ctypes ABI is deliberately not guessed_aocl_dlp_gemm declines until bound against real aocl-dlp headers + a license review on a licensed install.
  • emit/x86_llvm.py registers X86GenericCCandidate (Tier-1), proven on Zen 5.

Testing

  • tests/unit/test_candidate_arbiter.py — 13 host-free (registry, tiering, F4-gate, force/E3, measure/D2 seam, reference fallback, accuracy budget).
  • tests/unit/test_rocm_plugin.py §4 — live gfx1151 (WMMA candidate F4-gated across bias/relu/gelu/silu; arbiter tier-priority pick + fall-to-generic; escape hatch).
  • tests/unit/test_x86_plugin.py — C1b block (registration, availability-gated decline, arbiter falls to generic on Zen).
  • Targeted sweep: 168 passed. mypy python/tessera/ clean, ruff clean.

Still open (next phases)

  • D2 measured autotune (replaces tier-priority with on-device latency per shape-bucket) + D3 fallback log.
  • MFMA candidates (CDNA-gated) and AOCL-DLP ABI binding (licensed Zen box).
  • C2 NVIDIA emit + ptxas→CUBIN→tsrRegisterGpuLauncher bridge (NR2 Pro box).

🤖 Generated with Claude Code

Introduce the D1 candidate registry (emit/candidate.py) — the accuracy-budgeted
arbiter seam from Decision #28's three-tier model — and wire the crown-jewel
hand-tuned kernels through it as first-class candidates:

D1 core (emit/candidate.py):
- Candidate ABC (tier/target/op/available()/applies_to()/run()) + a registry
  keyed per (target, op); Tier enum {SYNTHESIZED, EMITTED, HAND_TUNED}.
- arbitrate()/run_arbitrated(): filter by applicability+availability, F4-gate
  each candidate through the SAME universal oracle (a KernelRunner adapter reuses
  fusion_core.verify_synthesized_*), then select by tier priority (crown-jewel
  first — lead-safe) with a `measure` hook (D2 seam) and a `force` escape (E3).

C3 tail (ROCm, live-proven gfx1151):
- runtime._rocm_wmma_fused_2d: direct fused WMMA GEMM+bias+{relu,gelu,silu} via
  the generate-wmma-gemm-kernel Generate* pass (f16 storage / f32 accum).
- emit/rocm_hip.py registers RocmWmmaGemmCandidate (Tier-3), RocmGenericHipCandidate
  (Tier-1), RocmFlashAttnCandidate (Tier-3). MFMA stays analytical (gfx1151 is
  RDNA3.5/WMMA; MFMA needs CDNA silicon).

C1b (x86, opt-in):
- emit/x86_aocl_dlp.py registers X86AoclDlpCandidate (Tier-3), availability-gated
  on $TESSERA_AOCL_DLP_LIB/$TESSERA_AOCL_DLP_SGEMM; the concrete post-op ABI is
  deliberately not guessed (declines until bound against real headers + license
  review). emit/x86_llvm.py registers X86GenericCCandidate (Tier-1), proven on Zen 5.

Tests: test_candidate_arbiter.py (13 host-free), test_rocm_plugin.py §4 (live
gfx1151), test_x86_plugin.py C1b block. Sweep 168 passed. mypy + ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <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: e3bf2ea1bf

ℹ️ 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/compiler/emit/candidate.py Outdated
Comment thread python/tessera/compiler/emit/rocm_hip.py Outdated
Comment thread python/tessera/compiler/emit/x86_aocl_dlp.py
P1 — candidate F4 probes shared the backend target as their oracle cache key,
so a Tier-3 probe's verdict could be reused for the real backend runner or a
sibling candidate on the same target. The _as_runner adapter now namespaces its
target as `candidate::<target>::<name>`, landing each probe on a candidate-private
verdict-cache key that never collides. New regression test asserts a failing
candidate probe on target T does not poison a later non-forced verification of a
real runner on T.

P2 — a candidate that declined to the numpy reference on its F4 probe still
counted as verified, so it could win arbitration by tier and then hand back only
the reference, starving a working lower tier. Fixed at two levels:
- Arbiter (root cause): verify_candidate now records the probe's execution tag and
  returns False when the candidate declined (REFERENCE_EXECUTIONS) — a decliner is
  not a viable arbitration winner. New tests cover the drop + fall-to-lower-tier.
- ROCm: RocmWmmaGemmCandidate.available() now probes the ACTUAL fused path
  (runtime._rocm_wmma_fused_available: tessera-opt + generated kernel), not just
  the shipped GEMM symbol.
- x86 AOCL-DLP: gated behind a `_ABI_WIRED` flag (False until the concrete post-op
  ctypes ABI is bound against real headers + license review), so a resolvable
  symbol can no longer make the lane "available" while run() still declines.

Sweep 171 passed (+3 regression tests). mypy + ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gstoner
gstoner merged commit bf8ec49 into main Jul 7, 2026
17 checks passed
@gstoner
gstoner deleted the c3-tail-wmma-candidates branch July 7, 2026 15:24
gstoner added a commit that referenced this pull request Sep 1, 2026
`applies_to(region)` is shape-blind by construction: a region carries
structure (epilogue chain, dtype, transpose flags) and the dimensions
arrive with the operands. So an aligned-only lane could not decline a
ragged shape at the applicability gate, and the F4 oracle could not cover
for it -- its probe shape is fixed and its verdict is cached under a key
with no shape in it. The lane declined inside `run` instead, by returning
the numpy reference, after it had already won.

Two harms, reproduced against the real NvidiaMmaGemmEmittedCandidate:

- Starvation. It won on tier at a ragged shape and handed back numpy while
  a lower-tier lane that could serve the shape went untried -- the failure
  RocmWmmaGemmCandidate.available was hardened against on the availability
  axis (PR #289 review), one axis over.
- A fabricated measurement. `_measure` timed the decline and stored
  0.00525 ms of numpy under the kernel's name against a real 0.00196 ms
  rival. That number is not inert: with the backstop disabled the record
  comes back `separated: True, margin 0.59`, so #663's separation machinery
  certifies a 2.4x loss for a kernel that never ran.

The execution tag already said so. The D3 arbiter log has described this
as "a silent degrade ... an unsupported shape" since it was written, and
nothing read it.

- `Candidate.applies_to_inputs(region, *inputs)`, additive, default True,
  fail-OPEN on absent/malformed operands (an operand error must still raise
  through `run`, not be silently excluded -- Decision #21).
- `candidate.live_candidates`, one statement of "who is racing", replacing
  the copy `arbitrate`, `measured_arbitrate` and `corpus_winner` each kept.
- `_measure` reads the tag: a reference decline lands in `unmeasured`, not
  in `candidates`. Fail-CLOSED backstop for lanes that never adopt the hook.
- Producers: the NVIDIA emitted GEMM (aligned-only, as its own docstring and
  device timer already said) and ROCm flash-attention (head_dim % 16, Tier-3
  on the one AMD device that executes -- the worse-placed of the two).

All four backends assessed under APPLIES-TO-SHAPE-BLIND-2026-09-01: NVIDIA
and ROCm follow-up required (device proof owed), Apple and x86 not
applicable with reasons. Mutation-verified: four mutations, each killing
only its own tests. Device evidence is NOT claimed -- this Mac has no CUDA
or ROCm, so harm 2 was reproduced under a simulated device and labelled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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