You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(dsws): correct entry != re-dispatch in pool-economy spec + plan
Propagate the Pool-T7 root cause (fixed in b01c722) back into the design
docs so the "unified dispatch" language can't reintroduce it.
- Spec §2: `.Ldispatch` is RE-DISPATCH ONLY, not a unified entry+re-dispatch
mechanism. First entry runs the full role `_alloc`/`_init`/`_follow`; only a
post-bail wave lands on `_follow`. Also corrected the inaccurate "INITFLAG
already consumed" rationale (INITFLAG is written once, never cleared; the real
reason re-dispatch skips `_init` is it would reset `s35`).
- Spec §3: seed arms fall into the full role entry, NOT `.Ldispatch`.
- Plan architecture summary + Task 3: Step 3 no longer flips the seed arms to
`.Ldispatch` (that was the exact instruction that caused the brick); the arms
stay on `.Lcompute`/`.Lafeed`/`.Lbfeed`. Task 3 retitled/re-scoped to
re-dispatch only; commit-message template updated.
No code change (docs only). Fix itself is b01c722.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0132aDSBLwusCJ4KzHQTnvdu
Copy file name to clipboardExpand all lines: docs/superpowers/plans/2026-07-01-dsws-phaseb-pool-economy.md
+23-12Lines changed: 23 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,12 +6,17 @@
6
6
8-wave partition into a lean-start grow-into-budget pool that rebalances its
7
7
{compute, A-feed, B-feed} mix at runtime.
8
8
9
-
**Architecture:** One scalar (`s59`)-driven dispatcher unifies entry and
10
-
re-dispatch (lands on each role's `_follow`, scalar-only). Every wave already
11
-
launches lean-32 (compute grows to `NFV` per-rowblk on demand and shrinks back —
12
-
Phase-A behavior); "seeding" a role is therefore just setting `s59` in the
13
-
existing lean partition arms, with **no launch-time grow**. The only
14
-
`s_alloc_vgpr` GROW in the whole design remains `conv_apply`'s, already audited.
9
+
**Architecture:** One scalar (`s59`)-driven dispatcher handles **re-dispatch**
10
+
(reached from a `_quiesce` bail; lands on each role's `_follow`, scalar-only).
11
+
**First-time entry is DISTINCT** — it seeds `s59` then runs the full role entry
12
+
(`.Lcompute`/`.Lafeed`/`.Lbfeed` → `_alloc` → `_init` → `_follow`); it must NOT
13
+
reuse `.Ldispatch`, which skips `_alloc`/`_init` (the Pool-T7 brick: corrected
14
+
2026-07-02, committed `b01c722df`). Every wave already launches lean-32 (compute
15
+
grows to `NFV` per-rowblk on demand and shrinks back — Phase-A behavior);
16
+
"seeding" a role is therefore just setting `s59` in the existing lean partition
17
+
arms and falling into that role's existing entry, with **no launch-time grow
18
+
added**. The only `s_alloc_vgpr` GROW in the whole design remains `conv_apply`'s,
19
+
already audited.
15
20
`BUDGET` is retuned to the real per-SIMD ceiling so feed→compute grows can
16
21
succeed (bidirectional balancing within the launched mix). A cooldown `K` damps
17
22
thrash; a `DSWS2_FORCE` hook gives a deterministic first GPU proof. All offline
@@ -141,7 +146,7 @@ Expected: `dsws_ctrl_model: dispatch/cooldown/pool OK` then `dsws_ctrl_model: AL
141
146
s_cmp_lt_u32 s24, (NBFEED+NAFEED)
142
147
s_cbranch_scc1 .Lseed_afeed
143
148
s_mov_b32 s59, NCOMP_SLOT
144
-
s_branch .Lcompute // Task 3 retargets these three to .Ldispatch
149
+
s_branch .Lcompute // FIRST entry: full role entry (_alloc/_init/_follow). Do NOT retarget to .Ldispatch (Pool-T7 brick).
145
150
.Lseed_afeed:
146
151
s_mov_b32 s59, NAFEED_SLOT
147
152
s_branch .Lafeed
@@ -184,14 +189,20 @@ done
184
189
185
190
---
186
191
187
-
## Task 3: The `.Ldispatch` trampoline + tail-branch replacements
192
+
## Task 3: The `.Ldispatch` RE-DISPATCH trampoline + tail-branch replacements
193
+
194
+
> **CORRECTION 2026-07-02 (Pool-T7 brick, committed `b01c722df`).**`.Ldispatch` is
195
+
> **RE-DISPATCH ONLY** — reached from a `_quiesce` bail, never from first-time entry.
196
+
> The original Step 3 below flipped the Task-2 seed arms to `.Ldispatch`; that skipped
197
+
> `_alloc`/`_init` on first entry and hung the first CONV=1 dispatch (desktop brick).
198
+
> Step 3 is corrected: the seed arms **stay** on the full role entry.
188
199
189
200
**Files:**
190
-
- Modify: `occ_kernel_dsws.s` (add `.Ldispatch`; replace tail branches at L907, L951, L1097; flip Task-2 seed arms to `.Ldispatch`)
201
+
- Modify: `occ_kernel_dsws.s` (add `.Ldispatch`; replace the 3 `_quiesce`-bail tail branches at L907, L951, L1097. **Leave the Task-2 seed arms on `.Lcompute`/`.Lafeed`/`.Lbfeed` — do NOT retarget them to `.Ldispatch`.**)
191
202
192
203
**Interfaces:**
193
204
- Consumes: `s59` (seeded in Task 2, flipped by `conv_apply`), the `_follow` labels `.Lcompute_follow`/`.Lafeed_follow`/`.Lbfeed_follow`.
194
-
- Produces: universal per-epoch role dispatch. Every non-claimer wave routes to the `_follow` of the role `s59` names.
205
+
- Produces: per-epoch role RE-dispatch after a bail. A bailed non-claimer wave routes to the `_follow` of the role `s59` names. (First entry does not use this — it runs the full role `_alloc`/`_init`/`_follow`.)
195
206
196
207
-[ ]**Step 1: Add the trampoline** (under `.if DSWS2_CONV`, placed after the three role bodies so all `_follow` labels are in scope):
197
208
@@ -216,11 +227,11 @@ done
216
227
.endif
217
228
```
218
229
219
-
-[ ]**Step 3: Flip the Task-2 seed arms**from the temporary `.Lcompute`/`.Lafeed`/`.Lbfeed` targets to `.Ldispatch` (three `s_branch .Ldispatch`), so entry uses the same dispatcher. **Verify (name in report):**`.Ldispatch` lands on `_follow` (NOT `_alloc`/`_init`), and `s35`(last-epoch) is preserved across the trampoline so a re-dispatched wave waits for the next epoch.
230
+
-[ ]**Step 3: Leave the Task-2 seed arms on the full role entry.**Do **NOT** retarget them to `.Ldispatch`. First-time entry must run `_alloc` (the `s_alloc_vgpr 32` allocator handshake) and `_init` (the `INITFLAG==0xACED` LDS rendezvous + `s35=0` epoch seed) before its first `_follow` — all of which live only inside the role entry. Only a wave that has *already* run those once (i.e. after a `_quiesce` bail) may use `.Ldispatch`. **Verify (name in report):**the seed arms still branch to `.Lcompute`/`.Lafeed`/`.Lbfeed`; `.Ldispatch`is reached only from the 3 bail tail-branches; on re-dispatch it lands on `_follow` (NOT `_alloc`/`_init`) and `s35` is preserved so the re-dispatched wave waits for the next epoch.*(Original Step 3 flipped these to `.Ldispatch` → Pool-T7 brick; corrected 2026-07-02.)*
220
231
221
232
-[ ]**Step 4: Assemble + byte-identity + RGA** — same commands as Task 2 Step 4. Expected: CONV=0 sha256 unchanged from baseline; 3× `ASSEMBLE_OK`; RGA 0 spills. Additionally grep the object disassembly is not required, but confirm no `s_barrier` was introduced: `grep -c s_barrier occ_kernel_dsws.s` → unchanged from HEAD.
0 commit comments