Skip to content

W1.1b: close the three $kind ops that failed open - #505

Merged
gstoner merged 1 commit into
mainfrom
agent/w1.1b-kind-enums
Aug 4, 2026
Merged

gstoner merged 1 commit into
mainfrom
agent/w1.1b-kind-enums

Conversation

@gstoner

@gstoner gstoner commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Not the item the plan describes, because its premise didn't survive measurement.

The plan says "EnumAttr for every semantic StrAttr (4 × $kind)". Measured: 17 ops carry $kind, 3 of them are I64Attr rather than strings, and 14 of 17 already fail closed with a named error in their generator.

Three did not. Probed by feeding each a bogus kind and inspecting the output rather than the exit code, tessera_rocm.{predicate,optimizer,clifford} returned 0 and emitted a complete GPU kernel.

The defect

All three the same way — a trailing else doing double duty as a real branch and an unnamed semantic default:

op a typo silently...
predicate tests isfinite
clifford computes the geometric product — a different algebra operation, returning plausible numbers
optimizer trains with Adam

Decision #21a: a semantic key fails closed; it may never be silently defaulted.

Deriving the sets is the hard part

Each legal set includes the else branch's own name — exactly what a kind == scan of the consumer cannot see. That scan yields {isnan, isinf} and {wedge, left_contraction}, omitting isfinite, geometric_product and adam, all of which producers really emit. A constraint built that way rejects valid programs — the same defect as the earlier mode set that omitted "set".

predicate  isnan, isinf, isfinite
clifford   geometric_product, wedge, left_contraction
optimizer  sgd, momentum, nesterov, lion, adam, adamw, adafactor

I made that mistake again inside this change

The first optimizer enum omitted adafactor — and the negative fixture used adafactor as its example of a plausible-but-unimplemented value. It's neither: the pass implements it and test_adafactor_full_backward_executes_on_gfx1151 runs it on hardware. Six unit tests failed and are what caught it. I'd read a 15-line window of the consumer and taken it for the vocabulary; the pass's full literal set is seven.

That's written into the .td as the durable lesson: the existing tests encode producer reality better than any scan of the consumer, so run them before trusting a set. A later scare (tests appearing to emit isnormal/inner) turned out to be my own negative fixtures matching a grep missing --include=*.py — checked rather than reacted to; the sets stand.

Not in scope

The other 14 already fail closed in their generators. Hoisting their sets into ODS is a layering improvement, not a correctness fix, and is better done per-op with the same derivation discipline than in bulk here.

298 lit, 14425 unit, mypy 0, ruff clean, docs in sync.

🤖 Generated with Claude Code

Not the item the plan describes, because the plan's premise did not survive
measurement. It says "EnumAttr for every semantic StrAttr (4 x $kind)". Measured:
**17** ops carry `$kind`, **3 of them are I64Attr** rather than strings, and 14
of the 17 ALREADY fail closed with a named error in their generator.

Three did not. Probed by feeding each a bogus kind and inspecting the OUTPUT
rather than the exit code, `tessera_rocm.{predicate,optimizer,clifford}`
returned 0 AND emitted a complete GPU kernel.

All three failed the same way: a trailing `else` doing double duty as a real
branch and an unnamed semantic default.

  predicate  else { /* isfinite */ }   -> a typo silently tests isfinite
  clifford   else { *t = GP; }         -> a typo silently computes the GEOMETRIC
                                          PRODUCT, a different algebra operation
                                          returning plausible numbers
  optimizer  falls through to Adam     -> a typo silently trains with Adam

Decision #21a: a semantic key fails closed; it may never be silently defaulted.

── The sets, and why deriving them is the hard part ──

Each legal set includes the ELSE BRANCH'S OWN NAME, which is exactly what a
`kind ==` scan of the consumer does not see. That scan yields {isnan, isinf} and
{wedge, left_contraction} and omits `isfinite`, `geometric_product` and `adam` --
all real values producers emit (`runtime.py:4000`, `_CLIFFORD_KIND_NAME`, and 4
uses of `"adam"`). A constraint built that way REJECTS VALID PROGRAMS, which is
the same defect as the earlier `mode` set that omitted "set".

  predicate  isnan, isinf, isfinite
  clifford   geometric_product, wedge, left_contraction
  optimizer  sgd, momentum, nesterov, lion, adam, adamw, adafactor

── And I made that exact mistake again, in this change ──

The first version of the optimizer enum omitted `adafactor`, and the negative
fixture used `adafactor` as its example of a plausible-but-unimplemented value.
It is neither: the pass implements it and
`test_adafactor_full_backward_executes_on_gfx1151` runs it on hardware. Six unit
tests failed and are what caught it -- I had read a 15-line window of the
consumer and taken it for the vocabulary; the pass's full literal set is seven.

The durable lesson, now written into the .td: the existing tests encode producer
reality better than any scan of the consumer, so run them before trusting a set.
A later scare (tests appearing to emit `isnormal`/`inner`) turned out to be my
own negative fixtures matching a grep that lacked `--include=*.py` -- checked
rather than reacted to, and the sets stand.

298 lit, 14425 unit, mypy 0, ruff clean, docs in sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gstoner
gstoner merged commit 477a0d1 into main Aug 4, 2026
14 checks passed
gstoner pushed a commit that referenced this pull request Aug 5, 2026
…ls OPEN

Review was right, and checking it invalidated my own framing.

I wrote "11 already-fail-closed `$kind` sites". I measured the COUNT and the
dialect spread, then inherited "already fail closed" from the previous plan row
without checking it. Same error shape as #520: measure one thing, carry an
unverified adjective attached to it.

Verified both directions rather than assuming either:

* `ROCM_Int4PackKernelOp` DOES fail closed. Its generator validates `kind`
  against an explicit set and errors naming
  `kind=pack|unpack|relu|sparse_gather|cache_append`. A genuine hoist candidate.

* `tessera.neighbors.topology.create` fails OPEN, and it is a Decision #21a
  violation rather than a layering nit. `CreateTopologyOp::verify()` checks only
  that `kind` EXISTS. `DynamicTopologyPass::isMutableKind` then dispatches by
  SUBSTRING —
  `contains("dynamic") || contains("adaptive") || contains("fault") ||
   contains("custom_graph")`.

  So a typo (`2d_mseh`) matches nothing and silently becomes a STATIC topology.
  The substring test is also wrong in the other direction: `not_dynamic` would
  classify as MUTABLE. `kind` drives `topology.dynamic`, `topology.replan`, and
  `topology.replan_hook`, so an unrecognized value silently selects different
  execution semantics — the same unnamed-semantic-default class #505 closed for
  `predicate` / `optimizer` / `clifford`.

So W1.1b is per-site triage first — fail-open sites are correctness fixes owing
a negative fixture (Decision #10a), fail-closed sites are ODS hoists — and its
remaining size is not yet known. The row no longer calls it a layering
improvement, because at least one site is a live fail-open defect.

Not fixed here: this PR is scoping, and the Neighbors fix wants its own change
with a `CHECK-NOT`-style negative fixture and the substring-vs-equality
correction, which is a behavioural change to topology classification.

Docs only. 14448 unit passed, ruff clean, 24 generated docs in sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gstoner
gstoner deleted the agent/w1.1b-kind-enums branch August 7, 2026 23:47
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