Skip to content

fix(breakdown): credit the GEAK kernels the collector is currently dropping - #1209

Open
iraj465 wants to merge 10 commits into
mainfrom
fix/geak-backfill-no-gain
Open

fix(breakdown): credit the GEAK kernels the collector is currently dropping#1209
iraj465 wants to merge 10 commits into
mainfrom
fix/geak-backfill-no-gain

Conversation

@iraj465

@iraj465 iraj465 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Branch: fix/geak-backfill-no-gainmain
Closes: #1208

Scope

This PR grew past the issue it closes. #1208 describes three collector defects;
the PR also carries four orchestrator fixes that the same investigation turned
up, because the first three only make the kernels visible and the rest are
what make them credited. Reading the sections in order follows that chain.

# fix file described in
1 back-fill on no_gain, not only ok collectors/geak.py #1208
2 read every e2e cycle, not just the one the pointer names collectors/geak.py #1208
3 collapse GEAK's alias twin collectors/geak.py #1208
4 attribution resolves the GEAK family from provenance collectors/attribution.py no issue
5 dead-run recovery reads a file that is actually written collectors/geak.py no issue
6 write the per-kernel adoption ledger phases/kernel.py no issue
7 prove the overlay loaded before crediting a kernel loop/writeback.py, loop/coordinator_helpers.py no issue

The A/B against the live campaign is in
this comment;
the coverage-gate fix and one defect it surfaced are in
this one.

On the counts below. The campaign is live and grew while this PR was open:
the sections written first say 62/64/65/66 sessions, the A/B comment says
99 sessions / 68 with a result.json, measured 18 Aug 2026. Where the two
disagree, the comment is current. No conclusion changes — every ratio held as
the corpus grew — but the absolute numbers below are the smaller corpus.

What this fixes

Three defects in collectors/geak.py, one commit each.

1. cd88067 — back-fill on no_gain, not only on ok

-if not accepted_kernels and status == "ok":
+if not accepted_kernels and status in ("ok", "no_gain"):

no_gain is a statement about end-to-end throughput. It says nothing about
whether a kernel was integrated. It is also the majority status: 35 of the 65
GEAK sessions in /shared_nfs/hyperloom-claw/. The collector refused to read
any of their journeys.

2. 6166943 — read every e2e cycle, not the one the pointer names

kernel_journey_path names the last cycle only. A new _journey_paths helper
returns the pointer first, then its sibling */kernel_journey.json in sorted
cycle order. Kernels accumulate deduped on kernel_id, and the pointer wins on
a tie, so the authoritative cycle keeps precedence.

Safe to union, and checked rather than assumed: across all 64 journeys on disk,
0 kernel_ids are KEEP in one cycle and non-KEEP in another.

3. 8d108b0 — collapse GEAK's alias twin

GEAK writes one acceptance under two ids: an overlay entry named for the
candidate tag (c0_triton) and a return entry named for the kernel symbol
(dsa_sparse_attn_prefill_main_kernel), with the same e2e_gain_pct and
gpu_pct: null on the second.

_collapse_journey_aliases groups accepted rows by gain and fires only when a
group holds both a measured and an unmeasured row. The measured row
survives and gains an aliases list; the unmeasured row is dropped. Two
measured rows of equal gain are two kernels and both survive. Unmeasured rows of
distinct gain are untouched.

accepted_kernels is typed list[Any] (breakdown/schema.py:1033), so adding
aliases is schema-safe.

Root cause is in GEAK and is fixed there
AMD-AGI/GEAK fix/journey-overlay-return-alias. This collapse still has to
ship: the 77 journeys already written to disk contain the duplicates and the
dashboard reads those files. Once the GEAK fix lands, this becomes a no-op on
new runs.

Verification 1 — replay over the live campaign

Ran the real collector over all 65 geak/result.json under
/shared_nfs/hyperloom-claw/, on main and on this branch.

main this branch
sessions with kernels_optimized > 0 12 15
kernels credited 23 23
of those, duplicates 6 0
distinct real kernels 17 23
sessions that lost a kernel 0

Newly visible, all status: "no_gain":

  • /shared_nfs/hyperloom-claw/GLM-5.2-MXFP4/20260814T163244Z/geak — recovered by
    the gate alone
  • /shared_nfs/hyperloom-claw/Qwen3-14B-FP8/20260816T050457Z/geak — needs the
    gate and the multi-cycle scan (pointer e2e_cycle1, KEEPs in e2e_cycle0)
  • /shared_nfs/hyperloom-claw/gemma-4-26B-A4B-it/20260816T112750Z/geak — same

The six sessions whose duplicate was removed are listed in the issue.

Reproduce:

python - <<'PY'
import sys, json, glob, inspect
sys.path.insert(0, "src")
from hyperloom.inference_optimizer.breakdown.collectors import geak as G
GATE = ("ok", "no_gain") if "no_gain" in inspect.getsource(G.collect_geak) else ("ok",)
sess = tot = 0
for rp in sorted(glob.glob('/shared_nfs/hyperloom-claw/*/*/geak/result.json')):
    r = json.load(open(rp))
    ak = r.get("accepted_kernels") or []
    if not ak and str(r.get("status")) in GATE:
        ak = G._geak_accepted_kernels_from_journey(r, []) or []
    if ak: sess += 1
    tot += len(ak)
print(GATE, "sessions:", sess, "kernels:", tot)
PY

Verification 2 — tests

Six new unit tests in
src/hyperloom/inference_optimizer/tests/test_geak_breakdown_unit.py:

test pins
test_collect_geak_backfill_scans_earlier_cycles a KEEP in a cycle the pointer does not name
test_collect_geak_backfill_dedupes_repeated_kernel_across_cycles the same kernel in two cycles is one credit
test_collect_geak_backfill_collapses_alias_twin the defect itself
test_collect_geak_backfill_collapses_rounded_alias_twin grouping tolerates float noise at 3 dp
test_collect_geak_backfill_keeps_two_measured_kernels_of_equal_gain two measured rows are two kernels
test_collect_geak_backfill_keeps_unmeasured_kernels_of_distinct_gain no over-collapse

The 13 geak/breakdown test files, same interpreter, same machine:

main        : 173 passed, 27 failed
this branch : 181 passed, 27 failed

The 27 failures are pre-existing and the failure sets are byte-identical on both
sides (pytest-asyncio configuration; diff of the two FAILED lists is
empty). The full repository suite does not complete here — it exceeds a 2-minute
budget and hits collection errors in test_multinode_server_log_dir.py and
test_gpu_probe_remote.py, identically before and after — so the run is scoped
to the files this change touches.

Not addressed here

  • Empty patches/ on GEAK sessions. By design: GEAK never sends the per-kernel
    apply request that session_paths.patches_dir serves
    (session_paths.py:219-232, one caller at request_handlers.py:1038).
  • reports/kernel_optimization_summary.json still reports "No kernels were
    attempted". It reads a different field.
  • Whether a gate: "stack" acceptance should count as an integrated kernel. One
    credited kernel (c1_tilelang, GLM session) is provisional by its own
    integrate_result.json. Worth deciding, separately.

Upstream: AMD-AGI/GEAK#407 / AMD-AGI/GEAK#408.


4. a44a190 — carry the credit the rest of the way to the dashboard

The three commits above make the collector see the kernels. This one makes the
rest of the pipeline name them. Same evidence base: 66 sessions with a result
under /shared_nfs/hyperloom-claw/.

GEAK is already credited 12 times, +1.2% to +68.7%, and every credit is filed as
a server flag. Four places separate a number from what produced it.

Change 1 — attribution resolves the GEAK family from provenance. The
revalidation dispatches as kind="explore" with provenance
geak_revalidate, so _action_family("explore") returned explore and all 12
wins landed in the explore family — exactly what the comment above
_ACTION_FAMILY_TABLE says the geak bucket exists to prevent. The provenance
names are reused from _CONFIG_REPLAY_PROVENANCE, so there is one list in the
tree. A new phase bucket splits the gain by what was running: config / kernel /
joint. A joint measurement is reported whole under joint — the stack rebench
cannot divide it, and an invented split is worse than none.

Change 2 — dead-run recovery reads a file that exists.
_geak_reconstruct_from_disk recovered kernels from kernel_journey.json,
which is written last: 0 of 30 killed runs have one, while 10 have per-candidate
overlay/*/integrate_result.json. Those are now a second source, same admission
test, tagged accepted_kernels_source=integrate_result_backfill and
validated: False. Recovers _mxfp8_linear_kernel at +40.626% and nothing else.

Change 4 — one adoption ledger. state.kernel_integrate_attempts is what
by_kernel, kernel_lifecycle.adopted, attribution and the timeline all read;
GEAK wrote only optimization_stack + geak_pending. The promotion now writes
both from the same measurement. Acceptances are read from both lanes —
accepted_heads and accepted_kernels differ only by which queue proposed
them, and 8 of the 11 sessions with an acceptance carry it in accepted_heads
alone. kind == "env" entries are excluded: they select an existing library, so
they are config gain, not an authored kernel.

Change 5 — prove the kernel ran before crediting it.
canonical_fingerprint covers (args, envs) only, so a revalidation that
silently dropped the overlay still passed its own identity assertion. Of the 62
results carrying a final_overlay, 24 name a directory that does not exist and
29 hold no sitecustomize.py. The dispatcher now requires a loadable overlay,
carries the overlay manifest digest beside the config hash, and names the
accepted kernels on the grid entry. canonical_fingerprint itself is unchanged.

Two traps found only on live data, both now covered by
test_geak_overlay_identity.py:

  • GEAK also emits a config-only overlay — {"modules": [], "rebinds": []}
    plus a note — which imports cleanly and installs nothing. Counting it as
    loadable would label a pure config win as a kernel win.
  • _overlay_manifest.json names the bind target, not the kernel body. Three
    unrelated sessions shared one manifest digest because all three patch
    sglang.kernels.ops.attention.decode_attention. The referenced bodies are
    folded in; digests went from 5 distinct to 7, with 0 collisions.

Verification 4 — end to end on campaign data

The credit chain run whole, not stage by stage:
geak/result.json + the orchestrator's real rebench numbers from
coordinator.db_record_geak_adopted_kernels
state.kernel_integrate_attempts_collect_adopted_kernels
collect_kernel_lifecycle["adopted"] → attribution family and phase.

main this branch
GEAK gains in the geak family 0 of 12 12 of 12 (217.1 gain-points)
gain-points split config / joint 186.3 / 30.9
sessions producing a named kernel row 0 3
adopted ledger rows 0 3, no duplicates, all validated: True
kernel_lifecycle["adopted"] [] agrees with the collector row for row

Replayed on the recorded dispatch payloads in coordinator.db rather than
geak/result.json: 26 dispatches, all declared an overlay, 7 loadable → 17
drop to flags-only, 2 fall back to the GEAK harness (2a), 0 cfg_hash changes,
7 distinct digests. Four of the 12 wins had the kernel proven loaded.

geak/result.json is a last-write-wins snapshot across e2e_cycle0/1/2, so
an offline replay keyed on it reads the last cycle, not the dispatched one. The
task params in coordinator.db are the dispatch, recorded verbatim, and are the
correct replay input. This is why the result-driven replay above shows 3 and the
dispatch-driven one shows 4.

Verification 5 — tests

10 new tests in test_geak_overlay_identity.py. Widest scoped run
(-k "geak or breakdown or kernel or attribution or overlay"), same
interpreter, same machine:

origin/main : 2964 passed, 252 failed
this branch : 2978 passed, 252 failed

The 252 failures are pre-existing and the failure sets are identical, not
merely the same size.

Deviation from plan — Change 3 is not adopted

The plan prescribed deriving GEAK's status once, using cold_speedup as the
verdict ratio. Replayed over 63 sessions, that flips 5 sessions the independent
director scored 0.9994–1.0035. It is refuted and was not merged. AMD-AGI/GEAK#406
addresses the same code and fixes the GLM case correctly upstream, publishing
1.7456 rather than leaving ok beside a 0.9877 ratio.

Limits

No GPU is present on the machine this was verified on (/dev/kfd absent), so
everything above is an offline replay against recorded campaign data. A live
session remains verification 9 and is only possible after merge. All 66
state.json and reports/decision_trace.json are root mode 600 and were not
read; no privilege escalation was used.

iraj465 and others added 3 commits August 17, 2026 09:58
collect_geak() only reconstructs accepted_kernels from kernel_journey.json
when status == "ok". status is derived from throughput_speedup, which GEAK
reports on the run's headline basis -- frequently "cold". A run can therefore
be stamped no_gain on the cold basis while alignment_metrics.hot_geak_speedup
records a large measured hot win and the journey holds genuine KEEP rows.
Those rows were dropped, and the session reported kernels_optimized: 0.

Widen the gate to ("ok", "no_gain"). error/timeout stay excluded: those runs
never produced a trustworthy workflow return.

Verified against all 64 GEAK result.json files in the hyperloom-claw campaign:
sessions with kernels_optimized > 0 goes 12 -> 13, kernels credited 23 -> 26,
one session changes, zero regressions. The recovered session is
GLM-5.2-MXFP4/20260814T163244Z -- e2e_gain_pct 29.994, hot_geak_speedup 2.5722,
a 31 KB final_patch.diff on disk, previously credited to nothing.

Note: counting accepted_heads alongside accepted_kernels is NOT the fix. In 7
of the 8 campaign runs carrying heads, the head is already the same kernel as
an accepted_kernels entry, so summing would double-count.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…last

``_geak_accepted_kernels_from_journey`` resolved a single journey file from
``kernel_journey_path`` / ``eval_dir``. That pointer names the LAST e2e cycle.
A run that keeps kernels in cycle 0 and then opens a cycle 1 that keeps
nothing back-fills nothing, and the run is reported as zero kernels
optimized.

Read the pointer plus every sibling ``e2e_cycle*/kernel_journey.json``,
de-duplicating on ``kernel_id`` with the pointer cycle winning. No kernel in
the 64 campaign result files is KEEP in one cycle and rejected in a later
one, so the union cannot over-credit.

Two campaign runs are affected:
  Qwen3-14B-FP8/20260816T050457Z    cycle0 3 KEEP, cycle1 0  -> 0 credited
  gemma-4-26B-A4B-it/20260816T112750Z cycle0 2 KEEP, cycle1 0 -> 0 credited

Replayed over all 64 GEAK result.json in the campaign, combined with the
no_gain gate change in the previous commit:
  sessions with kernels_optimized > 0   12 -> 15
  kernels credited                      23 -> 31
  regressions                           0
GEAK's journey records one acceptance twice when the profiler resolves a
dispatched candidate to a library symbol: once under the candidate id with the
measurement (``gpu_pct``), once under the resolved symbol with ``gpu_pct:
null``. Both rows repeat the same ``e2e_gain_pct``. Back-filling both doubled
the kernel.

Group accepted rows by rounded gain -- the twin is sometimes the rounded copy
(10.38337292749906 vs 10.383) -- and fold a group that holds both a measured
and an unmeasured row into the measured row, recording the dropped ids under
``aliases``. Groups that are all-measured or all-unmeasured are left intact, so
two real kernels of equal gain both survive and a shape-split pair of
unmeasured kernels is not mistaken for an alias.

Also extract journey resolution into ``_journey_paths``.

Replayed over all 64 campaign result files, with the two earlier commits:
  sessions with kernels_optimized > 0   12 -> 15
  kernels credited                      23 -> 23   (+3 recovered, -8 duplicates)
  alias twins collapsed                 8
  regressions                           0

Affected sessions carry an alias twin in every case:
  GLM-5.2-MXFP4/20260814T163244Z        c0_triton  <- dsa_sparse_attn_prefill_main_kernel
  Kimi-K3/20260816T122327Z              decode_attention_grouped_mla
  MiniMax-M3-MXFP8/20260801T023259Z     c0_flydsl  <- mxfp8_linear_kernel
  Qwen3-14B-FP8/20260814T163051Z        c1_ck      <- ck_gemm_a8w8_blockscale_bpreshuffle
  Qwen3.5-122B-A10B-FP8/20260801T034513Z, 20260805T080211Z
  gemma-4-26B-A4B-it/20260814T155153Z, 20260816T112750Z
@iraj465
iraj465 requested a review from a team as a code owner August 17, 2026 11:38
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

CI E2E report — ✅ Succeeded

item value
result ✅ Succeeded
model Qwen/Qwen3-0.6B (dense)
resources 1× GPU, TP=1
PR branch fix/geak-backfill-no-gain
commit 82dd83684c6a02fe033feb96ca85314c4e092252
session_id 11f4be19-c51c-4820-befd-cfd8cb09dcc4
queue → dispatch 0s
run time 170m 14s
total 170m 14s

details

@iraj465

iraj465 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Cross-workload view: what GEAK reported, what Hyperloom credited

Asked for during review: how the numbers in this PR break down per workload,
rather than as one campaign total.

Measured on 17 Aug 2026 over /shared_nfs/hyperloom-claw/, 66 GEAK CI
runs across 15 workloads
. The campaign is live, so counts drift upward.

Definitions, so the three columns are not read as the same thing:

  • GEAK e2egeak/result.jsonthroughput_speedup > 1.0. GEAK's own
    end-to-end verdict for the run.
  • Hyperloom e2ereports/final.mdcumulative_gain_val > 0. The
    session gain, from every action the optimizer took. GEAK is one of them,
    so this is not a like-for-like restatement of the column to its left.
  • GEAK kernel claimsKEEP + integrated rows in
    geak/e2e_cycle*/kernel_journey.json, across all cycles, after the alias
    twin is collapsed.

1. GEAK-reported e2e improvement, by workload

workload runs >0% >=1% >=5% >=10%
Qwen3-0.6B 9 4 2 0 0
Qwen3-14B-FP8 9 6 1 1 1
MiniMax-M3-MXFP4 7 0 0 0 0
Qwen3-8B 7 3 0 0 0
gemma-4-26B-A4B-it 7 2 2 2 1
DeepSeek-V4-Pro 5 0 0 0 0
Kimi-K3 5 1 1 1 1
Mixtral-8x7B-Instruct-v0.1 5 3 1 0 0
Llama-3.1-8B-Instruct 4 2 2 0 0
Qwen3.5-122B-A10B-FP8 2 2 2 2 2
Qwen3.8-2.4T-A95B-Quark-MXFP4 2 0 0 0 0
GLM-5.2-MXFP4 1 0 0 0 0
MiniMax-M3-MXFP8 1 1 1 1 1
Qwen3.5-397B-A17B-MXFP4 1 1 0 0 0
gpt-oss-120b 1 1 1 0 0
TOTAL 66 26 13 7 6

26 runs report a gain above zero, but half of those are below 1% — well inside
run-to-run variation. Only 6 of 66 clear 10%.

2. Hyperloom-reported e2e improvement, by workload

workload runs final.md readable gain >0% median gain
Qwen3-0.6B 9 4 4 57.42%
Qwen3-14B-FP8 9 3 3 27.13%
MiniMax-M3-MXFP4 7 7 4 16.38%
Qwen3-8B 7 3 2 3.73%
gemma-4-26B-A4B-it 7 3 3 9.48%
DeepSeek-V4-Pro 5 4 3 27.98%
Kimi-K3 5 3 1 0.00%
Mixtral-8x7B-Instruct-v0.1 5 4 3 10.30%
Llama-3.1-8B-Instruct 4 2 1 210.68%
Qwen3.5-122B-A10B-FP8 2 1 1 21.71%
Qwen3.8-2.4T-A95B-Quark-MXFP4 2 2 2 11.09%
GLM-5.2-MXFP4 1 1 1 26.28%
MiniMax-M3-MXFP8 1 0 0
Qwen3.5-397B-A17B-MXFP4 1 1 0 0.00%
gpt-oss-120b 1 1 1 18.45%
TOTAL 66 39 29

Caveat, stated rather than hidden: reports/final.md is mode 600 in 27 of
the 66 sessions, so the Hyperloom column covers 39 runs, not 66. The >0%
count is out of 39. It is not comparable run-for-run with the column above.

The two columns diverge because they answer different questions. Hyperloom's
number is the whole session; GEAK's is GEAK's own slice. A workload can show a
large session gain and a flat GEAK verdict in the same run.

3. GEAK kernel claims, and what Hyperloom credits

workload runs GEAK KEEP rows distinct after twin collapse credited on main credited on this branch
Qwen3-0.6B 9 4 3 3 (0 twins) 3
Qwen3-14B-FP8 9 6 5 3 (1 twin → 2 real) 5
MiniMax-M3-MXFP4 7 0 0 0 0
Qwen3-8B 7 0 0 0 0
gemma-4-26B-A4B-it 7 9 6 3 (1 twin → 2 real) 3
DeepSeek-V4-Pro 5 0 0 0 0
Kimi-K3 5 2 1 2 (1 twin → 1 real) 1
Mixtral-8x7B-Instruct-v0.1 5 2 2 2 (0 twins) 2
Llama-3.1-8B-Instruct 4 2 2 2 (0 twins) 2
Qwen3.5-122B-A10B-FP8 2 4 2 4 (2 twins → 2 real) 2
Qwen3.8-2.4T-A95B-Quark-MXFP4 2 0 0 0 0
GLM-5.2-MXFP4 1 3 2 0 2
MiniMax-M3-MXFP8 1 4 3 4 (1 twin → 3 real) 3
Qwen3.5-397B-A17B-MXFP4 1 0 0 0 0
gpt-oss-120b 1 0 0 0 0
TOTAL 66 36 26 23 (6 twins → 17 real) 23 (0 twins)

Sessions credited with at least one kernel: 12 → 15. Credited rows stay at
23; what changes is that 6 of them were the same kernel twice, and 6 real
kernels were hidden behind the two gates.

Read the per-workload rows rather than only the total. Qwen3-14B-FP8 goes 2 real
→ 5. GLM-5.2-MXFP4 goes 0 → 2, because that run is status: no_gain. Kimi-K3 and
Qwen3.5-122B-A10B-FP8 go down in raw count, 2 → 1 and 4 → 2, which is the
twin collapse removing phantom credit. Both directions are the fix working.

4. Three worked runs

gemma-4-26B-A4B-it/20260815T130915Zok, GEAK e2e +18.91%, Hyperloom
session +20.87%. The journey holds 5 KEEP rows:

fused_moe_kernel_c0_triton                     gpu=35.22  gain=14.973
fwd_grouped_kernel_stage1_c0_triton            gpu=33.59  gain=18.9148
fwd_grouped_kernel_stage1_stage2_c0_triton     gpu=35.22  gain=14.973
fwd_grouped_kernel_stage1_stage2_c0_triton_v2  gpu=35.22  gain=10.512
fwd_grouped_kernel_stage1                      gpu=None   gain=18.9148   <- twin of row 2

Qwen3-14B-FP8/20260816T050457Zno_gain on a hot basis, GEAK e2e
1.0000, Hyperloom session +51.72%, and 3 distinct kernels in the journey. Invisible
on main; credited on this branch. Also the run whose single cand_c0_aiter
overlay (delta 7.53) decomposes into two accepted records (6.779 and 0.705) —
the case the GEAK-side consume-once rule deliberately does not merge.

GLM-5.2-MXFP4/20260814T163244Z — the sharpest one. status: no_gain,
throughput_speedup 0.9877 on a cold basis, while
alignment_metrics.hot_geak_speedup is 2.5722. Three KEEP rows on disk, two
distinct. On main this run credits zero kernels.

That run is not an isolated quirk of one model: 24 of 66 runs report on the
cold basis
, which is what makes the status == "ok" gate the wrong filter for
per-kernel attribution.

5. One thing this PR does NOT fix

Reconciling the tables above leaves a gap of exactly 3 kernels — 26 distinct
claims, 23 credited — and it is all one session.

gemma-4-26B-A4B-it/20260815T130915Z: result.json ships a populated
accepted_kernels with 1 entry (_fwd_grouped_kernel_stage1, +18.9148%),
so the collector preserves the producer's list verbatim and never opens the
journey — which holds 4 distinct kernels. The back-fill is by design a
fallback for an empty list, and this PR does not change that.

Whether a non-empty producer list should be reconciled against a richer journey
is a separate decision. Flagging it rather than folding it in here.

Reproduce

# per-workload GEAK verdicts
python3 - <<'PY'
import glob, json
from collections import defaultdict
per = defaultdict(lambda: [0, 0])
for rp in sorted(glob.glob('/shared_nfs/hyperloom-claw/*/*/geak/result.json')):
    r = json.load(open(rp)); m = rp.split('/')[3]
    per[m][0] += 1
    if (r.get("throughput_speedup") or 0) > 1.0: per[m][1] += 1
for m, (runs, up) in sorted(per.items(), key=lambda kv: -kv[1][0]):
    print(f"{m:32} {runs:3}  {up:3}")
PY

For the credited columns, run the collector on each branch:
_geak_accepted_kernels_from_journey(result, []), gated on
status in ("ok",) for main and ("ok", "no_gain") for this branch.

@iraj465

iraj465 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up: does Hyperloom's e2e gain come from GEAK's kernels?

The earlier comment counted GEAK-reported gains and Hyperloom-reported gains side
by side. It said plainly that Hyperloom's cumulative_gain_val is the
whole-session gain, not GEAK's slice. This comment measures the slice.

Scope: the 66 GEAK runs across 15 workloads in /shared_nfs/hyperloom-claw/,
measured 17 Aug 2026. The campaign is live, so counts drift upward.

The three counts

question answer
runs where GEAK reported an e2e improvement 26 of 66
runs where Hyperloom reported an e2e improvement 29 of the 39 readable (27 final.md are mode 600)
runs where Hyperloom credited that improvement to a GEAK kernel 0 of 66
runs where both reported a gain of the same order, caused by a GEAK kernel 0 of 66
GEAK claimed kernel improvements 26 distinct KEEP+integrated, in 15 runs (36 rows before twin collapse)

Per workload

GEAK+ = geak/result.jsonthroughput_speedup > 1.0.
HL+ = reports/final.mdcumulative_gain_val > 0, of the readable ones.
claims = distinct GEAK KEEP+integrated journey rows, twins collapsed.
patKP = Hyperloom integrate_patch KEEP decisions carrying a numeric gain.
both = GEAK and Hyperloom both positive. same = both positive and within 3x.

workload runs GEAK+ HL readable HL+ claims runs w/ claims patKP both same order
Qwen3-0.6B 9 4 4 4 3 2 0 2 0
Qwen3-14B-FP8 9 6 3 3 5 3 11 2 0
MiniMax-M3-MXFP4 7 0 7 4 0 0 0 0 0
Qwen3-8B 7 3 3 2 0 0 1 1 0
gemma-4-26B-A4B-it 7 2 3 3 6 3 0 2 2
DeepSeek-V4-Pro 5 0 4 3 0 0 0 0 0
Kimi-K3 5 1 3 1 1 1 1 1 1
Mixtral-8x7B-Instruct-v0.1 5 3 4 3 2 1 3 2 0
Llama-3.1-8B-Instruct 4 2 2 1 2 1 0 1 0
Qwen3.5-122B-A10B-FP8 2 2 1 1 2 2 0 1 1
Qwen3.8-2.4T-A95B-Quark-MXFP4 2 0 2 2 0 0 1 0 0
GLM-5.2-MXFP4 1 0 1 1 2 1 0 0 0
MiniMax-M3-MXFP8 1 1 0 0 3 1 0 0 0
Qwen3.5-397B-A17B-MXFP4 1 1 1 0 0 0 0 1 0
gpt-oss-120b 1 1 1 1 0 0 0 1 0
total 66 26 39 29 26 15 17 13 4

Why the last column is 4 and not 0 — and then 0 again

Four runs pass a naive test: GEAK positive, Hyperloom positive, within 3x.

workload session GEAK Hyperloom
Kimi-K3 20260816T122327Z +12.10% +14.18%
Qwen3.5-122B-A10B-FP8 20260801T034513Z +17.10% +21.71%
gemma-4-26B-A4B-it 20260814T155153Z +9.95% +8.15%
gemma-4-26B-A4B-it 20260815T130915Z +18.91% +20.87%

Read as a coincidence check, that looks like agreement. It is not. Open each
session's reports/trace/decision_trace.jsonl and list every KEEP decision
with a positive gain:

Kimi-K3/20260816T122327Z          +14.182  param  --max-running-requests 64
Qwen3.5-122B-A10B-FP8/2026...     +21.712  other  warm_replay(exact)
                                  +21.513  param  --max-model-len 6144 | env: HIP_FORCE_DEV_KERNARG=1 ...
gemma-4-26B-A4B-it/20260814...     +8.146  param  --context-length 13312
gemma-4-26B-A4B-it/20260815...    +20.871  param  --tp-size 1 --dp-size 2

Every one of the four is a server argument. None is a kernel. Each single
argument accounts for the whole session gain to three significant figures. The
numbers match GEAK's because both sides measure the same server, not because
GEAK's kernel caused Hyperloom's number.

So the answer to "both reported a gain of the same order after taking in
GEAK's kernels
" is 0 of 66.

The same result from Hyperloom's own kernel report

reports/kernel_optimization_summary.json is readable in 54 of the 66 sessions
and carries 375 by_kernel rows. Their categories:

category rows
UNATTEMPTED 357
ATTEMPTED_REJECTED 14
IN_FLIGHT 4
accepted / integrated 0

There is no gain field on these rows at all — only last_micro_speedup, present
on 18 of 375. Hyperloom's kernel report has never credited a kernel with an e2e
gain in a GEAK session.

And from the patch trace

Across the 62 GEAK sessions with a readable decision_trace.jsonl, patches land
as change == "integrate_patch":

outcome rows
REVERT 106
KEEP 29
no_promote 13

29 KEEP, of which 17 carry a numeric gain. But the row cannot tell you what
was patched:

{"change": "integrate_patch", "component": "orchestration",
 "gain_pct": 8.702391612340799, "kind": "other",
 "operation_kind": "other", "outcome": "KEEP",
 "task_id": "a3962a52e1de4d2a9d687240e19446b9"}

component is always orchestration and operation_kind is always other.
There is no kernel value anywhere in decision.kind — campaign-wide the
14,111 decision rows use other 8580, param 2862, env 1218, baseline 839,
backend 599, gemm_tuning 13.

The task_id does join, through reports/trace/proposal_task_map.jsonl to
reports/trace/conversations.jsonl. Following the +8.70% row above:

a GPU-free serving_specialist patch to wire the tuned K=5120/K=17408 rows into
the CSV/dispatch path aiter actually loads

That is GEMM-tuning plumbing, not a GEAK kernel.

The sessions barely overlap

Put GEAK's kernel claims and Hyperloom's kept patches side by side per session:

  • 15 sessions hold a GEAK KEEP kernel claim.
  • 11 sessions hold a Hyperloom integrate_patch KEEP with a gain.
  • The intersection is 1GLM-5.2-MXFP4/20260814T163244Z — and there the
    KEEP row's gain_pct is null.

The two records are describing different work.

The worked case

/shared_nfs/hyperloom-claw/GLM-5.2-MXFP4/20260814T163244Z

GEAK's journey holds 3 KEEP rows: c0_triton (+29.994%), c1_tilelang
(+2.818%), and dsa_sparse_attn_prefill_main_kernel (+29.994%, gpu_pct: null)
— the third being the alias twin of the first, which is the defect this PR and
AMD-AGI/GEAK#408 fix.

Hyperloom's reports/final.md reports 1158.0 → 1462.3 tok/s/GPU,
cumulative_gain_val: 26.28%. Its decision_trace.jsonl decomposes that
completely:

+23.895  KEEP  --kv-cache-dtype fp8_e4m3
 +2.390  KEEP  env: ROCM_QUICK_REDUCE_QUANTIZATION=INT4

kernel_optimization_summary.jsonby_kernel: [].

GEAK claimed three kernels. Hyperloom's gain contains none of them.

What this does and does not say

It does not say GEAK's kernels are worthless. It says the CI cannot
currently show whether they are worth anything, because no artifact links a GEAK
kernel to a Hyperloom-measured e2e number.

That is the honest reading of the dashboard question. The three defects filed
here are the visible part of it:

None of the three closes the gap this comment measures. Fixing them makes the
kernel list correct; it does not make the trace record which kernel produced
which e2e number. An integrate_patch decision row that names the kernel it
integrated
is the missing artifact, and it is out of scope for these PRs.

Reproduce

python - <<'PY'
import json, glob, os
sess = sorted({os.path.dirname(os.path.dirname(p))
               for p in glob.glob('/shared_nfs/hyperloom-claw/*/*/geak/result.json')})
from collections import Counter
cat = Counter()
for s in sess:
    try: d = json.load(open(f"{s}/reports/kernel_optimization_summary.json"))
    except Exception: continue
    for r in d.get("by_kernel") or []:
        cat[r.get("category")] += 1
print(len(sess), "GEAK sessions;", dict(cat))
PY
# 66 GEAK sessions; {'UNATTEMPTED': 357, 'ATTEMPTED_REJECTED': 14, 'IN_FLIGHT': 4}

GEAK's dashboard row is ~0 because of plumbing, not kernel quality. Measured
over /shared_nfs/hyperloom-claw (66 sessions with a result): GEAK is credited
12 times, +1.2% to +68.7%, and every credit is filed as a server flag. It has
13 accepted, parity-checked kernel results and Hyperloom credits 0 of them to
a kernel. Four separate places drop the identity, the baseline or the evidence.

Change 1 - attribution: the GEAK family is resolved from provenance
  The revalidation dispatches as kind="explore" with provenance
  "geak_revalidate", so _action_family saw "explore" and all 12 wins landed in
  the explore family - exactly what the comment above _ACTION_FAMILY_TABLE says
  the geak bucket exists to prevent. The provenance names come from
  _CONFIG_REPLAY_PROVENANCE in the executor that stamps them, so there is one
  list in the tree. A new phase bucket splits the gain by what was running:
  config / kernel / joint. A joint row is reported whole under joint - the
  stack rebench cannot divide it, and an invented split is worse than none.

Change 2 - dead-run recovery reads the file that exists
  _geak_reconstruct_from_disk recovered accepted kernels from
  kernel_journey.json, which is written last: 0 of 30 killed runs have one,
  while 10 have per-candidate overlay/*/integrate_result.json. Those are now a
  second source, same admission test (gate == accepted, positive
  e2e_delta_pct), tagged accepted_kernels_source=integrate_result_backfill and
  validated: False. Recovers _mxfp8_linear_kernel at +40.626% and nothing else.

Change 4 - one adoption ledger
  state.kernel_integrate_attempts is what by_kernel, kernel_lifecycle.adopted,
  attribution and the timeline all read; GEAK wrote only optimization_stack +
  geak_pending. The promotion now writes both from the same measurement.
  _record_geak_candidate also stops dropping a result whose status is no_gain
  when it carries an accepted kernel with a positive same-config delta: that
  status is a verdict on GEAK's headline basis, not on its kernels.
  Acceptances are read from BOTH lanes - accepted_heads and accepted_kernels
  differ only by which queue proposed them, and 8 of the 11 sessions with an
  acceptance carry it in accepted_heads alone. kind == "env" entries are
  excluded: they select an existing library, so they are config gain, not an
  authored kernel. Alias twins collapse on (op_kind, e2e_delta_pct), keeping
  the kernel symbol over the candidate tag.

Change 5 - prove the kernel ran before crediting it
  canonical_fingerprint covers (args, envs) only, so a revalidation that
  silently dropped the overlay still passed its own identity assertion. Of the
  62 results carrying a final_overlay, 24 name a directory that does not exist
  and 29 hold no sitecustomize.py. The dispatcher now requires a loadable
  overlay, carries the overlay's manifest digest beside the config hash,
  re-checks both after the run, and names the accepted kernels on the grid
  entry. An overlay that is the only material and cannot load falls back to the
  GEAK harness (2a) instead of measuring plain baseline under GEAK's name.

  Two traps in that gate, both found by replaying the 26 recorded dispatches:

  - Loadable is not the same as installing a kernel. GEAK also emits a
    config-only overlay - {"modules": [], "rebinds": [], "note": "config-only
    result: no kernel overlay accepted ..."} - which imports cleanly and
    installs nothing, so a sitecustomize.py check alone would label a pure
    config win as a kernel win. When a manifest is present it must now name at
    least one module, rebind or capture. An overlay with no manifest keeps the
    old behaviour: absence of evidence is not evidence of an empty overlay.
    Latent today - none of the 7 dispatched kernel overlays is empty.
  - The manifest names the bind target, not the kernel body, so it does not
    identify what would run: three unrelated sessions share one manifest digest
    because all three patch sglang.kernels.ops.attention.decode_attention. The
    digest now folds in the bodies each entry points at. Over the 7 dispatches
    with a loadable overlay this turns 5 distinct digests into 7.

The gain written into the kernel ledger is always the orchestrator-measured
rebench number, never GEAK's self-reported delta. When several kernels rode in
on one rebench, or the overlay was not proven loaded, the row is written with a
null gain and validated: False.

Verified against the campaign, no privilege escalation (all state.json and
reports/decision_trace.json are root mode 600):
  - attribution, on the 12 real wins reconstructed from coordinator.db: every
    one moves explore -> geak, 217.1 gain-points total (186.3 config, 30.9
    joint), and the joint rows name their kernel
  - ledger: 9 sessions, 11 rows, no duplicates; null gain whenever the overlay
    is not proven loaded
  - overlay gate, replayed on the 26 recorded dispatch payloads rather than on
    geak/result.json: all 26 declared an overlay, only 7 can load one; 17 drop
    to flags-only, 2 fall back to 2a, 0 cfg_hash changes, 7 distinct digests
  - dead runs: exactly 1 recovery of 30, 29 correctly stay empty
  - geak+breakdown suites: 253 passed / 33 failed, failure set identical to
    origin/main; the 10 new overlay-identity tests pass

geak/result.json is a last-write-wins snapshot - GEAK runs several e2e cycles
and overwrites it - so any offline replay keyed on that file reads the last
cycle, not the one that was dispatched. The dispatch payloads in
storage/coordinator.db are the record; the counts above use them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lishuoshuo-amd

Copy link
Copy Markdown
Contributor

PR #1209 — Blocking items

The five items below all sit in a44a190 and I think they should be resolved before merge.

B1. _geak_kernel_names() reads only one lane, so Change 1 is a no-op on real data

attribution._geak_kernel_names() reads a single field:

for item in entry.get("accepted_kernels") or []:

Across the 7 stack entries with action=geak_e2e on disk, accepted_kernels is empty in
every one of them
; 4 carry their kernels in accepted_heads. The campaign-wide
lane × kind split points the same way:

accepted_heads    kind=authored  x6
accepted_heads    kind=env       x2
accepted_kernels  kind=authored  x1
accepted_kernels  kind=None      x3

The consequence isn't under-reporting, it's a wrong label: with kernels empty and
has_config true, _geak_contribution returns config, so a row that had a kernel loaded
is filed as a pure config gain and by_kernel_id stays empty.

You already got this right in coordinator_helpers._geak_accepted_kernel_specs, which reads
both lanes and whose docstring states "8 of the 11 sessions with an acceptance carry it in
accepted_heads alone." The attribution side missed the same handling. Worth extracting one
shared name-resolution helper and calling it from both.

B2. The two alias-collapse implementations keep opposite ids, so one kernel gets two names

Actual data from GLM-5.2-MXFP4/20260814T163244Z:

journey KEEP: id='c0_triton'                            gpu_pct=20.2  gain=29.994
journey KEEP: id='c1_tilelang'                          gpu_pct=20.2  gain=2.818
journey KEEP: id='dsa_sparse_attn_prefill_main_kernel'  gpu_pct=None  gain=29.994
accepted_heads: short_name='dsa_sparse_attn_prefill_main_kernel' kind='authored' delta=29.994
  • _collapse_journey_aliases groups by gain and keeps the measured row → c0_triton,
    with the symbol moved into aliases
  • _geak_accepted_kernel_specs explicitly documents "keeping the kernel symbol over the
    candidate tag" → keeps dsa_sparse_attn_prefill_main_kernel

Both are new in this PR and they resolve in opposite directions, so collect_geak and
kernel_lifecycle.adopted will name the same kernel differently with no way to join them.
Suggest picking one convention — I'd keep the symbol and record the candidate tag in
aliases, so lookups work from either side.

B3. The kind == "env" filter cannot be applied on the journey side, leaving two admission criteria in one PR

_geak_accepted_kernel_specs excludes kind == "env", and I agree with the reasoning. But
the journey backfill can't apply the same filter — of the 36 accepted journey rows on
disk, zero carry a kind field
:

journey row top-level keys: ['backend_result', 'dispatch', 'e2e', 'gpu_pct',
                             'kernel_id', 'micro_speedup', 'name']

Concrete case, Qwen3-14B-FP8/20260816T050457Z, the 3 KEEP rows in e2e_cycle0:

c0_aiter                                            gpu_pct=0.0   gain=7.53
gemm_a8w8_blockscale_bpreshuffle_ck#1 (down_proj)   gpu_pct=None  gain=6.779   <- kind=env in stack
gemm_a8w8_blockscale_bpreshuffle_ck#2 (gate_up)     gpu_pct=None  gain=0.705   <- kind=env in stack

The collector credits 3 kernels here (the issue lists it that way too); the ledger admits 1.
Same PR, two admission tests, two answers for one run. Either admit env in both paths and
tag it, or give the journey rows a kind source so the filter can actually run there.

B4. The 2a path proves the overlay by a non-empty string, which bypasses everything Change 5 establishes

New in _validate_geak_via_geak_harness:

self._promote_geak_from_candidate(
    ps,
    measured_tput=measured,
    provenance="geak_same_harness_geak",
    # 2a replays GEAK's own launch script, so an authored overlay
    # engages by construction — a ``succeeded`` replay is the proof.
    overlay_loaded=bool(str(ps.get("final_overlay") or "").strip()),
)

overlay_loaded=True is the only thing that lets a gain be stamped validated. Measured
(after applying _normalize_geak_overlay_dir):

declared final_overlay          : 64
overlay dir exists (normalized) : 39
has sitecustomize.py            :  9
manifest names a module/rebind  :  8

Only 9 of 64 declared overlays can load. On the 2a path the other 55 dead paths would read
as "the kernel ran." The comment assumes that replaying the launch script makes the overlay
engage by construction, but when the directory itself is gone the replay installs nothing.
Suggest reusing 2b's _geak_overlay_is_loadable + digest check here so both paths hold the
same bar.

B5. Reusing the rebench_unavailable status value destroys an existing diagnostic signal

On main this value has exactly one meaning — the revalidation task could not be dispatched.

src/hyperloom/orchestrator/phases/kernel.py:838-852

            pending = dict(state.geak_pending) if isinstance(state.geak_pending, dict) else {}
            if task_id and task_state in {"queued", "running"}:
                pending["status"] = "awaiting_rebench"
                ...
                return True

            pending["status"] = "rebench_unavailable"
            ...
            pending["revalidation_error"] = str(
                (summary or {}).get("reason") or f"task settled before dispatch ({task_state or 'unknown'})"
            )[:500]

The new 2b→2a fallback writes the same value when fb.get("validated") is falsy. On disk,
20 sessions currently sit in this state and their revalidation_error takes only two
values — task settled before dispatch (cancelled) and (succeeded) — which is the only
signal available for diagnosing dispatch failures. Folding "overlay could not load" into the
same bucket makes the two causes indistinguishable. Suggest a distinct value for the new
case, e.g. overlay_unloadable.

Saptarshi Majumder and others added 4 commits August 18, 2026 12:22
Five defects found while replaying the claw campaign against this branch.
Each is keyed on evidence that holds campaign-wide, not on one session.

B1 attribution: a GEAK revalidation dispatches as a plain `explore` task,
   so its action label says `explore` and only its provenance says GEAK.
   `_entry_family` now consults provenance, reusing the existing
   `_CONFIG_REPLAY_PROVENANCE` set rather than adding a second list.
   Without this every GEAK-driven gain is bucketed as generic exploration.

B2 alias twins: GEAK records one acceptance twice -- the candidate-slot row
   carries `gpu_pct`, the resolved profiler symbol carries `gpu_pct: null`.
   `_collapse_journey_aliases` keeps the measured row (it is the only one
   holding the number) and names it by the symbol (it is the id the
   acceptance ledger keeps). Naming it by the slot tag put one kernel under
   two names in two tables of the same report.

B3 kernel_integrate_attempts: the GEAK path never wrote the ledger, so
   dead-run recovery read a file that is never produced. `_record_geak_
   candidate` now writes it. Recovers `MiniMax-M3-MXFP8/20260731T182731Z`
   (`_mxfp8_linear_kernel`, +40.626%).

B4 status gate: `no_gain` is GEAK's verdict on its own headline number, not
   on the kernels it accepted. A run can report `no_gain` on the promoted
   basis while carrying an accepted kernel with a positive parity-checked
   same-config A/B. The gate now admits on `_geak_has_accepted_kernel`, and
   the rebench downstream still decides. Of 38 `no_gain` results in the
   campaign exactly one flips (`GLM-5.2-MXFP4/20260814T163244Z`,
   `dsa_sparse_attn_prefill_main_kernel`, +29.994%); the other 37 stay
   declined.

B5 overlay gate: a config-only `_overlay_manifest.json` imports cleanly and
   installs nothing, so "the overlay imported" was never evidence a kernel
   ran. `_geak_overlay_is_loadable` requires `sitecustomize.py` and at least
   one module or rebind; `overlay_loaded_2a` also checks the digest matches
   what the task was dispatched with. 64 runs declare `final_overlay`, 9 are
   loadable -- 55 false "kernel ran" credits removed.

`_geak_has_accepted_kernel`, `_geak_overlay_is_loadable` and
`_geak_overlay_digest` live in `loop/coordinator_helpers.py` as the single
owner; `phases/kernel.py` and `loop/writeback.py` import them.

Tests: three new files (37 tests) plus two assertion updates in
`test_geak_breakdown_unit.py` that still expected the pre-B2 spelling.
80 tests pass across the five GEAK test files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Re-running the collector A/B over all 98 claw sessions showed
``kernels_optimized`` falling 31 -> 26 on the recovery path, and one session
(Qwen3-14B-FP8/20260814T163051Z) going 2 -> 0 while discarding a +14.924% KEEP.
That read as a regression. It is not.

The journey holds an alias twin whose resolved symbol is a CK library GEMM.
``result.json`` ships an empty ``accepted_kernels`` and puts the win in
``accepted_heads`` with ``kind: env``. The collapse names the surviving row by
the symbol, the kind join then finds GEAK's own declaration, and the row is
excluded from the kernel bucket -- correctly. The e2e gain is untouched; it is
attributed to config, which is what it is. ``main`` reported 2 only because it
neither collapsed the twin nor read the kind.

Checked campaign-wide rather than on this one run: of every symbol
``result.json`` names across the 68 sessions holding one, exactly 2 are not
covered by a kept row, and both are declared ``env``. Non-env exclusions: 0.

The two tests pin both directions, because the exclusion is only safe while it
stays narrow: a declared ``env`` twin collapses to 0, and the same twin declared
``authored`` survives at 1 with ``kind_source: result_json``. A row no lane
names stays admitted as ``kind_source: absent`` -- guessing "env" there would
delete real kernels from dead runs, which is the loss this collector recovers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The kind join read only `result.json`. That file is rewritten once per
cycle and the last write wins, so a later cycle that accepts nothing
blanks the lanes an earlier cycle declared. On
Qwen3-14B-FP8/20260816T050457Z it names 0 lanes while the run accepted
three rows: every recovered row came out `kind_source: absent` and the
`kind == "env"` exclusion could not run on them at all.

The `action == "geak_e2e"` entries of `state.optimization_stack` carry
the same two lanes in the same spelling -- KernelPhase copies them from
the result of *that* cycle -- and the stack is append-only, so it keeps
what the file lost. `collect_geak` already receives the parsed state, so
the second source costs one argument threaded through, not a new reader.

Precedence keeps the run's own words authoritative: a declared kind beats
an undeclared one whichever artifact holds it, and between two
declarations `result.json` wins. So the stack can only fill gaps, never
overwrite a published kind.

`kind_source` gains `stack` / `stack_undeclared` beside the existing
`result_json` forms, so a stack-sourced kind is never reported as
something result.json said, and the untyped residual stays countable.

Replay over all 98 claw sessions is byte-identical (26 recover, 23 live):
every campaign `state.json` is root mode 600, so the replay synthesises
state from `result.json` and cannot reach a stack. The change is
strictly additive there; the three new unit tests cover the behaviour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@iraj465

iraj465 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

Re: the five blocking items

All five are fixed. Branch HEAD is now ea5500454. B1, B2, B4 and B5 are in
749dd9779; B3 needed new code and is in ea5500454. Numbers below are
re-measured today over all 98 hyperloom-claw sessions.

B1 — both lanes

Fixed. attribution._geak_kernel_names() and _geak_contribution() now read
accepted_kernels and accepted_heads, the same pair
_geak_accepted_kernel_specs reads.

main branch
_geak_contribution helper does not exist config 89 / kernel 9
sessions with >=1 GEAK kernel name 0 9

Your diagnosis was right: the label was wrong, not the count. Nine sessions
were filed as pure config gain.

B2 — one name per kernel

Fixed, in your direction. _collapse_journey_aliases keeps the measured row
but renames it to the resolved symbol, and puts the candidate tag in
aliases. On GLM-5.2-MXFP4/20260814T163244Z the collector and the ledger
both now say dsa_sparse_attn_prefill_main_kernel.

B3 — the journey rows now have a kind source

This is the item that needed new code, and your last sentence named the fix.

The kind join read only result.json. That file is rewritten once per cycle
and the last write wins. A later cycle that accepts nothing blanks the lanes an
earlier cycle declared. So on your case the file names 0 lanes.

The action == "geak_e2e" entries of state.optimization_stack carry the same
two lanes, in the same spelling. KernelPhase._record_geak_win copies them
from the result of that cycle (phases/kernel.py:1398), and the stack is
append-only. It keeps what the file lost. collect_geak already receives the
parsed state, so this cost one argument threaded through, not a new reader.

Your case, on the branch:

result.json lanes: accepted_kernels=0 accepted_heads=0

no stack:                                                  with the geak_e2e stack entry:
  c0_aiter                                 src=absent        c0_aiter          kind=None src=absent
  gemm_..._ck#1 (down_proj-shaped)         src=absent
  gemm_..._ck#2 (gate_up-shaped)           src=absent
                                                           kernels_optimized: 3 -> 1

Two details, so the record is straight:

  1. The ledger admits 0 for that run, not 1. _geak_accepted_kernel_specs
    on the flushed result.json returns [], because the file names no lanes.
    Both sides read the same two lanes now. Where the file is empty, the ledger
    has nothing to admit and the collector recovers from the journey. That is
    the difference this PR exists to create.
  2. I could not read your kind=env in stack myself. Every campaign
    state.json is root mode 600. I trust the stack because the writer copies
    both lanes verbatim, not because I inspected this run's copy. The block
    above uses the entry that writer produces.

Precedence keeps GEAK's own words authoritative. A declared kind beats an
undeclared one whichever artifact holds it. Between two declarations
result.json wins. So the stack can only fill gaps.

kind_source gains stack and stack_undeclared beside the existing
result_json forms. A stack-sourced kind is never reported as something
result.json said, and the untyped residual stays countable:

recover path, 98 sessions: result_json 7 | result_json_undeclared 4 | absent 15  = 26 admitted

Replay over all 98 sessions is byte-identical to the previous commit. That
is expected, and it is the honest limit of the evidence: the replay synthesises
state from result.json, so it never reaches a stack. The change is strictly
additive there. Three new unit tests cover the behaviour, including the
precedence rule.

B4 — 2a holds the same bar as 2b

Fixed. The 2a path now calls _geak_overlay_is_loadable on the normalized
directory, then requires the overlay digest to match the one recorded before
the replay. Re-measured: 64 declared, 9 loadable. The other 55 no longer
read as "the kernel ran."

B5 — distinct status value

Fixed. The new case writes overlay_unloadable, not rebench_unavailable.
phases/kernel.py maps only geak_overlay_unloadable to it, so the 20
sessions in the dispatch-failure bucket keep their meaning.


Tests: 59 pass across test_geak_breakdown_unit.py and
test_geak_acceptance_identity.py; 371 pass across the geak / breakdown /
attribution selection. One unrelated failure,
test_credentials_endpoint_resolution_and_geak_sync, reproduces on clean
main and is caused by ANTHROPIC_BASE_URL in the environment.

@iraj465

iraj465 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

A/B on the claw CI corpus: what this PR changes about GEAK credit

Control = the already-run Hyperloom CI sessions replayed through main @72c50eaaf. Test = the identical sessions replayed through this branch @ea5500454. Same corpus, same instant; each arm was verified to import its own tree. No kernel was re-run. This PR does not create speedups — it changes whether Hyperloom credits the ones GEAK already produced.

Corpus: 99 GEAK session dirs under /shared_nfs/hyperloom-claw/, 68 carrying geak/result.json, measured 18 Aug 2026. The campaign is live, so the count drifts upward; both arms were measured in one pass.

1. Census

measure control (main) test (this PR)
GEAK attribution row helper absent_geak_contribution does not exist on main, so all 99 runs are unattributed kernel 9 / config 90
runs naming >=1 GEAK kernel 0 9
overlay handling 64 declared, all 64 dispatched uncheckedmain has no loadability gate 64 declared, 9 loadable, 55 refused
no_gain runs admitted 0 of 38 — main line 1154 declines every non-ok 1 of 38
duplicate kernel rows 13 0
library pick inside the kernel bucket 1 run (CK GEMM) 0 — reclassified config

2. Where GEAK actually moves Hyperloom e2e

Runs the PR attributes to a kernel, where the overlay can load and the measured pair is a real gain. run e2e is computed from result.json's own final_throughput_tok_s / baseline_throughput_tok_snot from the published throughput_speedup, which is unreliable (GEAK #406).

session kernel credited micro kernel e2e delta run e2e (measured) run published
GLM-5.2-MXFP4/20260814T163244Z dsa_sparse_attn_prefill_main_kernel 2.20x +29.99% +47.58% 0.9877
Kimi-K3/20260816T122327Z _fwd_grouped_kernel_stage1 (+_fwd_kernel_stage2) 2.69x +11.71% +12.31% 1.121
MiniMax-M3-MXFP8/20260801T023259Z _mxfp8_linear_kernel 2.39x +11.69% +13.87% 1.1714
Qwen3.5-122B-A10B-FP8/20260801T034513Z vllm::unified_attention_with_output (decode paged attn) 1.67x +16.84% +16.73% 1.171
Qwen3.5-122B-A10B-FP8/20260805T080211Z kernel_paged_attention_2d (full-attention) 2.15x +5.96% +8.07% 1.1142
gemma-4-26B-A4B-it/20260814T155153Z _fwd_grouped_kernel_stage1 [full_attention] 1.66x +10.38% +10.51% 1.0995

6 runs. Measured e2e spans +8.07% to +47.58%; the arithmetic mean is +18.18%. These are six different models, so the figures do not compose into a single number — read them per row. run e2e is the whole run, which includes any config win; the kernel's own parity-checked share is the kernel e2e delta column.

On main, every one of these six carries no GEAK attribution at all.

3. Named by the PR, but deliberately NOT counted as e2e

Listed because section 2 alone would overstate the PR.

session why it is not e2e credit
Qwen3-0.6B/20260730T213628Z the run's measured pair is -1.76%, a slowdown, although result.json publishes 1.0172 — GEAK #406
Qwen3-0.6B/20260805T130336Z the run's measured pair is -1.39%, a slowdown, although result.json publishes 1.0199 — GEAK #406
gemma-4-26B-A4B-it/20260815T130915Z overlay declared but not loadable — this PR's writeback gate refuses to dispatch it, so the +18.91% the run measured cannot be claimed for a kernel
Qwen3-14B-FP8/20260816T050457Z no_gain with baseline == final exactly (1653.083) — the per-kernel deltas never reached e2e. The PR makes them visible, not credited.
gemma-4-26B-A4B-it/20260816T112750Z no_gain with baseline == final exactly (4543.051) — the per-kernel deltas never reached e2e. The PR makes them visible, not credited.
MiniMax-M3-MXFP8/20260731T182731Z dead run recovered — _mxfp8_linear_kernel (+40.63%, 1.94x) sat on disk and was unreadable by main. The run has no result.json throughput, so this recovers a record, not a gain.

4. False credit this PR removes

main credits 15 rows the PR drops, summing to 189.53% of e2e delta. Every row is accounted for — none is a dropped win:

session dropped row e2e reason
GLM-5.2-MXFP4/20260814T163244Z c0_triton 29.994% duplicate of dsa_sparse_attn_prefill_main_kernel — identical e2e and micro; one gain counted twice
Kimi-K3/20260816T122327Z decode_attention_grouped_mla 11.710% duplicate of _fwd_grouped_kernel_stage1 (+_fwd_kernel_stage2) — identical e2e and micro; one gain counted twice
Kimi-K3/20260816T122327Z fwd_grouped_kernel_stage1 (+_fwd_kernel_stage2) 11.710% duplicate of _fwd_grouped_kernel_stage1 (+_fwd_kernel_stage2) — identical e2e and micro; one gain counted twice
MiniMax-M3-MXFP8/20260801T023259Z c0_flydsl 11.690% duplicate of _mxfp8_linear_kernel — identical e2e and micro; one gain counted twice
MiniMax-M3-MXFP8/20260801T023259Z mxfp8_linear_kernel 11.690% duplicate of _mxfp8_linear_kernel — identical e2e and micro; one gain counted twice
Qwen3-0.6B/20260730T213628Z fwd_kernel (prefix_prefill attention) 0.745% duplicate of _fwd_kernel (prefix_prefill attention) — identical e2e and micro; one gain counted twice
Qwen3-0.6B/20260730T213628Z prefix_prefill 0.745% duplicate of _fwd_kernel (prefix_prefill attention) — identical e2e and micro; one gain counted twice
Qwen3-14B-FP8/20260814T163051Z c1_ck 14.924% kind: env library selection (CK GEMM), not an authored kernel — the run stays credited to GEAK as contribution=config
Qwen3-14B-FP8/20260814T163051Z ck_gemm_a8w8_blockscale_bpreshuffle 14.924% kind: env library selection (CK GEMM), not an authored kernel — the run stays credited to GEAK as contribution=config
Qwen3.5-122B-A10B-FP8/20260801T034513Z c0_triton 16.835% duplicate of vllm::unified_attention_with_output (decode paged attn) — identical e2e and micro; one gain counted twice
Qwen3.5-122B-A10B-FP8/20260805T080211Z kernel_paged_attention_2d 5.965% duplicate of kernel_paged_attention_2d (full-attention) — identical e2e and micro; one gain counted twice
gemma-4-26B-A4B-it/20260814T155153Z fwd_grouped_kernel_stage1 [full_attention] 10.383% duplicate of _fwd_grouped_kernel_stage1 [full_attention] — identical e2e and micro; one gain counted twice
gemma-4-26B-A4B-it/20260814T155153Z fwd_grouped_kernel_stage1_global 10.383% duplicate of _fwd_grouped_kernel_stage1 [full_attention] — identical e2e and micro; one gain counted twice
gemma-4-26B-A4B-it/20260815T130915Z fwd_grouped_kernel_stage1 18.915% duplicate of _fwd_grouped_kernel_stage1 — identical e2e (micro None vs 1.9641); one gain counted twice
gemma-4-26B-A4B-it/20260815T130915Z fwd_grouped_kernel_stage1_c0_triton 18.915% duplicate of _fwd_grouped_kernel_stage1 — identical e2e and micro; one gain counted twice

13 rows / 159.68% were duplicate counts of a gain already credited once. 2 rows / 29.85% are the CK GEMM library pick, which stays credited to GEAK but as config rather than as a kernel. Nothing here is a real gain lost.

5. What did not change

control test
status census {None: 31, 'no_gain': 38, 'timeout': 2, 'error': 2, 'ok': 26} {None: 31, 'no_gain': 38, 'timeout': 2, 'error': 2, 'ok': 26}

Same corpus, same statuses. This PR reads the record; it does not re-run or re-judge anything.


Reproduce with full.py <tree>/src <arm> over /shared_nfs/hyperloom-claw/*/*/geak; both arms assert the same session count before emitting.

The coverage gate failed at 89.98% against fail-under=90.00. The two units
this PR adds to carry a GEAK kernel from an acceptance to a named row were
the largest uncovered blocks it introduced:

  * _geak_accepted_kernel_specs -- the whole selection loop (lanes, env
    exclusion, non-positive deltas, alias-twin collapse) was reached only
    through its early returns.
  * KernelPhase._record_geak_adopted_kernels -- the per-kernel ledger writer,
    entirely uncovered. by_kernel, kernel_lifecycle.adopted and the
    attribution split all read what it writes.

Writing the ledger tests surfaced a real defect: best_gain_pct was set to the
current rebench gain, while the canonical writer in _kernel_decisions.py
computes it as a max over attempts. Both feed the same downstream field, so a
second, worse rebench lowered the kernel's recorded best. Now a max, keeping
None (rather than that writer's 0.0 default) for the unattributable case --
"not attributable" is not the same claim as "no gain".

Measured by combining this run's four CI coverage shards with the new tests:
89.98% -> 90.04% (7485 -> 7438 missing lines).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@iraj465

iraj465 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

Coverage gate cleared, and one defect it surfaced

coverage (Python 3.10) and coverage (Python 3.11) were failing at
89.98% against fail-under=90.00.

The cause was this PR's own code, not the baseline. breakdown/collectors/* is
omitted from the measured denominator (pyproject.toml), so the three collector
files — the PR's largest — contribute nothing. Of the measured files, the PR
added 76 lines that no test reached. The two biggest blocks were the units
that carry a GEAK kernel from an acceptance to a named row:

unit what was uncovered
_geak_accepted_kernel_specs the entire selection loop — both lanes, kind: env exclusion, non-positive deltas, alias-twin collapse. Only its early returns were reached.
KernelPhase._record_geak_adopted_kernels the per-kernel ledger writer, wholly uncovered. by_kernel, kernel_lifecycle.adopted and the attribution split all read what it writes.

test_geak_adoption_ledger.py adds 20 tests over both.

A real defect the tests surfaced

best_gain_pct was set to the current rebench gain. The canonical ledger
writer, _kernel_decisions.py, computes the same field as a max over
attempts
. Both feed the same downstream field, so a second, worse rebench
lowered the kernel's recorded best.

It is now a max. None is kept rather than that writer's 0.0 default: here it
means not attributable, which is not the same claim as no gain.

Numbers

Measured by combining this run's four CI coverage shards with the new tests,
then confirmed by CI:

before after
TOTAL 89.98% (7485 missing) 90.04% (7436 missing)
loop/coordinator_helpers.py 91.61% (52) 95.32% (29)
phases/kernel.py 77.73% (363) 79.22% (339)
uncovered lines added by this PR 76 18

The 18 that remain are the 2b-declined → GEAK-harness fallback block, which
sits inside _run_geak_kernel_phase and needs a full async phase fixture rather
than a unit.

No behaviour in the A/B changes: the posted per-kernel and e2e numbers are
unaffected by either edit.

@lishuoshuo-amd

Copy link
Copy Markdown
Contributor

Blocking: the conflict is semantic — #1188 removed the interface this PR builds on

mergeStateStatus is DIRTY, conflicting in loop/writeback.py and phases/kernel.py
the two files carrying this PR's core changes. c92784cbf (#1188) reshaped the promote path
and deleted the parameters this PR threads through it.

On origin/main:

def _promote_geak_from_candidate(self, result, *, measured_tput) -> None:   # no provenance
    ...
    self._lift_to_current_best("geak_e2e", measured, {...}, entry_extra={...})
    self._update_cumulative_gain_validated(measured, source="geak_e2e_promote")

cumulative_gain_provenance no longer exists in state/shared_state.py at all.

This PR still assumes a provenance: str keyword on both promote call sites, a hand-built
stack entry, direct assignment of cumulative_gain*, and provenance forwarded into
_record_geak_adopted_kernels as the ledger's decision_reason. So the rebase is a rewrite
of that block, not a conflict resolution — mainly: how overlay_loaded reaches the entry now
that _lift_to_current_best owns it, what replaces provenance, and where decision_reason
comes from.

entry_extra still carries accepted_kernels and accepted_heads, so the stack-sourced
kind join added for B3 survives the rebase.

I'd land the rebase before anything else. I have four non-blocking findings queued, but all
four sit inside the block this rewrite touches.

Resolves the two conflicts in the GEAK promote path, both created by #1188's
correctness sweep landing on the same function this branch extends.

phases/kernel.py, _promote_geak_from_candidate:
  main added a KEEP guard (a rebench that does not beat current_best must not
  overwrite the headline) and dropped the then-unused `provenance` parameter.
  This branch needs `provenance` and `overlay_loaded` to record the adoption
  ledger. Kept both sides: main's KEEP guard is untouched, and the two
  parameters return -- with `provenance` now DEFAULTED rather than required,
  so main's callers in writeback.py and test_geak_gain_alignment.py continue
  to work unchanged.

loop/writeback.py:
  restores the two keyword arguments at the promote call sites, matching the
  signature above.

143 GEAK tests pass, including main's test_geak_gain_alignment.py, which
omits `provenance` and so exercises the new default.
@iraj465

iraj465 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased onto main (was 64 behind) and re-ran the full suite on both arms.

arm passed failed
main @ 8a2fea5 10892 21
this branch 10972 21

Failure sets: 20 identical, 2 swapped. Both swapped tests are pre-existing flakes in files this branch does not touch (git diff --name-only origin/main...HEAD matches neither):

test isolation, branch isolation, clean main
test_concurrent_patchers_converge_to_single_patch 0/3 pass 1/3 pass — flaky on main too
test_kill_my_spawned_server_reaps_grandchildren 3/3 pass

The 20 common failures are all in test_preflight_auth_override.py, test_common_utils.py, test_coverage_gap_units.py, test_grid_runner.py and test_profile_and_kernel_handlers.py — unrelated to this change and failing on main.

The two stale alias-twin assertions now expect the resolved symbol (dsa_sparse_attn_prefill_main_kernel) and pass, so this repo and GEAK #408 agree on one spelling.

@iraj465

iraj465 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

@lishuoshuo-amd both resolved. 82dd83684 merges origin/main (was 64 behind), so mergeStateStatus is MERGEABLE again — and I checked the reconciliation is semantic, not just textual.

On #1188 / c92784cbf. You were right that the interface moved under this PR. Post-merge state:

your point now
cumulative_gain_provenance gone from shared_state.py 0 hits anywhere in src/hyperloom/orchestrator/
PR assumes a provenance: str keyword on the promote path the branch now defines it on _promote_geak_from_candidate as a defaulted keyword (provenance: str = "geak_e2e_promote"), so main's two call sites that pass nothing are unaffected
direct assignment of cumulative_gain* removed; goes through main's _update_cumulative_gain_validated(measured, source=...)
hand-built stack entry dropped in favour of main's _lift_to_current_best

On B1 — you were right, and the fix is the label, not the count. _geak_kernel_names now reads both lanes in ledger order and excludes kind == "env" (those select an existing library or server flag, so counting them as kernels would double-book the config win). The docstring carries your census.

Suite, both arms, after the rebase:

arm passed failed
main @ 8a2fea5 10892 21
this branch 10972 21

Failure sets: 20 identical, 2 swapped, and neither swapped file is touched by this branch. I did not assume they were flakes — test_kill_my_spawned_server_reaps_grandchildren passes 3/3 in isolation, and test_concurrent_patchers_converge_to_single_patch fails 2 of 3 on a clean main worktree too. Both pre-existing.

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.

2 participants