Skip to content

Commit 7b96805

Browse files
kmbandyclaude
andcommitted
docs(dsws): rolling dyn-VGPR architecture handoff + wedge instrumentation + race harness
Root-caused the residual CONV=1-dormant hang (post entry-fix b01c722) to the KNOWN multi-grower dyn-VGPR collision (ISA §3.3.3.2): occ_kernel_dsws.s .Lcompute_grow is a bare s_alloc_vgpr SCC-retry with no sum-envelope and no stagger, so all NCOMP compute waves grow to NFV=112 in lockstep and collide. Confirmed by: offline std::thread QUIESCE/epoch model (0/400 stalls) + Codex static review ruling OUT the protocol logic; and a heisenbug — adding DIAG wedge-frame instrumentation shifted timing and the CONV=1/DIAG=1 4c2a2b bin ran CLEAN (ok=1536 bad=0, all chunks, dmesg silent) where the stock bin hung. kmbandy confirmed the collision and the fix direction. Contents: - HANDOFF_DSWS_ROLLING_DYNVGPR.md — architecture (NOT yet detailed spec) for the fix: one pool + Σ≤BUDGET sum-envelope, real split-K (n_kseg>1) for per-kseg grow→flush-to-C→immediate shrink, every compute grow routed through the shared vgpr_reserved envelope (collision unreachable by construction), stagger for compute-saturation + collision-avoidance + feed fungibility, instrumentation baked in. Reconciles with SPEC_WAVESPEC traveling-peak (KG 1fdd5784), MAD305_DSWS_MASTER split-K framing, and the vgpr_reserved envelope. Full debug arc, references, safety rules, next-session tasks. - occ_kernel_dsws.s — wedge-frame DIAG instrumentation (epoch_mark macro + claimer advance-gate counter snapshot into host-streamed occ slots). CONV=0 and CONV=1/DIAG=0 .text byte-IDENTICAL to HEAD; markers only at CONV=1 && DIAG=1. RGA 0-spill, max-live 84. - test_dsws_quiesce_race.cpp — offline std::thread claimer+followers QUIESCE/epoch race harness (400 trials × {seq_cst, relaxed}, 0 stalls — ruled out the protocol race). Not-ours siblings (occ_kernel_coop.s, occ_dispatch.cpp, fp8_oracle.*) left untouched/unstaged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0132aDSBLwusCJ4KzHQTnvdu
1 parent a7212a6 commit 7b96805

3 files changed

Lines changed: 483 additions & 3 deletions

File tree

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
# HANDOFF — DSWS rolling dyn-VGPR (the sum-envelope grow economy)
2+
3+
**Written 2026-07-02** for a fresh session that will write the detailed spec + plan + implementation.
4+
This doc gives you the **architecture** (agreed with kmbandy) and the full **state of the world** so you
5+
can start cold. It deliberately stops short of the detailed transcription spec — that is YOUR first task.
6+
7+
Everything lives in `ggml/src/ggml-cuda/aiter-integration/rdna4_fp8_gemm/spike/dvgpr_occ/` unless noted.
8+
The kernel under work is **`occ_kernel_dsws.s`** (the "v2 substrate", `--dsws2` path). Do **not** touch
9+
`occ_kernel_coop.s`, `occ_dispatch.cpp`, `fp8_oracle.*` — they are shared/not-ours siblings (leave dirty,
10+
never stage).
11+
12+
---
13+
14+
## 0. TL;DR — what to do next
15+
16+
1. Read this doc, then the referenced repo docs (§7) and the SDD ledger (`.superpowers/sdd/progress.md`).
17+
2. Write the **detailed design spec** for the rolling dyn-VGPR grow economy (§4 is the architecture; you
18+
turn it into exact LDS offsets, register assignments, macro definitions, asm placement, CPU-model
19+
interfaces). Use the brainstorming→writing-plans flow. Save to `docs/superpowers/specs/`.
20+
3. Then plan (`docs/superpowers/plans/`) and implement, offline gates first, one supervised GPU oracle run.
21+
22+
**The one-line problem:** the DSWS compute waves currently grow to peak (`NFV=112`) via a bare
23+
`s_alloc_vgpr` SCC-retry with **no sum-envelope and no stagger**, so all `NCOMP` compute waves grow in
24+
lockstep and collide on the shared dyn-VGPR pool → intermittent forward-progress hang (ISA §3.3.3.2).
25+
**The fix:** route every compute grow through the shared `vgpr_reserved` sum-envelope + stagger the
26+
grows, so peaks never all coincide and freed budget flows to whatever role the bottleneck needs.
27+
28+
---
29+
30+
## 1. Where we are (git + disk state, 2026-07-02)
31+
32+
- **HEAD = `a7212a605`** on branch `feat/dsws-phaseb-conversion` (base `66eec7f54`).
33+
- Relevant commits (newest first):
34+
- `a7212a605` docs(dsws): correct entry != re-dispatch in pool-economy spec + plan
35+
- `b01c722df` **fix(dsws): route first-time wave entry through _alloc/_init** — the Pool-T7 *brick* fix
36+
(see §3). Message overstates it as "the Pool-T7 brick" fix: it fixed the desktop-**brick** failure mode
37+
but NOT the residual hang. Leave the commit; the record is corrected in the ledger + KG.
38+
- `3dbb8c985` feat(dsws): pool-economy offline machinery (Tasks 1-6)
39+
- `5421751` feat(dsws): CPU model for Phase-B snapshot/quiesce
40+
- **Uncommitted OURS (working tree):**
41+
- `occ_kernel_dsws.s` — the **wedge-frame DIAG instrumentation** (see §6). Byte-identity verified: at
42+
`DSWS2_CONV=0` and at `DSWS2_CONV=1/DIAG=0` the `.text` sha is IDENTICAL to HEAD (`e5ec5e50` /
43+
`e296b846`). The markers only materialize at `CONV=1 && DIAG=1`. **Safe to commit.**
44+
- `test_dsws_quiesce_race.cpp` (untracked) — the offline `std::thread` QUIESCE/epoch race harness (§5).
45+
- `lean_bounds_sim.cpp` (untracked) — pre-existing, not ours, ignore.
46+
- **Installed bins:** all three `occ_dsws2_{4c2a2b,6c1a1b,2c3a3b}_gd.bin` restored to the **safe CONV=0
47+
4840B** build (`e5ec5e50` / `bb8cb230` / `066b73a4`). No CONV=1 bin is installed (footgun rule).
48+
- The 4 not-ours siblings are dirty; never stage them.
49+
50+
---
51+
52+
## 2. What DSWS is (one paragraph, so you have the frame)
53+
54+
**Dynamic-Split Wave-Specialization** — one persistent-wave fp8 GEMM kernel on gfx1201 (RDNA4/R9700,
55+
wave32) that re-balances its mix of **{fat compute / lean A-feed / lean B-feed}** wave roles to the
56+
runtime bottleneck, using raw-PM4-armed **dyn-VGPR** (`s_alloc_vgpr`, which HIP cannot express — the moat)
57+
to make the per-SIMD VGPR budget **fungible across roles**. One WG = `WAVES` waves: wid0 = pinned
58+
"claimer" (super-tile broadcaster + B-feed-class), the rest are followers in three roles. Coordination is
59+
**barrier-free** (no `s_barrier`) via LDS atomics + epoch polling. Split-K decomposes K into `SEGK`-sized
60+
segments accumulated into C via `global_atomic_add_f32` (ksi-independent C term). Role mix is written
61+
`{NCOMP,NAFEED,NBFEED}` (e.g. `4c2a2b` = 4 compute, 2 A-feed, 2 B-feed). Phase-A = static substrate
62+
(`DSWS2_CONV=0`, GPU-green). Phase-B = the adaptive conversion economy (`DSWS2_CONV=1`).
63+
64+
Read `MAD305_DSWS_MASTER.md` for the full vision; `SPEC_DSWS_SUBSTRATE_V2.md` for the substrate;
65+
`SPEC_DSWS_PHASEB_CONVERSION.md` for the conversion economy.
66+
67+
---
68+
69+
## 3. How we got here — the debugging arc (so you don't re-walk it)
70+
71+
1. **Pool-T7 first GPU gate (CONV=1, conversions dormant) BRICKED** — MODE1 reset, rebooted the desktop
72+
(gfx1201 shares the graphics ring with Hyprland). CONV=0 was green across all mixes.
73+
2. **Entry-fix (`b01c722df`)** — root-caused offline: the CONV=1 **seed block routed first-time wave entry
74+
through the `.Ldispatch` re-dispatch trampoline**, which lands on `_follow` and skips `_alloc`/`_init`
75+
(the `s_alloc_vgpr 32` handshake, the `INITFLAG==0xACED` rendezvous, and `s35=0`). Re-pointed the seed
76+
arms at the full role entry (`.Lcompute/.Lafeed/.Lbfeed`). This **fixed the desktop-BRICK failure mode**
77+
— confirmed on silicon (re-attempt #2: dmesg silent, chunk watchdog self-aborted cleanly at ~24.8s).
78+
3. **BUT a residual non-bricking hang remained** — chunk 1 (8 super-tiles) completes, the *next* dispatch
79+
stalls at its first super-tile (`occ[20]` frozen, `occ[0]=1` claimer live). CONV=0 control ran clean
80+
(`ok=1536 bad=0`), so CONV=1-dormant has a real liveness regression.
81+
4. **Offline analysis RULED OUT the protocol logic:** a faithful `std::thread` model of the claimer+
82+
followers QUIESCE/epoch handshake (`test_dsws_quiesce_race.cpp`) → **0/400 stalls** (seq_cst *and*
83+
relaxed). Codex static review (task-mr3u2ig0) independently found no source-level race. Snapshot LDS
84+
offsets don't collide; snapshot values are constant in the dormant case (so `s50 == CONV=0`);
85+
`lds_put/get/fetch_add` all `s_wait_dscnt` (ordering HW-enforced). Logic is sound.
86+
5. **SKIPQ bisection BRICKED (do NOT repeat):** an uncommitted `DSWS2_DBG_SKIPQ` knob forced `s51=1` to
87+
advance on the snapshot sentinels alone. Dispatched → hard hang (~8 min) → brick. **Disabling the
88+
quiesce gate removes the chunk-watchdog's clean self-abort** and re-introduces the straggler bug the
89+
gate prevents. **Never disable the quiesce gate on the compositor card.**
90+
6. **HEISENBUG → root cause:** adding the wedge-frame DIAG instrumentation (extra occ stores in the
91+
claimer poll loop + per-role markers) shifted timing and the CONV=1/DIAG=1 bin ran **CLEAN**
92+
(`ok=1536 bad=0`, all 4 chunks, dmesg silent) where the stock bin hung. A timing-sensitive race that
93+
instrumentation perturbs away ⇒ **not a logic bug**. kmbandy confirmed: it's the **known multi-grower
94+
dyn-VGPR collision** — all `NCOMP` compute waves grow to 112 in lockstep and collide.
95+
96+
**Root cause (CONFIRMED, KG `21cc0d63`):** `occ_kernel_dsws.s` `.Lcompute_grow` is a **bare
97+
`s_alloc_vgpr NFV` SCC-retry with no sum-envelope reservation and no stagger**. The `vgpr_reserved`/`VRESV`
98+
envelope exists but only gates **role-conversion** grows, not the per-rowblk compute grow. All compute
99+
waves issue `s_alloc_vgpr` simultaneously → ISA §3.3.3.2 (HW deadlock-avoidance guarantees only *one*
100+
wave/SIMD can reach max) → intermittent hang, worsened by the shared B-ring (`RINGD=2`) interaction.
101+
102+
---
103+
104+
## 4. THE ARCHITECTURE (the fix) — build the detailed spec from this
105+
106+
The design kmbandy and I converged on. **One pool, one law, split-K churn, stagger for saturation +
107+
safety + fungibility.** This *unifies* the per-compute-wave grow with the role-conversion economy: they
108+
are the same pool discipline, not two systems.
109+
110+
### 4.1 One pool, one invariant
111+
A single per-SIMD VGPR budget `BUDGET`. The only governing law:
112+
```
113+
Σ instantaneous allocations over all resident waves ≤ BUDGET (at every instant)
114+
```
115+
Every grow — a compute wave taking a kseg, OR a feed wave converting to compute — reserves against the
116+
**same** `vgpr_reserved` counter. VGPR is fungible without regard to who grows next. That fungibility IS
117+
the adaptive substrate.
118+
119+
### 4.2 Real split-K (n_kseg > 1) makes the pool churn
120+
Old full-K behavior: a compute wave grabs its fp32 accumulators and camps at peak for ~95% of the K-loop
121+
(square wave — this is the `MAD305_DSWS_MASTER.md:78-81` "staggering buys nothing" case). With **real
122+
split-K** each compute wave: **grow → compute ONE kseg → flush that partial to C via
123+
`global_atomic_add_f32` → shrink to lean IMMEDIATELY → loop**. No accumulators persist across a wave's
124+
ksegs (the accumulate-into-C path split-K already uses across waves handles the sum), so peak is a *brief*
125+
window, duty drops, and the pool has genuine free headroom cycling through it. Split-K is **already
126+
plumbed** in the substrate: `n_kseg` is derived in-kernel from `KT` and `KSEG_STEPS=SEGK/16`; `DECODE_STI`
127+
splits `sti → (t, ksi)` and handles `n_kseg=1` for free (`shift=0, mask=0`). We've only ever run
128+
`n_kseg=1` (degenerate high-duty). The real thing runs `n_kseg > 1`.
129+
130+
### 4.3 Every grow through the shared sum-envelope (the collision fix)
131+
Replace the bare `.Lcompute_grow` SCC-retry with the **enveloped reserve→grow→…→shrink→release**, the
132+
same primitive `conv_apply` already uses for role conversion:
133+
```
134+
reserve : old = atomic_add(vgpr_reserved, NFV-VLEAN); if old+(NFV-VLEAN) > BUDGET { atomic_sub; spin-at-lean; retry }
135+
grow : s_alloc_vgpr NFV (SCC-retry stays as the hardware backstop)
136+
burst : one kseg of WMMA
137+
flush : global_atomic_add_f32 partials into C
138+
shrink : s_alloc_vgpr VLEAN
139+
release : atomic_sub(vgpr_reserved, NFV-VLEAN)
140+
```
141+
Because the budget can never be exceeded, the "all NCOMP grow at once" collision is **unreachable by
142+
construction** — only as many waves as fit can be at peak; the rest spin at lean until budget frees.
143+
This is exactly the ISA §3.3.3.2 "software forward-progress scheme." Reserve/release run at lean-32
144+
(v≤15, OOR-safe) — before the grow and after the shrink.
145+
146+
### 4.4 The stagger — three jobs at once
147+
Phase-offset the compute waves' grow windows (lock-free LDS phase tokens, reuse the prod/cons counter
148+
style — NO `s_barrier`) so:
149+
1. **Compute stays saturated** — there is always *some* compute wave at peak doing WMMA.
150+
2. **The collision can't recur** — grows don't all issue at the same instant (the envelope is the hard
151+
floor; the stagger is the scheduling that keeps peaks spread).
152+
3. **Feed fungibility** — the immediate per-kseg release frees budget so **feed waves can spawn/grow the
153+
moment the ring counters say feed is the bottleneck.** The freed VGPR flows to wherever the current
154+
bottleneck is, per-moment — the adaptive core of DSWS.
155+
156+
**Master knob = burst length** (ksegs held at peak before shrink) and **stagger period / concurrent-peak
157+
count**. These are the R3 sweep axes (`SPEC_WAVESPEC.md` R3). Short burst → more churn/occupancy but more
158+
grow/shrink overhead; long burst → amortized overhead but higher duty. Optimum = shortest burst that keeps
159+
the WMMA pipe full.
160+
161+
### 4.5 Instrumentation baked in from the start (kmbandy mandate)
162+
"Build the real thing with the real instrumentation so if/when it breaks, the data pinpoints it — not a
163+
blind brick." On top of the wedge-frame markers already in the tree (§6), add grow-envelope telemetry to
164+
host-streamed occ slots: `vgpr_reserved` high-water, per-wave reserve-spin count (permit-wait),
165+
grow/shrink/release event counts, per-role epoch. A wedge becomes a readout (permit-starvation vs
166+
elsewhere), not a mystery. All DIAG-gated so `DIAG=0` stays byte-identical.
167+
168+
### 4.6 Validation ladder
169+
CPU-model the envelope invariant (Σ ≤ BUDGET, no lost reservation, forward-progress under thread race —
170+
extend `dsws_ctrl_model.cpp` + `test_dsws_ctrl_model.cpp`) → assemble matrix + RGA 0-spill → CONV=0 /
171+
DIAG=0 byte-identity → **one** safeguarded GPU oracle run at `n_kseg>1` (`ok=1536 bad=0`) → then sweep
172+
concurrent-peak × burst × stagger-period for occupancy/throughput.
173+
174+
---
175+
176+
## 5. How this lines up with the existing repo design (reconciliation)
177+
178+
kmbandy asked explicitly whether this matches what's already written. It does, **with one correction and
179+
one addition** we made this session:
180+
181+
- **`SPEC_WAVESPEC.md` EXTENSION (2026-06-25), "rolling dyn-VGPR / traveling peak" (KG `1fdd5784`)** — the
182+
governing sum-envelope rule (Σ instantaneous ≤ B), the trapezoid grow→peak→shrink, the "three jobs"
183+
(occupancy, brick-avoidance, §3.3.3.2-unreachable). This IS our design; we're realizing it on the DSWS
184+
claim-based split-K substrate. Build order R0–R4 there.
185+
- **`MAD305_DSWS_MASTER.md:78-81`** — "Split-K is the headroom-creator; split-K creates brief peak windows
186+
= the room to reallocate VGPR between roles." Matches. **Correction:** its "staggering buys nothing"
187+
clause describes **full-K / n_kseg=1** (95% duty square wave). With real split-K the peak is brief and
188+
staggering both avoids the collision AND enables the fungibility. kmbandy's framing: the split-K/dyn-VGPR
189+
combo is for *whatever's needed at that instant* — compute-per-kseg OR role conversion — not one or the
190+
other. It's one pool.
191+
- **`vgpr_reserved`/`VRESV` sum-envelope** (`SPEC_DSWS_SUBSTRATE_V2.md:65,165`, `SPEC_DSWS_PHASEB_
192+
CONVERSION.md:95,130`) — already built, currently applied only to role-conversion grows. **Addition:**
193+
extend the *same* envelope to gate the per-rowblk/per-kseg compute grow (§4.3). Same counter, same
194+
primitive — this is the unification, not a new mechanism.
195+
- **`HYBRID_DESIGN.md`** — the grow-ordering rule (grow before loading operands; the DEFERGROW hazard),
196+
the Σ≤~1152/SIMD budget, RGA livereg. Keep the grow-ordering rule; it's orthogonal and still applies.
197+
198+
---
199+
200+
## 6. What's built & tested this session (all offline unless noted)
201+
202+
- **Entry-fix (`b01c722df`, committed)** — first-entry through `_alloc/_init`. Fixed the desktop-brick;
203+
confirmed on silicon.
204+
- **CPU model (committed at `5421751`, extended offline)**`dsws_ctrl_model.cpp` +
205+
`test_dsws_ctrl_model.cpp`: watermark/epoch/gate/reserve + snapshot/quiesce + entry-contract repro. All
206+
pass.
207+
- **QUIESCE race harness (`test_dsws_quiesce_race.cpp`, uncommitted)**`std::thread` claimer+7-follower
208+
model, 400 trials × {seq_cst, relaxed}, **0 stalls** — ruled out the protocol race.
209+
- **Wedge-frame DIAG instrumentation (`occ_kernel_dsws.s`, uncommitted, byte-identity verified)** — an
210+
`epoch_mark` macro + a claimer wait-loop snapshot of all advance-gate counters, routed into the host's
211+
existing `ML8_COOP_STREAM` occ slots. Stream field map: `cons`=ROWBLK_DONE, `tiles`=AROW_DONE,
212+
`compPh`=BFRAG_DONE, `comp:dsB`=QUIESCE_CNT, `feed:tr/pub/rawTi`=ROWBLK/AROW/BFRAG_NEXT,
213+
`roles[C/A/B]`=per-role last-bumped epoch. RGA 0-spill, max-live 84.
214+
- **GPU (supervised, kmbandy-greenlit):** the instrumented CONV=1/DIAG=1 4c2a2b bin ran **CLEAN**
215+
(`ok=1536 bad=0`, occ[0]=0, occ[20]=33, dmesg silent) — the heisenbug that pinned the root cause.
216+
Bins restored to safe CONV=0 immediately after.
217+
218+
---
219+
220+
## 7. References
221+
222+
**Repo docs (this dir unless noted):**
223+
- `MAD305_DSWS_MASTER.md` — the vision, the issue-port wall, split-K framing.
224+
- `SPEC_DSWS_SUBSTRATE_V2.md` — the claim-based split-K substrate + role economy.
225+
- `SPEC_DSWS_PHASEB_CONVERSION.md` — the conversion economy + `vgpr_reserved` envelope.
226+
- `SPEC_WAVESPEC.md` §EXTENSION — the rolling dyn-VGPR "traveling peak" design (R0–R4). **Primary.**
227+
- `HYBRID_DESIGN.md` — grow-ordering rule, Σ≤pool budget, RGA gates.
228+
- `RESULT_DSWS.md` — the substrate's GPU history (the feed-scheduling starvation class + K-outer fix).
229+
- `docs/superpowers/specs/2026-07-01-dsws-phaseb-pool-economy-design.md` + the matching plan — the
230+
pool-economy universal-dispatch design (Tasks 1-6 offline built, GPU gates T7-T10).
231+
- `.superpowers/sdd/progress.md` — the SDD ledger; the full blow-by-blow incl the brick/SKIPQ/heisenbug.
232+
233+
**KG (mneme) notes — search these:**
234+
- `1fdd5784` rolling dyn-VGPR / traveling peak (THE architecture).
235+
- `21cc0d63` root cause confirmed = multi-grower collision (this session).
236+
- `d1a6d529` correction: entry-fix fixed the brick, not the residual hang.
237+
- `2009aa16` dyn-VGPR OOR rule (no v>15 pre-grow) — already satisfied in the kernel.
238+
- `98614f24` / `1cef3378` / `a241842c` ISA §3.3.3.2 multi-grower deadlock (authoritative).
239+
- `11d86889` / `7c697c80` never dispatch a dyn kernel above the live SQ_DYN_VGPR cap (reboot lesson).
240+
241+
---
242+
243+
## 8. Safety & operating rules (HARD — kmbandy standing orders)
244+
245+
- **No GPU isolation exists.** gfx1201 drives the desktop; a hang can MODE1-reset it. **Bricks are
246+
accepted** ("if it bricks, it bricks — we reboot and go from there") **but only with safeguards.**
247+
- **kmbandy greenlights EVERY GPU dispatch individually.** Never auto-dispatch.
248+
- **The safeguarded, proven-non-bricking dispatch config** (keep ALL of these):
249+
```
250+
ML8_POOL=1 ML8_COOP_CHUNK=8 ML8_COOP_CHUNK_MAXS=0.75 ML8_COOP_STREAM=1 \
251+
DSWS_NCOMP=4 DSWS_NAFEED=2 DSWS_NBFEED=2 DSWS2_NKSEG=<N> \
252+
timeout 30 ./occ_dispatch --dsws2 4c2a2b
253+
```
254+
The chunk watchdog (`ML8_COOP_CHUNK_MAXS=0.75`) self-aborts a stalled chunk cleanly; `ML8_COOP_STREAM=1`
255+
streams occ frames to disk so the wedge frame survives a hard hang.
256+
- **NEVER disable the quiesce gate** (no `SKIPQ`-style force `s51=1`) — it removes the clean self-abort
257+
and bricks.
258+
- **Always rebuild+install the CONV=1 bin only at dispatch time, and restore the safe CONV=0 4840B bin
259+
immediately after, unconditionally** (footgun removal — see `scratchpad/fire_wedge_diag.sh` for the
260+
pattern). Never leave a CONV=1 bin installed.
261+
- **`NFV=112 < 128` (the default `SQ_DYN_VGPR` cap)** — do NOT exceed 128 VGPR without the umr flip
262+
(sudo, operator-only). Keep grows ≤128.
263+
- **Never modify** `occ_kernel_coop.s`, `occ_dispatch.cpp`, `fp8_oracle.*` — shared/not-ours. Never stage
264+
them.
265+
- **Commit to git ONLY when kmbandy asks.** Never `--gl2c`.
266+
267+
---
268+
269+
## 9. Your first tasks (next session)
270+
271+
1. **Spec** the rolling dyn-VGPR grow economy from §4: exact LDS slot(s) for the compute grow envelope
272+
(reuse `VRESV_OFF` or a sibling), the reserve/release macro, the stagger phase-token mechanism, where
273+
they plug into `.Lcompute_claim`/`.Lcompute_grow`/`.Lcompute_shrink`, the per-kseg flush structure
274+
(largely already there — each super-tile's ksi flushes to C), and the DIAG telemetry slots. Decide:
275+
concurrent-peak count (start 1-2, sweep), burst length, stagger period. Save to
276+
`docs/superpowers/specs/`. Self-review, then have kmbandy read it.
277+
2. **Plan** (`docs/superpowers/plans/`) — offline tasks (CPU model envelope invariant → asm → assemble/RGA
278+
→ byte-identity) then the supervised GPU oracle gate at `n_kseg>1`.
279+
3. **Build**, offline gates first. One greenlit GPU oracle run. Then the occupancy sweep.
280+
281+
**Open question to resolve in the spec:** at `n_kseg>1`, confirm each kseg's partial flushes to C
282+
immediately (atomic-add accumulate — it already does across super-tiles) so a compute wave truly shrinks
283+
to lean between segments (true trapezoid), vs any path where accumulators pin the peak. kmbandy confirmed
284+
the intent is per-kseg flush → immediate release.

0 commit comments

Comments
 (0)