2 Commits
Author SHA1 Message Date
Aharrypotter c6a7f834cb bench: ignore the switch's own annotations when fingerprinting the IR
FlagTree's _apply_musa_rlc_policy(mod) stamps the whole RLC policy onto the
module as ttg.rlc-* attributes whenever the switch is on, regardless of whether
the pass then changes anything. Hashing the raw text therefore carried a
constant offset: every operator that compiles a kernel differed on that one
line and screened as IR_CHANGED. A filter that excludes nothing is not
filtering.

The null control could not catch it. Both of its sides run with the switch off,
so both carry the same attributes and the fingerprints match — it proved the
dump is deterministic, which was true, and said nothing about this.

Stripping ttg.rlc-* before hashing turns the screen back into a filter. Over
the same 24 operators, recomputed from the artifacts already on disk: 23
IR_CHANGED becomes 16, with 7 falling back to NO_IR_DIFF — tanh, gelu, mul,
softmax, mm, bmm, replication_pad3d, each byte-identical apart from that line.
replication_pad3d is the PR's largest NVIDIA win at +124.6%; on MUSA this pass
does not touch it.

The counts also show why the convert_layout count fails as a criterion in both
directions: addmm keeps cvt at 15 -> 15 while all 15 of its ttgir files differ
in substance, and tanh has no conversions and no change.
2026-09-10 19:13:51 +08:00
Aharrypotter 2fbfe1dd16 bench: make screening a first-class step with the same caliber as the A/B
Six rounds of A/B cost 13-44 minutes per operator on S5000 (rand, 15 shapes:
13.0 min; sort, 25 shapes: 43.4 min). Screening one costs about 0.8 minutes —
21 operators in 15.0 minutes, which knocked 13 of them out of the expensive
queue and cut it from ~7 hours to ~2.7. That ratio is the whole argument for
having a separate first step.

Screening was being done by ad-hoc scripts living in the results tree, and
those got two things wrong that this codebase already knows better than:

Both sides ran `record`. Each swept autotune independently, so the two sides
compiled different configs and produced different IR for reasons that have
nothing to do with the switch — every operator would screen as "changed".
screen.sh pins configs exactly as round 1 of ab_repeat does: A records, B
replays A.

The criterion was the convert_layout count. Equal counts do not mean equal
generated code, and what the A/B measures is whether the generated code
changed. The ttgir fingerprint decides; the cvt counts are still recorded,
because they explain what kind of change it was.

Four verdicts, and three of them are not "the switch does nothing":
IR_CHANGED (measure it), NO_IR_DIFF (skip it), NO_KERNEL (the operator never
reached Triton on this backend), NO_ROWS (it did not run — usually the dtype).
The last two are runnability problems being mistaken for switch results, which
is how `fft` got written off: the screen forced DTYPES=float16 on every
operator and fft only accepts complex64. OPS entries now carry an optional
per-operator dtype and default to the operator's own set.

ir_fingerprint moves to _ir_fingerprint.sh so screening and the A/B cannot
drift apart on the criterion.
2026-09-10 16:49:32 +08:00