|
114 | 114 | .set BFRAG_DONE_OFF, 60 // B-frag STORE-completion counter (compute gates on this, NOT the claim ctr) |
115 | 115 | .set AROW_DONE_OFF, 64 // A-rowblk STORE-completion counter (compute gates on this) |
116 | 116 | .set INITFLAG_OFF, 68 // barrier-free LDS-init publish flag (claimer writes 0xACED LAST) |
| 117 | +// ---- Phase-B (DSWS2_CONV) control state: role-mix snapshot slots + quiesce counter ---- |
| 118 | +// Based at INITFLAG_OFF+4 (NOT the brief's SEGCNT_OFF+4): the brief predates the A3..A7 control |
| 119 | +// words (BFRAG_DONE/AROW_DONE/INITFLAG at 60/64/68), so SEGCNT_OFF+4=60 would collide with them. |
| 120 | +// Basing after the LAST control word keeps the new state inside the 0..255 control gap BELOW the |
| 121 | +// fixed resident region (BRES_OFF=256), so NO resident-region repoint is needed -- the resident |
| 122 | +// BRES_OFF/ARES_OFF immediates (emitted unconditionally in the kernel body) stay untouched, which |
| 123 | +// is what keeps the DSWS2_CONV=0 binary byte-identical to the Phase-A green bin. All `.set`s here |
| 124 | +// are inert (emit no bytes); the only new code (claimer init) is gated under `.if DSWS2_CONV`. |
| 125 | +.ifndef DSWS2_CONV |
| 126 | + .set DSWS2_CONV, 0 // 0 = pre-conversion static substrate (Phase A green); 1 = Phase B |
| 127 | +.endif |
| 128 | +.set SNAP_BASE, (INITFLAG_OFF + 4) // u32[6]: [parity*3 + {0:nC,1:nA,2:nB}] role-mix snapshots |
| 129 | +.set QUIESCE_CNT_OFF,(SNAP_BASE + 6*4) // u32 role-agnostic bail counter |
| 130 | +.set DSWS2_STATE_END,(QUIESCE_CNT_OFF + 4) |
117 | 131 | .set KSEG_STEPS, (SEGK/16) // K16-steps per split-K segment = SEGK K-elements / 16 |
118 | 132 | // FIX 1(b): NKSEG_SHIFT = log2(KSEG_STEPS), so the prologue can derive n_kseg = KT >> NKSEG_SHIFT instead |
119 | 133 | // of receiving it as a (now-dropped) kernarg. SEGK is always a power-of-two multiple of 16 in every |
|
141 | 155 | .if LDS_TOTAL_DSWS2 > 32768 |
142 | 156 | .error "DSWS2 LDS layout exceeds 32768B group segment" |
143 | 157 | .endif |
| 158 | +// Phase-B state must fit in the control gap below the resident region (inert compile check, no bytes). |
| 159 | +.if DSWS2_STATE_END > BRES_OFF |
| 160 | + .error "DSWS2 Phase-B state (SNAP_BASE/QUIESCE_CNT) overlaps resident B region (BRES_OFF)" |
| 161 | +.endif |
144 | 162 |
|
145 | 163 | .if DSWS2 |
146 | 164 | // ---- role counts (lifted from coop's `.ifndef NCOMP` etc., gated under DSWS2) ---- |
@@ -430,6 +448,17 @@ occ_kernel: |
430 | 448 | lds_put (GATE_OFF+12), 0 |
431 | 449 | lds_put VRESV_OFF, (NCOMP*NFV + (NAFEED+NBFEED)*VLEAN) |
432 | 450 | lds_put SEGCNT_OFF, 0 |
| 451 | +.if DSWS2_CONV |
| 452 | + // Phase-B: seed BOTH epoch-parity role-mix snapshots with the launch mix, zero the quiesce counter. |
| 453 | + // Gated so DSWS2_CONV=0 emits ZERO new bytes -> byte-identical to the Phase-A green bin. |
| 454 | + lds_put QUIESCE_CNT_OFF, 0 |
| 455 | + lds_put (SNAP_BASE + 0), NCOMP // parity-0 snapshot = launch mix |
| 456 | + lds_put (SNAP_BASE + 4), NAFEED |
| 457 | + lds_put (SNAP_BASE + 8), NBFEED |
| 458 | + lds_put (SNAP_BASE + 12), NCOMP // parity-1 = launch mix too (init) |
| 459 | + lds_put (SNAP_BASE + 16), NAFEED |
| 460 | + lds_put (SNAP_BASE + 20), NBFEED |
| 461 | +.endif |
433 | 462 | lds_put INITFLAG_OFF, 0xACED // LAST: publishes "LDS ready" to all follower waves |
434 | 463 | // FIX 1(e): load this dispatch's chunk terminal bound from occ[24] (host writes occW[6] per chunk; |
435 | 464 | // FIX 1j on the host side). All lanes read the same address -> no exec masking needed, just a |
|
0 commit comments