Files
d4r/kernels/rr/rrswin_enc2_epilogues.md
woutermans 0fe3a28cb7 kernels/rr: staged-image Swin layer engine prototypes
Per-layer staged-image engine for the eleven translated denoiser Swin
layers: descriptors (verified offsets per phase), cut recipes that splice an
isolated native phase into NVIDIA's PTX, wave templates, epilogue notes and
GPU probes. The isolated phase-8 splice produces a byte-identical final
4K frame but is slower than the translated body (14.90 vs 6.59 ms) - a
correctness experiment, not a shipping improvement; docs/rr-engine.md
records the design and the next direct-converter win (B operands built
from transposed accumulators).
2026-10-12 12:47:53 +02:00

1514 lines
79 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `cuda_dldn_engine_swin_enc2_kernel` — the epilogues of phases 1…38
Companion to `kernels/rr/rr_layer_spec.py enc2`. Everything below was read out of
`~/.cache/d4r-rr-corpus/0015-PREPASS_ENTRYPOINT_NAME.ptx`, entry
`cuda_dldn_engine_swin_enc2_kernel` (14199 statements, file lines 1018–34562).
## 0. Conventions
* **`sNNNN` is a statement index** in the linearisation `rr_layer_spec.py`
documents (statements of the entry body; a wrapped `{ … }` block and a 4-line
`mma.sync` count as one statement, numbered at their first line). **`LNNNNN`
is the physical line** of the same instruction in the corpus file, so every
claim can be checked with `sed -n 'LNNNNN,LNNNNN p' …ptx`.
* An **epilogue** is the run of statements between one phase's last `mma` and the
next phase's first `mma`. The phase table (`rr_layer_spec.py enc2`) gives the
ranges; this file names what each one *computes*.
* `W` denotes the prepared weight image: `ld.param.u64 %rd2,
[cuda_dldn_engine_swin_enc2_kernel_param_0+40]` (s8), `cvta.to.global.u64 %rd3,
%rd2` (s9). Every `ld.weak.global.ca.v4.u32` in an epilogue reads
`W + 16*laneid + imm`; every `ld.global.v2.u16` / `ld.global.u32` table load
reads `W + ((laneid<<2)&12) + imm`.
* `Wz` denotes the **per-`%tid.z` weight slab**: `%rd269 = %rd2 + 2*(%tid.z *
10752) + 16*laneid` (s4589–s4590, s4613–s4615) = `W + 21504*%tid.z +
16*laneid`. Phases 1…7 add offsets to *this* pointer; phases 9…36 add them to
`W + 16*laneid` directly (s8976–s8978); phase 37 to `W + 12288*%tid.z +
16*laneid` (s13634–s13639). Every byte offset in the phase table is relative
to the pointer named here, so the phase-table numbers do **not** include the
`%tid.z` term. See §6 U5.
* `S` denotes the plane arena: `ld.param.u64 %rd383, [%rd1+-32]` (s12865) with
`%rd1 = param_0 + 80` (s4) → **`param_0+48`**, then `cvta.to.global.u64 %rd5,
%rd383` (s12866). `I` denotes the input image: `ld.param.u64 %rd10,
[param_0+8]` (s17) → `%rd4` (s18). `O` denotes the epilogue-37 destination:
`ld.param.u64 %rd6, [%rd492+56]` (s13632) → **`param_0+56`**.
* The mma fragment layouts and the weight-addressing formula are the settled ones
(see `rr_layer_spec.py --help` and the enc0 companion): C/D `reg0 = (row g,
cols 2t,2t+1)`, `reg1 = (row g+8, same cols)`, `g = laneid>>2`, `t = laneid&3`.
* **Geometry.** Writing `m = M/16`, `n = N/8`, `k = K/32` for a phase, the mma
chain fixes the three exactly: `|A fragments| = m*k`, `|B fragments| = n*k`,
accumulator chains (maximal C←D dataflow runs) `= m*n`, each of length `k`, and
`mma = m*n*k`. `rr_layer_spec.py` prints `M = 16*|A fragments|` and
`N = 8*|B fragments|`, i.e. it omits the division by `k`, so its M and N
columns are too large by a factor `K/32` whenever a phase makes more than one
k32 step. Every row is re-derived from the chain in §2.
* Anything I could not pin down from the PTX is in §6 under **uncharacterised**.
## 1. Shared vocabulary
### 1.1 Addresses and parameters an epilogue touches
| symbol | how it is obtained | statements |
|---|---|---|
| `W` (weight image) | `ld.param.u64 %rd2, [param_0+40]` / `cvta.to.global.u64 %rd3, %rd2` | s8 / s9 |
| `Wz = W + 21504*%tid.z + 16*laneid` | `mul.lo.s32 %r16116, %r10, 10752` (`%r10 = %tid.z`, s22), `mul.wide.u32 %rd266, %r16116, 2`, `add.s64 %rd268, %rd2, %rd266`, `add.s64 %rd269, %rd268, %rd267` (`%rd267 = 16*laneid`) | s4589–s4590, s4613–s4615 |
| `I` = input image | `ld.param.u64 %rd10, [param_0+8]` / `cvta.to.global.u64 %rd4, %rd10` | s17–s18 |
| `S` = plane arena (`param_0+48`) | `add.s64 %rd1, %rd8, 80` (`%rd8 = param_0`, s1), `ld.param.u64 %rd383, [%rd1+-32]`, `cvta.to.global.u64 %rd5, %rd383` | s4, s12865–s12866 |
| `O` = `param_0+56` | `ld.param.u64 %rd6, [%rd492+56]` (`%rd492 = param_0`, s12803) | s13632 |
| `T` = texture (`param_0+88`) | `ld.param.u64 %rd480, [%rd491+88]` (`%rd491 = param_0`, s13941) | s13941, s14056 |
| surfaces | `ld.param.u64 [%rd491+112]` (s13953), `[+120]` (s14178), `[+128]` (s14179) | s13953, s14178–s14179 |
| extents `(ex, ey)` | `ld.param.v2.u32 {%r322, %r323}, [param_0+0]` | s14 |
| block origins | `sub.s32 %r1, %r317, %r318` (`%r317 = 8*ctaid.x`) and `sub.s32 %r2, %r321, %r319` (`%r321 = 8*ctaid.y`) | s3–s7, s11–s13 |
| patch origin offsets | `ld.param.v2.u16 {%rs126, %rs127}, [param_0+80]` | s5 |
| `%r5 = 8*ex`, `%r6 = ey*(8*ex)` | `shl.b32 %r5, %r322, 3`, `mul.lo.s32 %r6, %r323, %r5` | s15–s16 |
| `g = laneid>>2`, `t = laneid&3` | `shr.u32 %r8, %r315, 2`, `and.b32 %r9, %r315, 3` | s20–s21 |
| `%r182 = %r2 + 2*%tid.z` | `shl.b32 %r181, %r10, 1`, `add.s32 %r182, %r2, %r181` | s9184–s9185 |
| `%r17795 = %tid.z<<5` | `mov.u32 %r17745, %tid.z`, `shl.b32 %r17795, %r17745, 5` | s13135, s13139 |
The three scalar-table forms matter and are used throughout:
* `ld.weak.global.ca.v4.u32` at `ptr + 512*i` reads one **N-tile of a K=32 slice**
= 16 bytes/lane = 2 B fragments or 2 C pairs (the tool's own comment,
`rr_layer_spec.py:189–192`).
* `ld.global.v2.u16` at `W + ((laneid<<2)&12) + off` reads 4 bytes/lane, the four
lanes with equal `laneid&3` reading the same word, so a run of such loads at
16-byte stride is one **per-column** vector (a 96-element f16 table is 12 such
loads: 12 × 4 bytes × 4 distinct lane offsets = 192 bytes).
* `ld.global.u32` at the same addressing reads one word = 2 f16 = one per-column
bias pair, used **in both halves** of an mma C operand, i.e. replicated across
the 16 rows of the tile (s9820 `{%r9477, %r9477}`, s13871 `{%r17465, %r17465}`).
### 1.2 Constants that survive between epilogues
| register | first definition | f32/f64 literal | value used (after the `cvt`) | read by |
|---|---|---|---|---|
| `%f476` | s5020 `mov.f32 %f476, 0f3C8CCB50` | 0.017186790704727173 | f16 `0x2466` = 0.017181396484375 | E7 |
| `%fd383` | s5024 `mov.f64 %fd383, 0dBFE1CC0000000000` | −0.55615234375 | f16 `0xB873` = −0.55615234375 | E7 |
| `%fd385` | s5029 `mov.f64 %fd385, 0d3FE1CC0000000000` | +0.55615234375 | f16 `0x3873` = +0.55615234375 | E7 |
| `%f478` | s5035 `mov.f32 %f478, 0f3F6D6000` | 0.92724609375 | f16 `0x3B6B` = 0.92724609375 | E7 |
| `%f480` | s5040 `mov.f32 %f480, 0f3FB00000` | 1.375 | f16 `0x3D80` = 1.375 | E7 |
| `%f861` | s9833 `mov.f32 %f861, 0f3ED306EB` | 0.4121621549129486 | f16 `0x3698` = 0.412109375 | E13…E35 |
| `%f862` | s9836 `mov.f32 %f862, 0f3DA60DD6` | 0.0810810774564743 | f16 `0x2D30` = 0.0810546875 | E13…E35 |
| `%f863` | s9839 `mov.f32 %f863, 0f3F000000` | 0.5 | f16 `0x3800` = 0.5 | E13…E35 |
| `%f864` | s9842 `mov.f32 %f864, 0f40000000` | 2.0 | f16 `0x4000` = 2.0 | E13…E35 |
| `%fd1` | s3662 `mov.f64 %fd1, 0d3F20000000000000` | 2⁻¹³ | f16 `0x0800` = 0.0001220703125 | prologue, E12 |
`%f861…%f864` are defined **inside E13** (s9833–s9842) and re-read by the `cvt`
of every later 164-statement epilogue (E15 s10174–s10181, E17 s10422–…, and so
on to E35), so those epilogues contain `cvt.rn.f16.f32` but only 2 `mov.u32`.
Also live across the region: `%r3037 = 1` (s3318), `%r3046 = 2` (s3611),
`%r3048 = −1` (s3604) — the delta / segmask / membermask operands of every
`shfl.sync.bfly.b32`; and `%r8606 = 0` (s4616), the zero C operand of phases 1,
2 and 8.
### 1.3 Two quantisation helpers
* `cvt.rn.satfinite.e4m3x2.f16x2` — the requantisation used everywhere
(`f16x2_to_e4m3x2_satfinite_bits` in `ptx/lib/zluda_ptx_impl.cpp`).
* `cvt.rn.f16x2.e4m3x2` — the *other* direction (f16x2 → e4m3x2), used only in
the prologue to quantise the input patch (s3320 ff.).
* `rcp.approx.ftz.f32`, `rsqrt.approx.ftz.f32`, `ex2.approx.ftz.f32`,
`div.approx.ftz.f32` — always wrapped as `cvt.f32.f16 → op → cvt.rn.f16.f32`
(round each step through f16).
## 2. Summary
### 2.1 The 38 epilogues
| epilogue | range | stmts | named operation |
|---|---|---|---|
| E1 | s4645–s4651 | 7 | phase 2 B weight loads |
| E2 | s4676–s4682 | 7 | phase 3 B weight loads |
| E3 | s4707–s4713 | 7 | phase 4 B weight loads |
| E4 | s4738–s4744 | 7 | phase 5 B weight loads |
| E5 | s4769–s4775 | 7 | phase 6 B weight loads |
| E6 | s4800–s4970 | 171 | score-bias C-seed loads + packs of phase-5/6 D → phase 7 A and B |
| E7 | s5019–s8861 | 3843 | softmax of the 64×96 score, V transpose, packs → phase 8 A and B |
| E8 | s8910–s9078 | 169 | phase-8 D → shared, phase 9 A read, phase 9 B loads, per-column table add → phase 9 C |
| E9 | s9091–s9109 | 19 | phase 10 A from shared + phase 10 B loads |
| E10 | s9122–s9140 | 19 | phase 11 A from shared + phase 11 B loads |
| E11 | s9153–s9171 | 19 | phase 12 A from shared + phase 12 B loads |
| E12 | s9184–s9819 | 636 | RMS norm of phase-12 D + gain, packs; phase 13 A/C and phase 15 B |
| E13 | s9832–s10088 | 257 | clamped cubic on phase-13 D + packs; residual+table → phase 14 C; phase 14 B |
| E14 | s10101–s10160 | 60 | phase 15 B + C loads; 24 packs of the normed tile → phase 15 A |
| E15 | s10173–s10336 | 164 | clamped cubic on phase-15 D + packs; phase 16 B |
| E16 | s10349–s10408 | 60 | phase 17 B + C loads; packs of the normed tile → phase 17 A |
| E17 | s10421–s10584 | 164 | clamped cubic on phase-17 D + packs; phase 18 B |
| E18 | s10597–s10656 | 60 | phase 19 B + C loads; packs of the normed tile → phase 19 A |
| E19 | s10669–s10832 | 164 | clamped cubic on phase-19 D + packs; phase 20 B |
| E20 | s10845–s10904 | 60 | phase 21 B + C loads; packs of the normed tile → phase 21 A |
| E21 | s10917–s11080 | 164 | clamped cubic on phase-21 D + packs; phase 22 B |
| E22 | s11093–s11152 | 60 | phase 23 B + C loads; packs of the normed tile → phase 23 A |
| E23 | s11165–s11328 | 164 | clamped cubic on phase-23 D + packs; phase 24 B |
| E24 | s11341–s11400 | 60 | phase 25 B + C loads; packs of the normed tile → phase 25 A |
| E25 | s11413–s11576 | 164 | clamped cubic on phase-25 D + packs; phase 26 B |
| E26 | s11589–s11648 | 60 | phase 27 B + C loads; packs of the normed tile → phase 27 A |
| E27 | s11661–s11824 | 164 | clamped cubic on phase-27 D + packs; phase 28 B |
| E28 | s11837–s11896 | 60 | phase 29 B + C loads; packs of the normed tile → phase 29 A |
| E29 | s11909–s12072 | 164 | clamped cubic on phase-29 D + packs; phase 30 B |
| E30 | s12085–s12144 | 60 | phase 31 B + C loads; packs of the normed tile → phase 31 A |
| E31 | s12157–s12320 | 164 | clamped cubic on phase-31 D + packs; phase 32 B |
| E32 | s12333–s12392 | 60 | phase 33 B + C loads; packs of the normed tile → phase 33 A |
| E33 | s12405–s12568 | 164 | clamped cubic on phase-33 D + packs; phase 34 B |
| E34 | s12581–s12640 | 60 | phase 35 B + C loads; packs of the normed tile → phase 35 A |
| E35 | s12653–s12816 | 164 | clamped cubic on phase-35 D + packs; phase 36 B |
| E36 | s12829–s13698 | 870 | pack phase-36 D → arena scatter + shared staging; phase 37 A/B/C |
| E37 | s13747–s13870 | 124 | pack phase-37 D → 4 stores to `param+56`; phase 38 B/C |
| E38 | s13877–s14199 | 323 | shared staging, real row max, softmax, 9 texture reads, 3×3 gather, sigmoid/0.25/lane sum, 3 surface writes |
### 2.2 Phase geometry re-derived from the mma chain
`|A|` and `|B|` are the distinct A-quad and B-pair counts;
`chains`/`len` come from the C←D dataflow runs; `mma` is the emitted count.
`spec` is the phase table's (`M`, `N`, `K`, `tiles`, `mma`).
| # | A-quads | B-pairs | chains×len | k | re-derived (M,N,K,tiles) | spec (M,N,K,tiles) | M/16·N/8·K/32 vs mma |
|---|---|---|---|---|---|---|---|
| 1–6 | 6 | 4 | 24×1 | 1 | 96,32,32,24 | 96,32,32,24 | 6·4·1 = 24 = mma ✔ |
| 7 | 4 | 12 | 48×1 | 1 | 64,96,32,48 | 64,96,32,48 | 4·12·1 = 48 = mma ✔ |
| 8 | 12 | 12 | 16×3 | 3 | **64,32,96,16** | 192,96,96,16 | 4·4·3 = 48 = mma ✔ (spec M,N too big) |
| 9–12 | 1 | 12 | 12×1 | 1 | 16,96,32,12 | 16,96,32,12 | 1·12·1 = 12 = mma ✔ |
| 13,15,…,35 | 3 | 12 | 4×3 | 3 | **16,32,96,4** | 48,96,96,4 | 1·4·3 = 12 = mma ✔ (spec M,N too big) |
| 14,16,…,36 | 1 | 12 | 12×1 | 1 | 16,96,32,12 | 16,96,32,12 | 1·12·1 = 12 = mma ✔ |
| 37 | 12 | 48 | 4×12 | 12 | **16,32,384,4** | 192,384,384,4 | 1·4·12 = 48 = mma ✔ (spec M,N too big) |
| 38 | 3 | 6 | 2×3 | 3 | **16,16,96,2** | 48,48,96,2 | 1·2·3 = 6 = mma ✔ (spec M,N too big) |
Explicit answer to the flagged rows: **in every one of the 38 rows the identity
`mma = (M/16)·(N/8)·(K/32)` holds, and none of the phase-table rows is
arithmetically inconsistent.** What is wrong in the table is `M` and `N` (and
hence the `full`/`band` label the tool derives from them): the tool sets
`M = 16·|A|`, `N = 8·|B|` (`rr_layer_spec.py:481`, `:590–592`), which counts every
k32 step as a separate m- and n-tile, so whenever `K > 32` its M and N are too
large by exactly the factor `k = K/32` and its `dense` test
(`nmma == nA*nB*lens[0]`, `:593`) is too strict. Dividing out `k` — which the
chain's own `m·k = |A|`, `n·k = |B|`, `m·n = chains` fixes uniquely — gives the
row marked `re-derived`, and every one then satisfies the identity:
* rows 1–7, 9–12, 14, 16, …, 36 are correct as printed (`k = 1`);
* row 8: `|A|=12, |B|=12, k=3` → **M=64, N=32, K=96** (tool: 192, 96, 96) —
dense, 4·4·3 = 48;
* rows 13, 15, …, 35: `|A|=3, |B|=12, k=3` → **M=16, N=32, K=96** (tool: 48, 96,
96) — dense, 1·4·3 = 12; the tool's `K = 96` is right, only M and N are 3× too
large;
* row 37: `|A|=12, |B|=48, k=12` → **M=16, N=32, K=384** (tool: 192, 384, 384) —
dense, 1·4·12 = 48; again only M and N are wrong (12×);
* row 38: `|A|=3, |B|=6, k=3` → **M=16, N=16, K=96** (tool: 48, 48, 96) — dense,
1·2·3 = 6.
The *operand provenance* of the corrected rows is checked separately from the
counts: for row 8 the 12 A quads are E7's probability packs of a 64×96 matrix
(§3/E7(g)) and the 12 B pairs its `movmatrix` transposes of a 96×32 matrix, giving
4 m-tiles × 3 k and 4 n-tiles × 3 k directly; for rows 13…35 the 3 A quads are
E12's three 16×32 e4m3 slices of the 16×96 normed tile (§3/E12) → 1 m-tile × 3 k;
for row 37 the 12 A quads are read as 48 `ld.shared.u32` from the staged phase-36
output and the 48 B pairs come from 24 512-byte tiles → 1 m-tile × 12 k and 4
n-tiles × 12 k; for row 38 the 3 A quads are staged from phase 37's chain-final D
and the 6 B pairs from 3 tile loads → 1 × 3 and 2 × 3. The only thing the operand
provenance does *not* settle is which (n, k) each 512-byte B tile holds for rows
13…35 and 37 — see §6 U1.
## 3. The epilogues
### E1 — s4645–s4651: phase 2 B weight loads
```
s4645 L7837: mov.u32 %r3499, %laneid
s4646 L7839: mul.wide.u32 %rd270, %r3499, 16
s4647 L7840: add.s64 %rd271, %rd268, %rd270
s4648 L7841: add.s64 %rd64, %rd271, 3264
s4649 L7843: ld.weak.global.ca.v4.u32 { %r3500,%r3501,%r3502,%r3503},[%rd64]
s4650 L7845: add.s64 %rd65, %rd271, 3776
s4651 L7847: ld.weak.global.ca.v4.u32 { %r3504,%r3505,%r3506,%r3507},[%rd65]
```
Two 16-byte/lane fragments of `Wz + {3264, 3776}` = the weight block
`[3264, 4296)` — phase 2's B operand (`%r3500,%r3501` … `%r3506,%r3507`), which
phase 2 consumes at s4652–s4675. `%rd268` is the `Wz` pointer of §1.1, so this
is `W + 21504*%tid.z + 16*laneid + off`. Nothing else.
### E2 — s4676–s4682: phase 3 B weight loads
Same shape, base register `%rd268`, offsets `+1216` (s4679) and `+1728` (s4681)
→ `%r3749…%r3756`. Weight block `[1216, 2248)`.
### E3 — s4707–s4713: phase 4 B weight loads
Offsets `+4288` (s4710), `+4800` (s4712) → `%r3998…%r4005`. Block
`[4288, 5320)`.
### E4 — s4738–s4744: phase 5 B weight loads
Offsets `+2240` (s4741), `+2752` (s4743) → `%r4247…%r4254`. Block
`[2240, 3272)`.
### E5 — s4769–s4775: phase 6 B weight loads
Offsets `+5312` (s4772), `+5824` (s4774) → `%r4496…%r4503`. Block
`[5312, 6344)`.
---
### E6 — s4800–s4970: score-bias seeds + packs of phases 5 and 6
171 statements: 24 weight loads, 80 `cvt.rn.satfinite.e4m3x2.f16x2`, 40
`mov.b32`, and the address setup. Two independent things happen.
**(a) The phase-7 score bias, s4800–s4850.** 24 `ld.weak.global.ca.v4.u32` at
`Wz + 16*laneid + 6336 + 512*i`, `i = 0…23`:
```
s4803 L8746: add.s64 %rd74, %rd281, 6336
s4804 L8748: ld.weak.global.ca.v4.u32 { %r4745,%r4746,%r4747,%r4748},[%rd74]
… +6848, +7360, +7888, … +18112 …
s4850 L8840: ld.weak.global.ca.v4.u32 { %r4837,%r4838,%r4839,%r4840},[%rd97]
```
24 × 512 bytes = **12288 bytes** = 6144 f16, the byte block `[6336, 18624)` of
the slab. The 96 registers `%r4745…%r4840` are phase 7's **C operand**: each
mma uses one distinct C pair and the chain analysis of §2.2 shows all 48 pairs
are distinct (grid dump: `C frags: %r4745,%r4746 … %r4839,%r4840`). So the
score GEMM adds a **full 64×96 f16 additive bias, one value per score element**,
laid out tile-major: with `m` = m-tile 0…3 and `n` = n-tile 0…11,
```
C(m,n) = the register pair at Wz + 6336 + 512*(4*(n>>1) + m) + 16*laneid + 4*((n&1)*2 + j), j = 0,1
byte base of tile (m,n) = 6336 + 512*(4*(n>>1) + m), 48 tiles × 512 B = 12288 B.
```
Verified directly on the emitted chain: `s4971` uses `C={%r4745,%r4746}` with
`A=%r5033…`, `B={%r5287,%r5288}`; `s4983` (the same m-tile 1 step later) uses
`C={%r4749,%r4750}`; `s4995` `C={%r4753,%r4754}`; `s5007` `C={%r4757,%r4758}` —
stride 4 registers per m-tile, 2 registers per n-tile. This is the same layout
formula enc0's E9 derived for its 12288-byte score bias
(`C(m,n) = load_tile(4*(n>>1)+m) + 4*(n&1)`); only the base differs (6336 here,
8384 there). What the table *is* cannot be decided from the PTX — see §6 U2.
**(b) Phase 7's operands are register-resident, s4851–s4970.** 80 `cvt` +
40 `mov.b32` produce **both** A and B of phase 7 from phase 5's and phase 6's D:
```
s4851 L8843: cvt.rn.satfinite.e4m3x2.f16x2 %rs1462, %r4275
s4852 L8846: cvt.rn.satfinite.e4m3x2.f16x2 %rs1461, %r4255
s4853 L8848: mov.b32 %r5287, {%rs1461, %rs1462} // phase 7 B frag 0
…
s4925 L9016: mov.b32 %r5033, {%rs1509, %rs1510} // phase 7 A frag 0
```
`%r5287` and `%r5033` are **bit-identical**: both are
`{pack(%r4255), pack(%r4275)}` (s4852–s4853 vs s4924–s4925, with `%r4255` ← the
phase-5 D of s4745 and `%r4275` ← that of s4747). Every further pair follows
the same pattern with the two halves swapped: s4865 `%r5307 =
{pack(%r4295), pack(%r4315)}` against s4937 `%r5153 = {pack(%r4315),
pack(%r4295)}`. So phase 7's B operand carries the *same data* as its A operand
(re-ordered for the row/col fragment layouts), i.e. the score GEMM multiplies one
projection by its own transpose; and 4 A quads + 12 B pairs = 64×32 · 32×96.
**Inputs:** phase 5's D `%r4255…%r4486`, phase 6's D `%r4504…%r4735`, `Wz`.
**Outputs:** the 48 C seeds `%r4745…%r4840`, the 4 A quads
(`%r5033…%r5036`, `%r5153…%r5156`, `%r5273…%r5276`, `%r5393…%r5396`) and the 12
B pairs (`%r5287…%r5398`). **Memory:** 24 weight loads.
---
### E7 — s5019–s8861: softmax of the 64×96 score, then the V transpose
3843 statements, **no memory access at all** (0 `ld.*`, 0 `st.*`). Sub-sections,
verified by counting each op's first and last statement:
| range | stmts | what |
|---|---|---|
| s5019–s7136 | 2118 | 96 per-element groups: scale, clamp, cubic, exponent extraction |
| s7137–s7222 | 86 | in-lane partial sum tree |
| s7223–s7344 | 122 | 16 `shfl.sync.bfly` → 8 row sums |
| s7345–s8117 | 773 | 192 `rcp.approx.ftz.f32` → 96 reciprocals |
| s8118–s8597 | 480 | 192/288 `mul.f16` → 96 probabilities |
| s8598–s8645 | 48 | `movmatrix` transpose of phase 6's D |
| s8646–s8861 | 216 | 144 `cvt.rn.satfinite.e4m3x2.f16x2` packs |
**(a) per-element exponent, s5019–s7136.** 96 groups of 22 statements. A group:
```
s5020 L9461: mov.f32 %f476, 0f3C8CCB50
s5021 L9464: cvt.rn.f16.f32 low, %f476
s5022 L9465: mov.b32 %r5402, {low,low}
s5023 L9469: mul.f16x2 %r5403,%r4921,%r5402
s5025 L9474: cvt.rn.f16.f64 %rs1542, %fd383 // -0.55615234375
s5028 L9483: max.f16x2 %r5406,%r5403,%r5408
s5033 L9497: min.f16x2 %r5409,%r5406,%r5411 // +0.55615234375
s5034 L9501: neg.f16x2 %r5412,%r5409
s5039 L9515: fma.rn.f16x2 %r5414,%r5409,%r5412,%r5417 // 0.92724609375
s5044 L9529: fma.rn.f16x2 %r5418,%r5409,%r5414,%r5421 // 1.375
s5045 L9532: shl.b32 %r16192, %r5418, 5
s5046 L9533: and.b32 %r7323, %r16192, 2145419232 // 0x7FE07FE0
```
For each of phase 7's 96 f16x2 D registers, per half (an f16 value `x`):
```
m = clamp(f16(x * 0.017181396484375), -0.55615234375, +0.55615234375)
t = f16(m*(-m) + 0.92724609375)
u = f16(m*t + 1.375) = f16(1.375 + m*(0.92724609375 - m^2))
E = bits(u)[9:5] // floor(32*frac(u)) -- top five mantissa bits
F = bits(u)[4:0] // low five mantissa bits
expval = f16 from bits (E << 10) | (F << 5) // = 2^(E-15)*(1 + F/32)
```
Exactly the enc0 E5 scheme (`((u_bits<<5) & 0x7FE07FE0)` drops `u`'s sign and
exponent so the mantissa lands in the exponent field): `expval ≈
2^(32·frac(u) − 15) = 2^(32u − 47)` with `u ∈ [1.03125, 1.71875]` because the
clamp `±0.55615… = √(0.92724609375/3)` is the turning point of
`0.92724609375·m − m³`. **This is not `exp`**: it is the cubic
`32·(0.375 + 0.92724609375·m − m³)` truncated to a 6-bit significand.
**(b),(c) row sums, s7137–s7344.** 80 `add.f16x2` reduce the 96 `expval`
registers in-lane; then eight times (one per row `g`, `g+8` of the four m-tiles):
```
s7223 L16329: shfl.sync.bfly.b32 %r7567,%r7563,%r3037,%r7570,%r3048 // delta 1
s7224 L16333: add.f16x2 %r7572,%r7563,%r7567
s7229 L16344: shfl.sync.bfly.b32 %r7576,%r7572,%r3046,%r7579,%r3048 // delta 2
s7230 L16348: add.f16x2 %r7581,%r7572,%r7576
s7232 L16353: add.f16 %rs2309,%rs2310,%rs2311
s7233 L16356: mov.b32 %r7778, {%rs2309, %rs2309}
```
Two butterfly steps over lane bits 0 (delta 1, `%r3037`) and 1 (delta 2,
`%r3046`), then `add.f16` of the two halves and a broadcast into both halves.
Result: **8 row sums** `%r7778 %r7782 %r7826 %r7830 %r7874 %r7878 %r7922
%r7926`, one per row of the 64-row window.
**There is no row maximum anywhere in this epilogue.** Enumerated: every one of
the 96 `max.f16x2` (s5028…s7121) is immediately followed by a `min.f16x2`
(s5033…s7125) and preceded by the `mul.f16x2` with `%r5402` (the 0.017181 scale)
— one clamp triple per element group. The 96 `neg.f16x2` (s5034…s7126) feed the
first `fma`, and the 16 `shfl.sync.bfly` are the row sums above. Nothing else
touches a D register. Contrast E38 (§3/E38), which *does* compute a real row
max.
**(d) reciprocals, s7345–s8117.** 192 `rcp.approx.ftz.f32` = 96 f16x2
reciprocals, each `cvt.f32.f16 → rcp.approx.ftz.f32 → cvt.rn.f16.f32` on a row
sum (`s7350 L16652: mov.b32 {hl, hu}, %r7778` / `s7353 L16655:
rcp.approx.ftz.f32 fl, fl`), duplicated four times per row sum (once per n-tile).
**(e) probabilities, s8118–s8597.**
```
s8118 L17897: mov.b32 {%rs2334, %rs2337}, %r7323 // expval
s8119 L17898: mov.b32 {%rs2335, %rs2338}, %r7735 // 1/rowsum
s8120 L17900: mul.f16 %rs2336,%rs2337,%rs2338
s8121 L17904: mul.f16 %rs2333,%rs2334,%rs2335
s8122 L17907: mov.b32 %r8071, {%rs2333, %rs2336}
```
`p = expval · (1/rowsum)`; the row sums cancel the constant `2⁻⁴⁷` of (a), so
`p_ij ∝ 2^(32·u_ij)`. 96 f16x2 results.
**(f) V transpose, s8598–s8645.** 48 `movmatrix.sync.trans.aligned.m8n8.b16`, one
per register of **phase 6's D** (`%r4504, %r4505, %r4514, %r4515, %r4544,
%r4545, … %r4734, %r4735` — exactly the 24 C/D pairs listed at s4776–s4799, each
once):
```
s8598 L18954: movmatrix.sync.trans.aligned.m8n8.b16 %r7927, %r4504
s8645 L19095: movmatrix.sync.trans.aligned.m8n8.b16 %r8021, %r4735
```
48 × 64 = 3072 values = the whole 96×32 tile of phase 6's D.
**(g) packs, s8646–s8861.** 144 `cvt` / 72 `mov.b32` in two groups:
* s8646–s8717 — from the **movmatrix** results → phase 8's 12 B pairs
(`%r8533,%r8534`, `%r8543,%r8544`, … `%r8633,%r8644`), i.e. the transposed V:
`s8646 L19098: cvt.rn.satfinite.e4m3x2.f16x2 %rs2910, %r7935` /
`s8648 L19103: mov.b32 %r8533, {%rs2909, %rs2910}`.
* s8718–s8861 — from the **probabilities** → phase 8's 12 A quads
(`%r8239…%r8242`, `%r8259…`, `%r8279…`, `%r8359…`, `%r8379…`, `%r8399…`,
`%r8479…`, `%r8499…`, `%r8519…`, `%r8599…`, `%r8619…`, `%r8639…%r8642`):
`s8720 L19271: mov.b32 %r8239, {%rs2957, %rs2958}`.
**Inputs:** phase 7's 96 D f16x2 (`%r4921…%r5392`), phase 6's 48 D
(`%r4504…%r4735`), `%r3037/%r3046/%r3048`, the five constants of §1.2.
**Outputs:** the 5 constants + phase 8's 12 A quads and 12 B pairs.
**Memory:** none.
---
### E8 — s8910–s9078: phase-8 D → shared, phase 9 A, table add → phase 9 C
169 statements, four moves.
**(a) stage phase 8's D into shared, s8910–s8968.**
```
s8910 L19937: bar.sync 0
s8911 L19938: shl.b32 %r16320, %r10, 11 // %tid.z * 2048
s8912 L19939: add.s32 %r16321, %r3216, %r16320 // %r3216 = smem symbol
s8915 L19944: add.s32 %r16323, %r16321, %r16322 // + 16*laneid
s8928 L19973: st.shared.v4.u32 [%r16323], {%r16327, %r16326, %r16325, %r16324}
s8941 L20002: st.shared.v4.u32 [%r16323+512], {…}
s8954 L20031: st.shared.v4.u32 [%r16323+1024], {…}
s8967 L20060: st.shared.v4.u32 [%r16323+1536], {…}
s8968 L20061: bar.sync 0
```
Four v4 stores (16 bytes/lane) at `smem + 2048*%tid.z + 16*laneid + {0,512,1024,
1536}`. Each v4 word is an e4m3 pack of **two** distinct phase-8 D registers
(e.g. s8916 `cvt %rs3054, %r8267`, s8917 `cvt %rs3053, %r8207`, s8924
`mov.b32 %r16324, {%rs3059, %rs3060}`); all 32 `cvt` in the block name distinct
registers, so **32 of phase 8's 48 D registers are staged** here, 16 words per
lane.
**(b) phase 9's A, s8969–s8974.**
```
s8969 L20062: shl.b32 %r16340, %r10, 9 // %tid.z * 512
s8970 L20063: add.s32 %r16341, %r3216, %r16340
s8973 L20068: add.s32 %r16343, %r16341, %r16342 // + 16*laneid
s8974 L20069: ld.shared.v4.u32 {%r16344, %r16345, %r16346, %r16347}, [%r16343]
```
One A quad (`%r16344…%r16347`), i.e. the e4m3-packed phase-8 D, re-read through
shared. Phase 9's mma (s9079) uses exactly this quad.
**(c) phase 9's B, s8975–s8989.** 6 `ld.weak.global.ca.v4.u32` at
`W + 16*laneid + 18624 + 512*i`, `i = 0…5` (s8978 `add.s64 %rd98, %rd283,
18624`) → `%r8682…%r8705`, the 12 B pairs of phase 9. Note the base is `%rd283 =
%rd2 + 16*laneid` (s8977) — **no `%tid.z` term**, unlike E1–E6.
**(d) per-column residual table → phase 9's C, s8990–s9078.**
```
s8995 L20106: ld.global.v2.u16 {%rs4364, %rs4365}, [%rd286+86224]
… 86240, 86256, 86272, 86288, 86304, 86320, 86336, 86352, 86368, 86384, 86208
s9007 L20119: add.f16 %rs3088,%rs4387,%rs1103
s9008 L20123: add.f16 %rs3085,%rs4386,%rs1100
s9009 L20126: mov.b32 %r8715, {%rs3085, %rs3088}
```
12 `ld.global.v2.u16` at `W + ((laneid<<2)&12) + {86208, 86224, …, 86384}` = 192
bytes = 96 f16, a per-column vector over the 96-wide N axis. 48 `add.f16` add
them (pair-swapped) to the 48 halves of 24 **prologue** registers and 24
`mov.b32` build the 24 registers `%r8715…%r8826` = phase 9's **C operand**.
The 48 added operands are `%rs1100 … %rs1361`, and every one of them is defined
by a prologue `mov.b32` from the *quantised input patch* — `%rs1100/%rs1103` ←
`%r2798` (s3366, source line 4684), `%rs1106/%rs1109` ← `%r2802`, … — where
`%r2798` is itself `cvt.rn.f16x2.e4m3x2 %r2798, %rs128` (s3320), i.e. the first
element of the input image read at s176. So
```
C9 = column_table[86208] + (the block's quantised input patch, re-read as f16)
```
— an *input* skip connection, **not** phase 8's D. (This is a surprising but
direct reading: the 48 `add.f16` sources are the halves of `%r2798…%r2845`, the
prologue's `cvt.rn.f16x2.e4m3x2` results, and no statement anywhere redefines
them; see §6 U9.)
**Inputs:** phase 8's 48 D (staged in (a)), the prologue's 24 quantised input
registers `%r2798…`, table `86208`, `%tid.z`, `%r3216`, `W`.
**Outputs (live 49):** `%r16344…%r16347` (via shared), the 24 C seeds, the 12 B
pairs. **Memory:** 6 weight loads + 12 table reads + 2 barriers + 4 shared
stores + 1 shared load.
---
### E9 — s9091–s9109: phase 10 A from shared + phase 10 B
19 statements.
```
s9091 L20419: mov.u32 %r8827, %laneid
s9092 L20421: shl.b32 %r16349, %r8827, 4
s9094 L20423: ld.shared.v4.u32 {%r16351, %r16352, %r16353, %r16354}, [%r16350+2048]
s9099 L20431: ld.weak.global.ca.v4.u32 { %r8829,%r8830,%r8831,%r8832},[%rd104]
… 5 more at 512 stride …
s9109 L20451: ld.weak.global.ca.v4.u32 { %r8849,%r8850,%r8851,%r8852},[%rd109]
```
One A quad read from `smem + 16*laneid + 2048` (i.e. the *next* staged slot of
(a) in E8), and 6 weight fragments at `W + 16*laneid + 40128 + 512*i` = phase
10's B (`%r8829…%r8852`). The shared slot is 2048 bytes above the slot phase 9
read, so the four staged v4 words serve phases 9, 10, 11, 12 at
`base + {0, 2048, 4096, 6144}`.
### E10 — s9122–s9140: phase 11 A from shared + phase 11 B
Same shape; `s9125 L20542: ld.shared.v4.u32 {%r16357…%r16360}, [%r16356+4096]` and
6 weight fragments at `W + 16*laneid + 61632 + 512*i` (s9130 …) → `%r8975…%r8998`.
### E11 — s9153–s9171: phase 12 A from shared + phase 12 B
`s9156 L20661: ld.shared.v4.u32 {%r16363…%r16366}, [%r16362+6144]` and 6 weight
fragments at `W + 16*laneid + 83136 + 512*i` (s9161 …) → `%r9121…%r9144`.
Note phases 9–12 also chain their C: phase 12's C is
`{%r8999,%r9000}` = phase 11's D (s9141 / s9172), and likewise 10←9, 11←10.
---
### E12 — s9184–s9819: the RMS norm before the MLP band
636 statements. Structure (counts from the op histogram of s9184–s9819: 182
`mov.b32`, 144 `mul.f16`, 50 `add.f16`, 48 each `cvt.f32.f16` /
`rsqrt.approx.ftz.f32` / `cvt.rn.f16.f32`, 26 `add.f16x2`, 24
`cvt.rn.satfinite.e4m3x2.f16x2`, 12 `ld.global.v2.u16`, 6 weight loads, 4
`shfl.sync.bfly`):
| range | stmts | op |
|---|---|---|
| s9184–s9281 | 98 | 48 `mul.f16` — the squares of phase 12's D |
| s9282–s9301 | 20 | 21 `add.f16x2` — in-lane reduction tree |
| s9302–s9344 | 43 | 4 `shfl.sync.bfly` + `add.f16x2` + `add.f16` + `+ eps`, broadcast into 24 b32 |
| s9345–s9405 | 61 | 48 `add.f16` more (24 duplicated eps-bearing sums) |
| s9406–s9598 | 193 | 48 `rsqrt.approx.ftz.f32` (24 inverses) |
| s9599–s9615 | 17 | 12 gain loads `+86400 … +86576` |
| s9616–s9687 | 72 | 48 `mul.f16` — `inv · gain` |
| s9688–s9759 | 72 | 48 `mul.f16` — `x · (inv·gain)` |
| s9760–s9774 | 15 | 6 weight loads `+86632 … +89192` (phase 13's B) |
| s9775–s9783 | 9 | 4 `ld.global.u32` `+89664 … +89712` (phase 13's C seeds) |
| s9784–s9819 | 36 | 24 packs → phase 13's A |
Evidence:
```
s9185 L20776: add.s32 %r182, %r2, %r181 // %r2 + 2*%tid.z
s9186 L20777: mov.b32 {%rs3838, %rs3841}, %r9145 // unpack a D register
s9187 L20779: mul.f16 %rs3232,%rs3841,%rs3841 // square (high half)
s9188 L20783: mul.f16 %rs3229,%rs3838,%rs3838 // square (low half)
s9282 L21018: add.f16x2 %r9265,%r9266,%r9267
s9303 L21101: add.f16x2 %r9326,%r9313,%r9319
s9308 L21112: shfl.sync.bfly.b32 %r9330,%r9326,%r3037,%r9333,%r3048
s9317 L21136: add.f16 %rs3373,%rs3374,%rs3375
s9333 L21179: cvt.rn.f16.f64 %rs3379, %fd1 // eps = 2^-13
s9334 L21183: add.f16 %rs3383,%rs3373,%rs3379
s9410 L21407: rsqrt.approx.ftz.f32 fl, fl
s9604 L21720: ld.global.v2.u16 {%rs4388, %rs4389}, [%rd295+86416]
s9616 L21732: mov.b32 {%rs3525, %rs3528}, %r9369
s9688 L21949: mul.f16 %rs3671,%rs3841,%rs3527 // x * (inv*gain)
s9690 L21956: mov.b32 %r15561, {%rs3668, %rs3671} // the normed register
s9784 L22205: cvt.rn.satfinite.e4m3x2.f16x2 %rs3813, %r15562
s9786 L22210: mov.b32 %r9540, {%rs3812, %rs3813}
s9780 L22200: ld.global.u32 %r9477, [%rd300+89664]
```
**What it computes.** Phase 12's D is 24 registers = 48 f16/lane; each register
pairs `(row g, cols 2t,2t+1)` with `(row g+8, cols 2t,2t+1)`, and two registers
(`%r9145`,`%r9146`) are one n-tile. For each of the two rows a lane holds:
```
sumsq[row] = Σ_{c=0..95} x[row,c]^2 (f16, one shfl.bfly pair)
inv = rsqrt.approx.ftz.f32(f32(f16(sumsq + 2^-13))) // rounded to f16
out[row,c] = x[row,c] * inv * gain[c]
```
* **There is no mean subtraction and no `1/N`**: `%rs3232/%rs3229` are raw
squares (`mul.f16 %rs3232,%rs3841,%rs3841`), the tree only adds, and the only
constant added is `%fd1 = 2⁻¹³` (s9333/s9334). The quantity is the raw sum of
96 squares plus `2⁻¹³`; the mean is never formed. This is an **RMS norm**, not
a mean-subtracting LayerNorm.
* `gain[c]` is read from `W + ((laneid<<2)&12) + {86400, 86416, …, 86576}` (12
`v2.u16` at 16-byte stride = 192 bytes = 96 f16), i.e. a per-column vector over
the 96 columns, constant across rows.
* the two butterfly steps (`%r3037 = 1`, `%r3046 = 2`, segmask 31, membermask
−1 at s9307/s9313) reduce over the four lanes with equal `laneid>>2`, which
between them hold all 96 columns of the row; `add.f16 %rs3373,%rs3374,%rs3375`
folds the two column halves. The inverse is broadcast into both halves
(`mov.b32 %r9370, {%rs3380, %rs3383}`) so one row value serves all n-tiles.
* the norm's *bias* is **not** added here. It is the 4 `ld.global.u32` at the end
(s9780–s9783), which become phase 13's C seeds as `{%r9477, %r9477}` etc. —
a per-column bias replicated over the 16 rows.
**The prologue's `normalise:96@s3812` is the same function.** Its op block
(s3250–s4497) has the same shape and the same missing pieces: 48
`cvt.rn.f16x2.e4m3x2` quantise the 24 `ld.global.v2.u16` input loads (s176,
s328, … s3316, all through `%rd12 = %rd4 + 4*index`, `%rd4 = param_0+8`, i.e.
the input image); 96 `mul.f16` square them in place
(`s3431 L4846: mul.f16 %rs321,%rs1199,%rs1199`); 52 `add.f16x2` + 8
`shfl.sync.bfly` + `add.f16` reduce; `s3662 L5488: mov.f64 %fd1,
0d3F20000000000000` / `s3664 L5494: add.f16 %rs526,%rs510,%rs522` add the
*same* `2⁻¹³`; 96 `rsqrt.approx.ftz.f32` (48 pairs, `s3812 L5934:
rsqrt.approx.ftz.f32 fl, fl`) invert; the 96 products are multiplied by a
per-column gain read as 12 `ld.global.v2.u16` at `W + ((laneid<<2)&12) +
{16, 32, …, 176, 0}` (s4198–s4209, 192 bytes = 96 f16); 96 more `mul.f16`
(`s4211 L6573: mul.f16 %rs811,%rs812,%rs1459`) apply the gain; 48
`cvt.rn.satfinite.e4m3x2.f16x2` (s4498–s4521) requantise and six
`st.shared.v4.u32` (s4540, s4553, s4566, s4576, s4581, s4586) stage the 18 A
quads. No mean, no `1/N`, no bias add — **also an RMS norm**, with its bias
deferred to a later GEMM's C exactly as in E12.
**The normed tile is the A operand of every odd phase 13…35.** E12's output
registers `%r15561…%r15584` (24 b32) are re-packed not only here (s9784–s9819,
→ `%r9540,%r9541,%r9542,%r9543` … `%r9580…%r9583`, i.e. three 16×32 A slices)
but again in **every even-numbered epilogue E14, E16, …, E34**:
`%r15561` is read by exactly the s9785 (E12), s10126 (E14), s10374 (E16),
s10622 (E18), s10870 (E20), s11118 (E22), s11366 (E24), s11614 (E26), s11862
(E28), s12110 (E30), s12358 (E32), s12606 (E34) — twelve repacks, one per band
phase. So all twelve odd phases 13, 15, …, 35 share **one** input tile.
**Inputs:** phase 12's 24 D, `%fd1`, the gain table, `W`. **Outputs (54 live):**
phase 13's 3 A quads (`%r9540…%r9543`, `%r9560…%r9563`, `%r9580…%r9583`), phase
13's 4 C seeds (`%r9477, %r9487, %r9537, %r9547`) and 12 B pairs (`%r9419…%r9442`,
6 loads at `+86592…+89152`), the 24 normed registers `%r15561…%r15584` (re-read by
E14, E16, …, E34). **Memory:** 12 table + 6 weight loads.
---
### E13 — s9832–s10088: clamped cubic + residual/table, packs
257 statements. This is the epilogue that materialises `%f861…%f864`.
**(a) the activation, s9832–s10076.** 8 groups (one per chain-final D register of
phase 13: `%r9508 %r9518 %r9509 %r9519 %r9568 %r9578 %r9569 %r9579`), 17
statements each:
```
s9833 L22375: mov.f32 %f861, 0f3ED306EB
s9836 L22382: mov.f32 %f862, 0f3DA60DD6
s9839 L22389: mov.f32 %f863, 0f3F000000
s9842 L22396: mov.f32 %f864, 0f40000000
s9845 L22404: neg.f16x2 %r9593,%r9592 // -2.0
s9846 L22408: max.f16x2 %r9595,%r9508,%r9593 // max(x, -2)
s9847 L22412: min.f16x2 %r9598,%r9595,%r9592 // min(·, +2)
s9848 L22416: abs.f16x2 %r9601,%r9598 // |y|
s9849 L22420: mul.f16x2 %r9603,%r9590,%r9601 // 0.0810546875*|y|
s9850 L22424: sub.f16x2 %r9606,%r9589,%r9603 // 0.412109375 - that
s9851 L22428: mul.f16x2 %r9609,%r9598,%r9606 // y * that
s9852 L22432: add.f16x2 %r9612,%r9591,%r9609 // 0.5 + that
s9853 L22436: mul.f16x2 %r9615,%r9508,%r9612 // x * g
```
Per element, `y = clamp(x, −2, +2)` and
```
g = 0.5 + y * (0.412109375 − 0.0810546875 * |y|) // f16 throughout
out = x * g
```
`g` is a cubic ramp: `g(+2) = 1` so `out = x` for `x ≥ 2`; `g(−2) = 0` so
`out = 0` for `x ≤ −2`. The constants and the op order are **byte-identical to
enc0's E13** (`0f3ED306EB`, `0f3DA60DD6`, `0.5`, `2.0`, `neg/max/min/abs/mul/
sub/mul/add/mul`): this is the same clamped cubic, not a GELU, not a sigmoid and
not a polynomial in `x`. Reproduce the formula, not `x·sigmoid(x)`.
**(b) the residual + per-column table → phase 14's C, s9990–s10076.**
```
s9993 L22895: ld.global.v2.u16 {%rs4412, %rs4413}, [%rd305+92816]
… 92832, 92848, 92864, 92880, 92896, 92912, 92928, 92944, 92960, 92976, 92800
s10005 L22908: add.f16 %rs3839,%rs4435,%rs3841
s10006 L22912: add.f16 %rs3836,%rs4434,%rs3838
s10007 L22915: mov.b32 %r9863, {%rs3836, %rs3839}
```
12 `ld.global.v2.u16` at `W + ((laneid<<2)&12) + {92800…92976}` (192 bytes = 96
f16, one per column), then 48 `add.f16` and 24 `mov.b32` producing
`%r9863…%r9974`, the 24 registers phase 14 uses as its C operand. `%rs3838/
%rs3841` are the two halves of `%r9145` — **phase 12's D**, not phase 13's, so
```
C14 = D12 + column_table[92800] (a residual, added to all 16 rows)
```
**(c) phase 14's B, s9977–s9989.** 6 `ld.weak.global.ca.v4.u32` at
`W + 16*laneid + 89728 + 512*i` → `%r9822…%r9845`.
**(d) packs, s10077–s10088.** 8 `cvt` + 4 `mov.b32` → `%r9967, %r9969, %r9968,
%r9970` = phase 14's A quad, from the activation outputs (`%r9615`, `%r9644`,
`%r9673`, `%r9731`, `%r9760`, `%r9789`, `%r9818`, `%r9702`):
```
s10077 L23124: cvt.rn.satfinite.e4m3x2.f16x2 %rs3981, %r9731
s10078 L23127: cvt.rn.satfinite.e4m3x2.f16x2 %rs3980, %r9615
s10079 L23129: mov.b32 %r9967, {%rs3980, %rs3981}
```
**Inputs:** phase 13's 8 chain-final D, phase 12's 24 D, table `92800`, `W`.
**Outputs (24 live):** `%f861…%f864`, `%r9967…%r9970`, `%r9863…%r9974`,
`%r9822…%r9845`. **Memory:** 6 weight + 12 table loads.
### E14 — s10101–s10160: phase 15 B/C + packs of the normed tile
60 statements: 6 weight loads at `+92992…+95552` → `%r9976…%r9999` (phase 15's
B); 4 `ld.global.u32` at `+96064, +96080, +96096, +96112` → `%r10034, %r10044,
%r10094, %r10104` (phase 15's C seeds, each used as `{%rX, %rX}`); and 24 packs
of **E12's normed registers** into phase 15's 3 A quads:
```
s10126 L23279: cvt.rn.satfinite.e4m3x2.f16x2 %rs3988, %r15561
s10127 L23281: mov.b32 %r10097, {%rs3988, %rs3989}
… %r10098, %r10099, %r10100 (quad 1) ; %r10117…%r10120; %r10137…%r10140
```
Note the pack order is `%r10097←(%r15561,%r15562)`, `%r10099←(%r15563,%r15564)`,
`%r10098←(%r15565,%r15566)`, `%r10100←(%r15567,%r15568)` (s10125–s10136), i.e.
the whole 16×96 normed tile is re-quantised into 12 b32 = three 16×32 A slices.
### E15 — s10173–s10336: clamped cubic on phase 15's D
164 statements = 8 activation groups + 6 weight loads + 4 packed b32. Identical
to E13(a) but on phase 15's chain-final D (`%r10065 %r10075 %r10066 %r10076
%r10125 %r10135 %r10126 %r10136`) and with **no constants of its own** and **no
`ld.global`** — the four `cvt.rn.f16.f32` read `%f861…%f864` defined in E13:
```
s10174 L23448: cvt.rn.f16.f32 low, %f861
s10183 L23475: max.f16x2 %r10152,%r10065,%r10150
s10190 L23503: mul.f16x2 %r10172,%r10065,%r10169
s10314 L23933: ld.weak.global.ca.v4.u32 { %r10379,…},[%rd140] // +96128
s10325 L23956: cvt.rn.satfinite.e4m3x2.f16x2 %rs4013, %r10288
s10327 L23961: mov.b32 %r10523, {%rs4012, %rs4013}
```
Outputs phase 16's A quad (`%r10523…%r10526`) and phase 16's B (6 loads at
`+96128…+98688`). **No column-bias add.**
### E16 — s10349–s10408: phase 17 B/C + packs of the normed tile
Identical in shape to E14: B at `+99200 … +101760`, C words at
`+102272, +102288, +102304, +102320` (`s10369 L24103: ld.global.u32 %r10590,
[%rd317+102272]`), and 24 packs of `%r15561…%r15584` (s10373 ff.) → phase 17's
three A quads `%r10653…%r10656`, `%r10673…%r10676`, `%r10693…%r10696`.
### E17 — s10421–s10584: clamped cubic on phase 17's D
164 statements. 8 activation groups (17 statements each, the E13(a) shape) on
phase 17's chain-final D registers `%r10621 %r10631 %r10622 %r10632 %r10681
%r10691 %r10682 %r10692`; no constants of its own (`cvt.rn.f16.f32 low, %f861`
opens the first group at s10422); 6 weight loads at `W + 16*laneid +
102336 + 512*i` = phase 18's B; 8 `cvt` + 4 `mov.b32` → phase 18's A quad
`%r11079…%r11082`.
### E18 — s10597–s10656: phase 19 B/C loads + packs of the normed tile
60 statements: 6 weight loads at `+105408 … +107968` (phase 19's B), 4
`ld.global.u32` at `+108480, +108496, +108512, +108528` (phase 19's C seeds,
each used as `{%rX, %rX}`), and 24 `cvt` / 12 `mov.b32` of `%r15561…%r15584` →
phase 19's three A quads `%r11209…%r11212`, `%r11229…%r11232`,
`%r11249…%r11252`. Evidence:
`s10601 L24906: ld.weak.global.ca.v4.u32 { %r11088,…},[%rd158]`;
`s10617 L24935: ld.global.u32 %r11146, [%rd324+108480]`.
### E19 — s10669–s10832: clamped cubic on phase 19's D
164 statements, identical to E17. Chain-final D `%r11177 %r11187 %r11178
%r11188 %r11237 %r11247 %r11238 %r11248`; phase 20's B at `+108544 … +111104`;
phase 20's A quad `%r11635…%r11638`.
### E20 — s10845–s10904: phase 21 B/C loads + packs of the normed tile
60 statements. B `+111616 … +114176`; C `+114688, +114704, +114720, +114736`;
A quads `%r11765…%r11768`, `%r11785…%r11788`, `%r11805…%r11808`. Evidence:
`s10849 L25738: ld.weak.global.ca.v4.u32 { %r11644,…},[%rd170]`;
`s10865 L25767: ld.global.u32 %r11702, [%rd331+114688]`.
### E21 — s10917–s11080: clamped cubic on phase 21's D
164 statements. Chain-final D `%r11733 %r11743 %r11734 %r11744 %r11793
%r11803 %r11794 %r11804`; phase 22's B at `+114752 … +117312`; phase 22's A
quad `%r12191…%r12194`.
### E22 — s11093–s11152: phase 23 B/C loads + packs of the normed tile
60 statements. B `+117824 … +120384`; C `+120896, +120912, +120928, +120944`;
A quads `%r12321…%r12324`, `%r12341…%r12344`, `%r12361…%r12364`. Evidence:
`s11097 L26570: ld.weak.global.ca.v4.u32 { %r12200,…},[%rd182]`;
`s11113 L26599: ld.global.u32 %r12258, [%rd338+120896]`.
### E23 — s11165–s11328: clamped cubic on phase 23's D
164 statements. Chain-final D `%r12289 %r12299 %r12290 %r12300 %r12349
%r12359 %r12350 %r12360`; phase 24's B at `+120960 … +123520`; phase 24's A
quad `%r12747…%r12750`.
### E24 — s11341–s11400: phase 25 B/C loads + packs of the normed tile
60 statements. B `+124032 … +126592`; C `+127104, +127120, +127136, +127152`;
A quads `%r12877…%r12880`, `%r12897…%r12900`, `%r12917…%r12920`. Evidence:
`s11345 L27402: ld.weak.global.ca.v4.u32 { %r12756,…},[%rd194]`;
`s11361 L27431: ld.global.u32 %r12814, [%rd345+127104]`.
### E25 — s11413–s11576: clamped cubic on phase 25's D
164 statements. Chain-final D `%r12845 %r12855 %r12846 %r12856 %r12905
%r12915 %r12906 %r12916`; phase 26's B at `+127168 … +129728`; phase 26's A
quad `%r13303…%r13306`.
### E26 — s11589–s11648: phase 27 B/C loads + packs of the normed tile
60 statements. B `+130240 … +132800`; C `+133312, +133328, +133344, +133360`;
A quads `%r13433…%r13436`, `%r13453…%r13456`, `%r13473…%r13476`. Evidence:
`s11593 L28234: ld.weak.global.ca.v4.u32 { %r13312,…},[%rd206]`;
`s11609 L28263: ld.global.u32 %r13370, [%rd352+133312]`.
### E27 — s11661–s11824: clamped cubic on phase 27's D
164 statements. Chain-final D `%r13401 %r13411 %r13402 %r13412 %r13461
%r13471 %r13462 %r13472`; phase 28's B at `+133376 … +135936`; phase 28's A
quad `%r13859…%r13862`.
### E28 — s11837–s11896: phase 29 B/C loads + packs of the normed tile
60 statements. B `+136448 … +139008`; C `+139520, +139536, +139552, +139568`;
A quads `%r13989…%r13992`, `%r14009…%r14012`, `%r14029…%r14032`. Evidence:
`s11841 L29066: ld.weak.global.ca.v4.u32 { %r13868,…},[%rd218]`;
`s11857 L29095: ld.global.u32 %r13926, [%rd359+139520]`.
### E29 — s11909–s12072: clamped cubic on phase 29's D
164 statements. Chain-final D `%r13957 %r13967 %r13958 %r13968 %r14017
%r14027 %r14018 %r14028`; phase 30's B at `+139584 … +142144`; phase 30's A
quad `%r14415…%r14418`.
### E30 — s12085–s12144: phase 31 B/C loads + packs of the normed tile
60 statements. B `+142656 … +145216`; C `+145728, +145744, +145760, +145776`;
A quads `%r14545…%r14548`, `%r14565…%r14568`, `%r14585…%r14588`. Evidence:
`s12089 L29898: ld.weak.global.ca.v4.u32 { %r14424,…},[%rd230]`;
`s12105 L29927: ld.global.u32 %r14482, [%rd366+145728]`.
### E31 — s12157–s12320: clamped cubic on phase 31's D
164 statements. Chain-final D `%r14513 %r14523 %r14514 %r14524 %r14573
%r14583 %r14574 %r14584`; phase 32's B at `+145792 … +148352`; phase 32's A
quad `%r14971…%r14974`.
### E32 — s12333–s12392: phase 33 B/C loads + packs of the normed tile
60 statements. B `+148864 … +151424`; C `+151936, +151952, +151968, +151984`;
A quads `%r15101…%r15104`, `%r15121…%r15124`, `%r15141…%r15144`. Evidence:
`s12337 L30730: ld.weak.global.ca.v4.u32 { %r14980,…},[%rd242]`;
`s12353 L30759: ld.global.u32 %r15038, [%rd373+151936]`.
### E33 — s12405–s12568: clamped cubic on phase 33's D
164 statements. Chain-final D `%r15069 %r15079 %r15070 %r15080 %r15129
%r15139 %r15130 %r15140`; phase 34's B at `+152000 … +154560`; phase 34's A
quad `%r15527…%r15530`.
### E34 — s12581–s12640: phase 35 B/C loads + packs of the normed tile
60 statements. B `+155072 … +157632`; C `+158144, +158160, +158176, +158192`;
A quads `%r15657…%r15660`, `%r15677…%r15680`, `%r15697…%r15700`. Evidence:
`s12585 L31562: ld.weak.global.ca.v4.u32 { %r15536,…},[%rd254]`;
`s12601 L31591: ld.global.u32 %r15594, [%rd380+158144]`.
### E35 — s12653–s12816: clamped cubic on phase 35's D
164 statements. Chain-final D `%r15625 %r15635 %r15626 %r15636 %r15685
%r15695 %r15686 %r15696`; phase 36's B at `+158208 … +160768`
(`s12794 L32253: ld.weak.global.ca.v4.u32 { %r15939,…},[%rd260]`); phase 36's A
quad `%r16083…%r16086`. This is the last of the twelve band activations; its
output feeds phase 36, whose output E36 packs (and this is where the A-quad
chain from the normed tile ends).
#### Shape of the whole MLP band (E12–E36)
```
E12 normed tile N (24 b32, %r15561…%r15584) — RMS norm of the attention output
├─ pack → P13 A (s9784) P13 : A = N, B = W+86592, C = bias@89664 → D13
│ E13: clamped cubic(D13) pack → P14 A; D12 + table@92800 → P14 C; P14 B = W+89728
├─ pack → P15 A (s10126) P15 : A = N, B = W+92992, C = bias@96064 → D15
│ E15: clamped cubic(D15) pack → P16 A; P16 B = W+96128, C = D14
├─ pack → P17 A (s10373) P17 : A = N, B = W+99240, C = bias@102272 → D17
│ E17: clamped cubic(D17) pack → P18 A; P18 B = W+102336, C = D16
⋮ (twenty-four phases, twelve repetitions of the pair)
├─ pack → P35 A (s12606) P35 : A = N, B = W+155072, C = bias@158144 → D35
│ E35: clamped cubic(D35) pack → P36 A
└───────────────────────── P36 : A = act(D35), B = W+158208, C = D34 → D36
```
So the band is **twelve branches off one shared normed tile**, each branch being
the pair (odd phase: 48×96×32 banded GEMM with clamped cubic and a per-column
bias; even phase: 16×96×32 GEMM whose C is the running residual `D12 + table`
and whose output is fed to the next odd phase as `B`), and the residual chain
runs `D12 → D14 → D16 → … → D36`. `D36` (12 registers, 16×96) is the band's
output and is the input to E36.
---
### E36 — s12829–s13698: arena scatter, shared staging, phase 37 A/B/C
870 statements. Four sequential moves.
**(a) requantise, s12829–s12864.** 24 `cvt.rn.satfinite.e4m3x2.f16x2` + 12
`mov.b32` → `%r183…%r194` (12 b32), the requantised 16×96 output of phase 36.
Each pair of e4m3 registers is built from `(reg0, reg2)` / `(reg1, reg3)` of a
phase-36 D brace group:
```
s12829 L32388: cvt.rn.satfinite.e4m3x2.f16x2 %rs4341, %r15991
s12830 L32391: cvt.rn.satfinite.e4m3x2.f16x2 %rs4340, %r15971
s12831 L32393: mov.b32 %r183, {%rs4340, %rs4341}
```
**(b) plane-arena scatter to `param+48`, s12865–s13009.**
```
s12865 L32471: ld.param.u64 %rd383, [%rd1+-32] // %rd1 = param_0+80 → param_0+48
s12866 L32472: cvta.to.global.u64 %rd5, %rd383
s12868 L32476: shr.u32 %r195, %r16115, 2 // g = laneid>>2
s12869 L32477: and.b32 %r196, %r16115, 3 // t = laneid&3
s12870 L32478: shr.u32 %r16389, %r16115, 5
s12872 L32480: add.s32 %r16391, %r182, %r16389 // y = %r182 + (laneid>>5)
s12878 L32486: add.s32 %r16392, %r1, %r16390 // x = %r1 + (g&7)
s12884 L32492: mad.lo.s32 %r197, %r5, %r16391, %r16393 // %r5 = 8*ex
s12885 L32493: add.s32 %r16394, %r196, %r197 // + t (+ guard bit)
s12886 L32494: selp.b32 %r198, -1, %r16394, %p1
s12887 L32495: setp.lt.s32 %p197, %r198, 0
s12888 L32496: @%p197 bra $L__BB1_196
s12889 L32498: mul.wide.s32 %rd384, %r198, 4
s12890 L32499: add.s64 %rd385, %rd5, %rd384
s12891 L32500: st.global.u32 [%rd385], %r183
```
Twelve `st.global.u32`, all with `idx = 8·ex·y + 8·x + d` in units of 4 bytes:
| # | stmt | value | index base | guard | d |
|---|---|---|---|---|---|
| 1 | s12891 | `%r183` | `%r197 = 8*ex*(%r182 + (laneid>>5)) + 8*(%r1 + (g&7))` | p1 | `t` |
| 2 | s12900 | `%r184` | `%r197` | p1 | `t\|4` |
| 3 | s12933 | `%r185` | `%r201 = 8*ex*(%r182 + ((g+8)>>3)) + 8*(%r1 + ((g+8)&7))` | p2 | `t` |
| 4 | s12941 | `%r186` | `%r201` | p2 | `t\|4` |
| 5 | s12950 | `%r187` | `%r204 = %r197 + %r6` | p1 | `t` |
| 6 | s12958 | `%r188` | `%r204` | p1 | `t\|4` |
| 7 | s12967 | `%r189` | `%r207 = %r201 + %r6` | p2 | `t` |
| 8 | s12975 | `%r190` | `%r207` | p2 | `t\|4` |
| 9 | s12984 | `%r191` | `%r210 = %r204 + %r6` | p1 | `t` |
| 10 | s12992 | `%r192` | `%r210` | p1 | `t\|4` |
| 11 | s13001 | `%r193` | `%r213 = %r207 + %r6` | p2 | `t` |
| 12 | s13009 | `%r194` | `%r213` | p2 | `t\|4` |
with `%r5 = 8*ex` (s15), `%r6 = ey·8·ex` (s16, one image plane), `%r182 =
%r2 + 2·%tid.z` (s9185), `g = laneid>>2`, `t = laneid&3`. Each store block is
guarded by `p1`/`p2` = `(y<0)|(y≥ey)|(laneid>63)|(x<0)|(x≥ex)` (s12874–s12882,
s12916–s12924) and a guard failure stores `-1` as the index, which the following
`setp.lt.s32 %p, %idx, 0` + `bra` turns into "skip the store" (the pattern of
s12886–s12888). Note the index also has the guard *bit* added
(`add.s32 %r16394, %r196, %r197` at s12885 uses `%r196` — a predicate register
read as 0/1), which the `selp`/`bra` pair makes harmless.
**(c) shared staging, s13013–s13131.**
```
s13013 L32645: bar.sync 0
s13014 L32647: mov.u32 %r16412, %laneid
s13018 L32652: add.s32 %r16414, %r17741, %r16413 // %r17741 = 2*%tid.z, %r16413 = laneid>>5
s13022 L32656: shl.b32 %r16415, %r16414, 5
s13023 L32657: and.b32 %r16416, %r16412, 28
s13025 L32659: or.b32 %r218, %r217, %r16417
s13031 L32666: st.shared.u32 [%r16420], %r183
s13039 L32676: st.shared.u32 [%r16424], %r184 // index + 256
s13059 L32698: st.shared.u32 [%r16434], %r185 // group 2, base from (laneid>>2)+8
s13067 L32708: st.shared.u32 [%r16438], %r186
… +512, +768, +1024, +1280 variants for %r187…%r194 …
s13131 L32788: st.shared.u32 [%r16470], %r194
```
Twelve `st.shared.u32`, word index for the first six
`(2·%tid.z)·32 + (laneid & 28)` and `+256`, and for the last six
`((2·%tid.z)+((laneid>>2)+8)>>3)·32 + (((laneid>>2)+8)<<2 & 28)` and `+256`
(s13043–s13058, s13061–s13074). See §6 U3 for the address collision this
produces. A second `bar.sync 0` follows at s13136.
**(d) phase 37's A operand from shared, s13138–s13625.**
```
s13138 L32798: ld.param.v2.u32 {%r16472, %r16473}, [%rd489+-80] // param_0+0 = (ex, ey)
s13143 L32804: shr.u32 %r16475, %r16471, 2
s13146 L32807: and.b32 %r16478, %r16477, -64
s13148 L32809: and.b32 %r16480, %r16479, 24
s13150 L32811: or.b32 %r16482, %r16476, %r16481
s13151 L32812: shl.b32 %r16483, %r16482, 2
s13152 L32813: add.s32 %r16485, %r3216, %r16483
s13153 L32814: ld.shared.u32 %r235, [%r16485]
s13165 L32826: ld.shared.u32 %r236, [%r16490]
… 48 loads total, %r235…%r282 …
s13625 L33286: ld.shared.u32 %r282, [%r16812+144]
```
48 `ld.shared.u32` = 12 A quads (one `{a0,a2,a1,a3}`-ordered quad each). The
first word's index is
```
word = ((laneid<<2) & ~63) | ((laneid<<1) & 24) | ((laneid>>2)&3)
= 64·(laneid>>4) + 8·((laneid>>2)&1) + ((laneid>>2)&3)
byte = smem + 4·word
```
and the remaining 47 use the same base plus `+4, +8, +12, +16, +20` and a
divisor-by-24 decomposition of `(laneid&3)|4` / `|8` / `|12` … (`s13156
mul.wide.u16 %r16486, %rs4437, -21845` / `s13157 shr.u32 %r16487, %r16486, 20`
computes `⌊x/24⌋`, `s13159–s13160` the remainder, `s13161–s13163` select the
byte plane), with the whole block guarded by `setp.gt.u32 %p233, %r17795, 127`
(s13140) and by bounds checks against `(ex, ey)` at s13287–s13295.
**(e) phase 37's B, s13634–s13687.**
```
s13634 L33296: mul.lo.s32 %r17412, %r17795, 384 // %r17795 = %tid.z<<5
s13635 L33297: cvt.u64.u32 %rd433, %r17412
s13636 L33298: add.s64 %rd434, %rd2, %rd433
s13638 L33302: mul.wide.u32 %rd435, %r16825, 16
s13639 L33303: add.s64 %rd436, %rd434, %rd435
s13640 L33304: add.s64 %rd409, %rd436, 161280
s13641 L33306: ld.weak.global.ca.v4.u32 { %r16826,%r16827,%r16828,%r16829},[%rd409]
… 24 loads at 512 stride, last at +173056 …
s13687 L33398: ld.weak.global.ca.v4.u32 { %r16918,%r16919,%r16920,%r16921},[%rd432]
```
24 weight fragments at `W + 12288·%tid.z + 16·laneid + 161280 + 512·i`, `i =
0…23` = 12288 bytes = 48 B pairs = phase 37's B. The whole block is inside the
loop `$L__BB1_244` (s13633) which advances `%r17795` by 128 and branches back at
s13847–s13850 while `%r17795 < 128`; with `%r17795 = %tid.z<<5` this is a single
iteration for `%tid.z ≤ 3`.
**(f) phase 37's C, s13688–s13698.** 4 `ld.global.u32` at
`W + ((laneid*4)&12) + {210432, 210448, 210464, 210480}` → `%r16932, %r16942,
%r17172, %r17182`, each used as `{%rX, %rX}` — a per-column bias replicated over
the 16 rows, seeding the four chains of phase 37.
**Inputs:** phase 36's 24 D, `%r3216`, `W`, `(ex,ey)`. **Outputs:** the 12 arena
stores (side effect), `%r183…%r194`, phase 37's 12 A quads, 48 B pairs, 4 C
seeds. **Memory:** 12 global stores, 12 shared stores, 48 shared loads, 24
weight loads, 4 table loads, 2 barriers.
---
### E37 — s13747–s13870: packs + 4 stores to `param+56`
124 statements.
**(a) packs, s13747–s13756.** 8 `cvt` + 3 `mov.b32` from phase 37's chain-final
D registers → `%r287` (2 b32), `%rs4534/%rs4535`, `%rs4540/%rs4541`:
```
s13747 L33750: cvt.rn.satfinite.e4m3x2.f16x2 %rs4534, %r17143
s13748 L33753: cvt.rn.satfinite.e4m3x2.f16x2 %rs4535, %r17383
s13749 L33756: cvt.rn.satfinite.e4m3x2.f16x2 %rs4537, %r17393
s13750 L33759: cvt.rn.satfinite.e4m3x2.f16x2 %rs4536, %r17153
s13751 L33761: mov.b32 %r287, {%rs4536, %rs4537}
```
**(b) the four stores to `param+56` (`O`), s13757–s13845.**
```
s13763 L33783: shr.u32 %r17418, %r16473, 1 // ey>>1
s13764 L33784: shr.u32 %r17419, %r16472, 1 // ex>>1
s13765 L33785: shl.b32 %r17420, %r17419, 3 // 8*(ex>>1)
s13766 L33786: mul.lo.s32 %r17421, %r17418, %r17420
s13767 L33787: shr.u32 %r17422, %r17795, 5 // %tid.z (loop-carried)
s13768 L33788: mul.lo.s32 %r290, %r17421, %r17422
s13769 L33789: add.s32 %r17423, %r283, %r17416 // y = (%r2>>1) + (laneid>>4)
s13776 L33796: mad.lo.s32 %r17424, %r17420, %r17423, %r290
s13777 L33797: add.s32 %r17425, %r284, %r17417 // x = (%r1>>1) + ((laneid>>2)&3)
s13783 L33803: add.s32 %r291, %r17426, %r17424
s13784 L33804: or.b32 %r17427, %r17415, %r291 // + t
s13791 L33812: st.global.v2.u16 [%rd445], {%rs4534, %rs4535}
s13802 L33825: st.global.u32 [%rd448], %r287
s13836 L33861: st.global.u32 [%rd451], %r288
s13845 L33872: st.global.v2.u16 [%rd454], {%rs4540, %rs4541}
```
`%r283 = %r2>>1` (s13628), `%r284 = %r1>>1` (s13631), `%r17416 = laneid>>4`,
`%r17417 = (laneid>>2)&3`, `t = laneid&3`; the second pair recomputes
`y' = (%r2>>1) + (((laneid>>2)+8)>>2)`, `x' = (%r1>>1) + (((laneid>>2)+8)&3)`
(s13811–s13822) at the same base `%r290`. Extents are **halved** (`ex>>1`,
`ey>>1`) and the destination is `param+56`, not the plane arena. Guards are
`p6 = (y<0)|(y≥(ey>>1))|(laneid>63)|(y-constrained tid.z>127)|(x<0)|(x≥(ex>>1))`
(s13762–s13781), with the same `selp −1` + `bra` skip.
**(c) loop close and phase 38's operands, s13846–s13870.**
```
s13847 L33875: add.s32 %r299, %r17795, 128
s13848 L33876: setp.gt.u32 %p256, %r17795, -129
s13849 L33877: mov.u32 %r17795, %r299
s13850 L33878: @%p256 bra $L__BB1_244
s13852 L33881: mov.u32 %r17758, _ZZ…E4smem
s13858 L33889: add.s64 %rd455, %rd459, 210688
s13859 L33891: ld.weak.global.ca.v4.u32 { %r17443,%r17444,%r17445,%r17446},[%rd455]
s13861 L33895: ld.weak.global.ca.v4.u32 { %r17447,…},[%rd456] // +211200
s13863 L33899: ld.weak.global.ca.v4.u32 { %r17451,…},[%rd457] // +211712
s13869 L33908: ld.global.u32 %r17465, [%rd463+212224]
s13870 L33909: ld.global.u32 %r17475, [%rd463+212240]
```
Three weight fragments at `W + 16*laneid + {210688, 211200, 211712}` = phase
38's 6 B pairs, and 2 `ld.global.u32` at `W + ((laneid*4)&12) + {212224, 212240}`
= phase 38's C seeds (each used as `{%rX, %rX}`).
---
### E38 — s13877–s14199: the final epilogue
323 statements: 4 `st.shared.u32` (staging phase 38's D), 5 `ld.shared.u32` +
1 `ld.shared.v2.u16` (the softmax window), 1 real row max over 5 values, 5
`ex2.approx.ftz.f32` + 5 `div.approx.ftz.f32`… no — 9 `tex.base.2d.v4.f16.s32`,
3 `sust.b.2d.v4.b16.zero`, 4 `shfl.sync.down.b32`, 3 `ld.param.u64`, 1 `ret`.
**(a) stage phase 38's D for the softmax, s13877–s13907.**
```
s13877 L33952: bar.sync 0
s13878 L33954: mov.u32 %r17516, %laneid
s13882 L33959: add.s32 %r17521, %r304, %r17746 // g + 16*tid.z
s13883 L33960: and.b32 %r17522, %r17521, 1073741816 // & 0x40000008
s13884 L33961: or.b32 %r17523, %r17522, %r17518 // | (laneid>>2)&7
s13885 L33962: mad.lo.s32 %r17524, %r17523, 6, %r305 // *6 + t
s13887 L33964: add.s32 %r306, %r17758, %r17525 // *4 → byte address
s13888 L33965: st.shared.u32 [%r306], %r17496
s13892 L33970: st.shared.u32 [%r306+16], %r17506
s13905 L33984: st.shared.u32 [%r308], %r17497
s13907 L33987: st.shared.u32 [%r308+16], %r17507
```
Four words staged: the phase-38 chain-final pairs `{%r17496,%r17497}` and
`{%r17506,%r17507}`, at a 6-word row pitch (`*6`) plus `t`, in two banks 16 bytes
apart for the two rows `g` and `g+8`.
**(b) bounds gate, s13909–s13939.** `%r311 = %r17766 + (tid.x&7)` with
`%r17766 = 8*ctaid.x - rs126` (the x origin) and `%r312 = %r17762 +
(tid.x>>3)`; `p265 = (tid.z>1)|((%r312|%r311)<0)|(%r311≥ex)|(%r312≥ey)` (s13931–s13939)
skips the whole softmax/gather. Note `(tid.x + 32*tid.z)` is first reduced mod 8
into `%r309 = ... & -8` and `%r310 = ... >>3` (s13922–s13928).
**(c) the softmax window, s13940–s14038.**
```
s13946 L34028: ld.shared.u32 %r17554, [%r17703]
s13948 L34030: ld.shared.u32 %r17555, [%r17703+4]
s13950 L34032: ld.shared.u32 %r17558, [%r17703+8]
s13951 L34033: ld.shared.u32 %r17561, [%r17703+12]
s13952 L34034: ld.shared.v2.u16 {%rs4674, %rs4675}, [%r17703+20]
s13954 L34036: ld.shared.u32 %r17575, [%r17703+16]
s13957 L34040: cvt.f32.f16 %f865, %rs4542
s13958 L34043: mul.ftz.f32 %f893, %f865, 0fBFB8AA3B // -log2 e
s13959 L34044: ex2.approx.ftz.f32 %f894, %f893
s13960 L34045: add.ftz.f32 %f895, %f894, 0f3F800000
s13962 L34047: div.approx.ftz.f32 %f866, %f896, %f895 // %f896 = 1.0
s13964 L34053: max.f16x2 %r17553,%r17554,%r17555
s13965 L34057: max.f16x2 %r17556,%r17553,%r17558
s13966 L34061: max.f16x2 %r17559,%r17556,%r17561
s13968 L34066: max.f16 %rs4544,%rs4545,%rs4546
s13969 L34070: max.f16 %rs4547,%rs4544,%rs4549
s13970 L34073: mov.b32 %r17576, {%rs4547, %rs4547}
s13971 L34075: sub.f16x2 %r17562,%r17554,%r17576
s13974 L34083: mul.ftz.f32 %f897, %f867, 0f3FB8AA3B // +log2 e
s13975 L34084: ex2.approx.ftz.f32 %f869, %f897
```
**This epilogue does have a real row maximum.** `max.f16x2` twice and `max.f16`
twice (s13964–s13969) reduce the *low* halves of the five words
`%r17554, %r17555, %r17558, %r17561, %r17575` (the last through `%rs4549`) into
`%r17576`, which is broadcast to both halves and subtracted
(`s13971: sub.f16x2 %r17562,%r17554,%r17576`). Then a textbook f16 softmax:
`2^((x−max)·log2e)` per element through `ex2.approx.ftz.f32` (s13974–s14029),
the row sum accumulated in f32 (s13979, s13983, s13996, s14009, s14022, s14030),
inverted with `div.approx.ftz.f32 1.0/…` (s14031
`div.approx.ftz.f32 %f885, %f896, %f914`), and the five f16x2 registers scaled
(s14034–s14038 `mul.f16x2 %r17577…%r17589,%…,%r17591`).
**(d) the 3×3 texture gather, s14039–s14121.** The nine
`tex.base.2d.v4.f16.s32` (s14058, s14060, s14077, s14079, s14087, s14089, s14102,
s14104, s14117) sample the surface `param+88` (`%rd480`, s14056) at the nine
combinations of `(x−1, x, x+1)` × `(y−1, y, y+1)`:
```
s14044 L34234: setp.lt.s32 %p267, %r311, 1
s14045 L34235: selp.b32 %r17640, 1, %r17706, %p267 // xm
s14051 L34241: selp.b32 %r17609, 1, %r17709, %p269 // ym
s14055 L34245: selp.b32 %r17642, 1, %r17710, %p271 // xp
s14058 L34249: tex.base.2d.v4.f16.s32 {%rs4569,%rs4570,%rs4571,%rs4572}, [%rd464, {%r17640,%r17609}]
```
`%rd464…%rd480` are all `mov.u64` copies of `%rd480` (s14057, s14059, …). The
sampled values are combined with the five softmax weights by `fma.rn.f16x2`
(s14062, s14064, s14066, s14081, s14083, s14085, s14091, s14093, s14095, s14106,
s14109, s14112) and the 2×2 accumulator halves folded with `add.f16` (s14114,
s14115, s14116), then one more shared value `%rs4610` folded with `fma.rn.f16`
(s14119–s14121).
**(e) sigmoid, difference, scale, cross-lane sum, s14122–s14179.**
```
s14122 L34385: cvt.f32.f16 %f886, %rs4674
s14123 L34388: mul.ftz.f32 %f915, %f886, 0fBFB8AA3B
s14125 L34390: add.ftz.f32 %f917, %f916, 0f3F800000
s14126 L34391: div.approx.ftz.f32 %f887, %f896, %f917 // sigmoid
s14134 L34409: mul.f16 %rs4630,%rs4543,%rs4614
s14137 L34421: sub.f16 %rs4645,%rs4622,%rs4636 // acc - sigmoid*acc
s14138 L34424: mov.f32 %f892, 0f3E800000 // 0.25
s14145 L34444: mul.f16x2 %r17658,%r17659,%r17660 // * 0.25
s14152 L34463: shfl.sync.down.b32 %r17662,%r17658,%r17683,%r17665,%r17693 // delta 1
s14153 L34467: add.f16x2 %r17667,%r17658,%r17662
s14158 L34478: shfl.sync.down.b32 %r17671,%r17667,%r17691,%r17674,%r17693 // delta 8
s14159 L34482: add.f16x2 %r17676,%r17667,%r17671
s14168 L34506: add.f16 %rs4657,%rs4651,%rs4656
s14177 L34530: add.f16 %rs4663,%rs4657,%rs4662
```
`sigmoid(v) = 1/(1 + 2^(−log2e·v))` on two more shared values
(`%rs4674/%rs4675`, the v2.u16 at `+20`), then three `acc − sigmoid·acc`
differences scaled by `0.25` (f16), then a two-step partial warp reduction:
`shfl.sync.down` delta 1 (`%r17683`, s13956) then delta 8 (`%r17691`, s13949),
each followed by an `add.f16x2`; the scalar path repeats the same two deltas with
`add.f16` (s14168, s14177). Segmask `%r17665`/`%r17674` is `(WARP_SZ<<8)−8192|31`
= 31 in both, membermask `%r17693 = −1`: a partial (not five-step) reduction.
**(f) the three surface writes, s14178–s14199.**
```
s14178 L34533: ld.param.u64 %rd484, [%rd491+120]
s14179 L34534: ld.param.u64 %rd487, [%rd491+128]
s14180 L34535: shl.b32 %r17697, %r311, 3
s14181 L34537: sust.b.2d.v4.b16.zero [%rd482, {%r17697,%r312}], {%rs4639,%rs4642,%rs4645,%rs4676}
s14182 L34540: sust.b.2d.v4.b16.zero [%rd484, {%r17697,%r312}], {%rs4630,%rs4633,%rs4636,%rs4677}
s14183 L34542: and.b32 %r17724, %r313, 1
s14185 L34544: mov.pred %p279, 0
s14186 L34545: xor.pred %p280, %p278, %p279
s14187 L34546: @%p280 bra $L__BB1_260
s14191 L34551: shl.b32 %r17729, %r17728, 2
s14192 L34552: and.b32 %r17725, %r17729, -8
s14197 L34558: sust.b.2d.v4.b16.zero [%rd487, {%r17725,%r17726}], {%rs4678,%rs4679,%rs4663,%rs4681}
s14199 L34562: ret
```
Three four-channel b16 surface writes to `param+112`, `param+120` and
`param+128`; the third is taken only when `(x|y)` is odd
(`and.b32 %r17724, %r313, 1` at s14183, `@%p280 bra`) and stores
`mov.u16 %rs4681, 0` (s14196) in its fourth channel. `%r17725 = (x<<2) & −8`,
`%r17726 = y>>1` for that one, versus the plain `(x<<3, y)` of the first two.
**Inputs:** the four staged phase-38 D words, `%rd480` (texture), `(ex,ey)`,
`%r1/%r2/%tid.z/%tid.x`, constants `0fBFB8AA3B`, `0f3FB8AA3B`, `0f3F800000`,
`0f3E800000`. **Outputs:** none (the kernel returns).
---
## 4. The plane arena (`param_0+48`) and the other `ld.param` buffers
The four `ld.param` that matter, quoted verbatim:
```
s4 L1032: add.s64 %rd1, %rd8, 80
s5 L1033: ld.param.v2.u16 {%rs126, %rs127}, [cuda_dldn_engine_swin_enc2_kernel_param_0+80]
s8 L1036: ld.param.u64 %rd2, [cuda_dldn_engine_swin_enc2_kernel_param_0+40]
s14 L1042: ld.param.v2.u32 {%r322, %r323}, [cuda_dldn_engine_swin_enc2_kernel_param_0]
s17 L1045: ld.param.u64 %rd10, [cuda_dldn_engine_swin_enc2_kernel_param_0+8]
s12865 L32471: ld.param.u64 %rd383, [%rd1+-32] // = param_0 + 48
s13632 L33293: ld.param.u64 %rd6, [%rd492+56] // = param_0 + 56
s13941 L34023: mov.b64 %rd491, cuda_dldn_engine_swin_enc2_kernel_param_0
s13953 L34035: ld.param.u64 %rd482, [%rd491+112]
s14056 L34246: ld.param.u64 %rd480, [%rd491+88]
s14178 L34533: ld.param.u64 %rd484, [%rd491+120]
s14179 L34534: ld.param.u64 %rd487, [%rd491+128]
```
| offset | role | read by | written by |
|---|---|---|---|
| 0 | `(ex, ey)` v2.u32 | s14 (`%r322/%r323`), s13138 (`%r16472/%r16473`) | — |
| 8 | **input image** `I` | prologue: 24 × `ld.global.v2.u16 [%rd12]` (s176, s328, … s3316) via `%rd4` | — |
| 40 | **weight image** `W` | every weight load, §1.1 | — |
| 48 | **plane arena** `S` | **never** | 12 × `st.global.u32` (s12891…s13009) |
| 56 | phase-37 output buffer `O` | **never** | 4 stores (s13791, s13802, s13836, s13845) |
| 80 | patch origins v2.u16 | s5 (`%rs126/%rs127`), reused at s13910–s13915 | — |
| 88 | input texture | 9 × `tex.base.2d.v4.f16.s32` (s14058…s14117) | — |
| 112, 120, 128 | output surfaces | — | 3 × `sust.b.2d.v4.b16.zero` (s14181, s14182, s14197) |
**Is anything generated into the plane arena?** Yes, exactly one thing:
E36(b) writes phase 36's requantised 16×96 output — 12 `st.global.u32`, 4 bytes ×
32 lanes × 12 = **1536 bytes per block** — into `S` at
`4·(8·ex·y + 8·x + d)`. Nothing in the entry ever *reads* `param_0+48`:
```
$ grep -n '%rd5\b\|%rd383' 0015-PREPASS_ENTRYPOINT_NAME.ptx
32471:ld.param.u64 %rd383, [%rd1+-32];
32472:cvta.to.global.u64 %rd5, %rd383;
32499:add.s64 %rd385, %rd5, %rd384;
… 11 more add.s64 %rd5, all feeding st.global.u32 …
```
`%rd5` appears only in the twelve `st.global.u32` (there is **no** `ld.*` with
`%rd5` as base) and `%rd383` only at s12865. So the arena write is a pure
side effect for the next launch; the same 12 registers are *also* consumed
inside this kernel via the shared staging of E36(c).
The one `surface-write`-style marker the brief attributes to a "phase 30
epilogue" (`surface-write:32@s25247`) has no counterpart here: s25247 does not
exist (the entry ends at s14199) and **E30 is a 60-statement load/pack epilogue
with no store of any kind** (§3/E30; verified by enumerating every `st.*` in the
entry — the only `st.global` are s12891–s13009 and s13791–s13845, and the only
`st.shared` are the prologue's six, E8's four, E36's twelve and E38's four).
That marker belongs to a different linearisation — see §6 U6.
## 5. Cross-lane reductions worth calling out
Introduction: the entry contains exactly **32** `shfl.sync.bfly.b32` and **4**
`shfl.sync.down.b32`; 8 of the former are in the prologue, 16 in E7, 4 in E12 and
4 in E38. Each butterfly uses the shared delta operands `%r3037 = 1` (s3318),
`%r3046 = 2` (s3611) and membermask `%r3048 = −1` (s3604), with a segmask built as
`((WARP_SZ<<8) − 8192) | 31` = 31.
1. **The prologue's RMS reduction** (s3605, s3612, s3621, s3627, s3637, s3643,
s3652, s3658): four butterfly pairs over lane bits 0 (`%r3037`) and 1
(`%r3046`), each followed by `add.f16x2` and a final `add.f16`
(`s3646 L5446: add.f16 %rs516,%rs517,%rs518`) — four row sums from the
prologue's 96 squared input values.
2. **E7's row sums** (s7223–s7344): 16 `shfl.sync.bfly.b32` = eight such pairs,
each followed by `add.f16x2` and a final `add.f16` of the two halves — 8 row
sums over 96 columns of the score window.
3. **E12's RMS reduction** (s9308–s9330): the same two butterfly steps
(`delta 1` at s9308, `delta 2` at s9314) over the four lanes with equal
`laneid>>2`, folding the 96 squares of one row; then `add.f16` of the two
column halves (s9317, s9332). This is the whole cross-lane traffic of the
norm.
4. **E36's and E38's `bar.sync` pairs** (s8910/s8968, s13013/s13136,
s13877/s13920): block-wide, guarding the shared tiles. The seventh
`bar.sync` is the prologue's, s4588.
5. **E38's partial lane sums** (s14152–s14177): four `shfl.sync.down.b32`, two
on the f16x2 path (`delta 1` = `%r17683`, `delta 8` = `%r17691`) and two on the
scalar path, segmask 31, membermask −1.
There is no `red.*` or `atom.*` anywhere in the entry, and `movmatrix` occurs only
in E7 (the 48 of §3/E7(f)).
## 6. Uncharacterised
**U1. The (n,k) indexing of the 512-byte B tiles of phases 13…35 and 37.**
The *geometry* of these phases is not in doubt: the chain fixes `m·k = |A|`,
`n·k = |B|`, `m·n = chains`, `k =` chain length, so phase 13 (and 15…35) is
`m=1, n=4, k=3` → M=16, N=32, K=96 and phase 37 is `m=1, n=4, k=12` → M=16,
N=32, K=384 (§2.2); every row then satisfies `mma = (M/16)(N/8)(K/32)`. What I
cannot derive is *which* (n-tile, k-step) each 512-byte tile holds. For phase 13
the 12 B pairs sit in six tiles at `W + 86592 + 512*i` (E12's six loads), and the
emitted chains pair them as chain 0 = tiles {0,2,4} at byte `+0`, chain 1 = tiles
{0,2,4} at byte `+8`, chain 2 = tiles {3,4,5} at `+0`, chain 3 = tiles {3,4,5} at
`+8` (mma s9820/s9822/s9824, s9821/s9823/s9825, s9826/s9828/s9830,
s9827/s9829/s9831). If a chain is one n-tile's three k-slices, its three tiles
would have to be the same tile — they are not; so either the weight image's tile
stride is not the `(n,k)`-major layout `rr_layer_spec.py` assumes
(`:189–192`, `:491–498`), or `m·n` counts something other than the chains. The
register/byte evidence above is exact and sufficient to reproduce the *operands*;
only their (n,k) naming is unresolved. *Missing:* the `_NAME_prep` permutation
that built the weight image, or a run of the kernel with a weight-image dump.
**U2. The identity of the 12288-byte score bias.** Phase 7 adds the f16 table
at `W + 6336 … W + 18624` as its mma C operand, one value per element of the
64×96 score, tile-major at 512 bytes per output tile (§3/E6(a)). Whether it is a
relative-position bias, a learned score bias, or something else cannot be decided
from the PTX: it is an opaque blob in a permuted weight image. *Missing:* the
weight image's layout description (the `_prep` permutation) or the parameter
names from the model file.
**U3. E36(c)'s shared staging produces 4-way write collisions.** The word index
is `(2·%tid.z)·32 + (laneid & 28)` for the first six stores and
`((2·%tid.z) + ((laneid>>2)+8)>>3)·32 + (((laneid>>2)+8)<<2 & 28)` for the last
six, plus `+256` for the alternating pair. `laneid & 28` takes only the eight
values 0,4,…,28, so lanes 0…3, 4…7, … all write the *same* word, with *different*
data (`%r183` vs `%r184` are the two halves of the same D pair, and `%r185` is
the other half of `%r183`'s source). Either the four colliding lanes are
guaranteed to hold equal data in this kernel's inputs (unlikely — they are
distinct e4m3 packs of distinct D registers) or the staging is racy and the
issued values come from whichever lane wins. I could not decide which from the
PTX. *Missing:* a run with a shared-memory dump, or the high-level source of the
phase-36→37 hand-off. (The corresponding *read* side, E36(d), is 48
`ld.shared.u32` with the swizzle of §3/E36(d) and is complete.)
**U4. E8's shared slot layout.** E8 stages four words at
`smem + 2048*%tid.z + 16*laneid + {0,512,1024,1536}` (s8911–s8967), but phases 9,
10, 11 read single quads at `smem + 16*laneid + {2048, 4096, 6144}` (s8974,
s9094, s9125) and phase 12 at `smem + %tid.z*512 + 16*laneid` (s8969–s8974 uses
`%tid.z*512` for phase 9's *other* read). For `%tid.z = 0` the written slots are
{0,512,1024,1536} while phase 9 reads 2048, phase 10 4096, phase 11 6144 —
disjoint. The union over `%tid.z ∈ {0,1,2,3}` of the writes is the 16 slots
{0…15}, which *does* contain 4, 8 and 12 (i.e. the reads 2048/4096/6144 are
slots 4/8/12). This is consistent only if `blockDim.z = 4` and the four z-planes
write the block's shared tile cooperatively; the module has **no `.maxntid`
declaration** so I cannot confirm the launch shape. *Missing:* the harness's
launch configuration (gridDim/blockDim), or whatever `.maxntid`/`.reqntid` the
unstripped cubin carries.
**U5. The `%tid.z` weight-slab strides are mutually inconsistent.**
Phases 1–7 index the weight image through `W + 21504*%tid.z + 16*laneid`
(s4589–s4590, s4613–s4615); phases 9–36 index it through `W + 16*laneid` with no
`%tid.z` term at all (s8976–s8978); phase 37 through `W + 12288*%tid.z +
16*laneid` (s13634–s13639); phase 38's bias again without a `%tid.z` term
(s13688–s13694). Since phase 9's very first weight offset (18624) is smaller
than the 21504-byte stride of phases 1–7, the two regions overlap for `%tid.z ≥ 1`
whatever the value of `%tid.z`. The addresses are as quoted and are sufficient
to reproduce each load; the *reason* they differ is not derivable from the PTX.
*Missing:* the launcher's `gridDim.z` and the weight-image builder. For
`%tid.z = 0` the touched byte range of the image is `[192, 212244)` (see below).
**Weight-image extent.** Relative to the pointer named in U5 (i.e. excluding any
`%tid.z` term and the `16*laneid` lane stride):
* the highest weight-fragment offset is `173056 + 16` (phase 37's last
`ld.weak.global.ca.v4.u32`, s13687, `add.s64 %rd432, %rd436, 173056`);
* the highest scalar-table offset is `212240 + 4` (phase 38's second C seed,
`ld.global.u32 [%rd463+212240]`, s13870), and `%rd463 = %rd3 +
((laneid*4)&12)` so the true last byte is `212240 + 12 + 4 = 212256`.
**The weight image therefore spans at least 212256 bytes**, and per block the
touched range is `[16*laneid + 192, 16*laneid + 212256)`. Per-`%tid.z` slabs add
`21504*%tid.z` (phases 1–7) and `12288*%tid.z` (phase 37) on top (U5).
**U6. The brief's stale landmarks.** Three statement indices given with this
ticket do not exist in this linearisation: `s25247` (the entry has 14199
statements), and the range markers "phase 30's epilogue has
`surface-write:32@s25247`". `s12891` (`surface-write:12`) and `s13791`
(`surface-write:4`) do match, and `s13959` / `s14058` match the reported
`softmax:12` and `texture-read:9`. So only the `s25247` landmark is foreign; it
is most likely from an enc0-era numbering. *Missing:* the numbering that
produced `s25247`, if it is meant to be in this layer.
**U7. The semantic names of the per-column tables.** `W + 0 … 192` (the
prologue's norm gain, 12 loads at `+0,16,…,176`: s4198–s4209), `W + 86208 … 86400`
(E8's residual add), `W + 86400 … 86592` (E12's norm gain), `W + 92800 … 92992`
(E13's residual add), and the four-word biases at `89664`, `96064`, `102272`, …,
`158144`, `210432`, `212224` are all read with the same
`W + ((laneid<<2)&12) + off` pattern and are 96 f16 or 32 f16 wide. Their *roles*
are computable from the arithmetic (gain in the two RMS norms, additive per-column
bias elsewhere) but their *names* are not. *Missing:* the weight-image layout or
the model's parameter names.
**U8. Phase 37's K = 384 against a 96-wide A.** The chain gives phase 37
`m=1, n=4, k=12` → M=16, N=32, K=384, and 48 mma (verified: 4 chains of 12, each
step a distinct A quad and a distinct B pair). But the A operand is 12 quads =
48 registers read from a shared tile whose source (E36(c)) stages only 12 words
per lane, and E36(a) packs only 12 of phase 36's 24 D registers — i.e. one of the
twelve 16×8 n-tiles of phase 36's output is staged per staged word. The
mechanical relation between the 12 staged words, the 48 A registers, and a
384-deep k axis is not determined without the swizzle's intent. *Missing:* the
high-level structure of the phase-36→37 merge, or a shared-memory dump.
**U9. The residual operand added into phase 9's C.** E8(d) adds a per-column
table (at `W+86208`) to 48 f16 values that are the halves of the prologue's
quantised-input registers `%r2798…%r2845`. The mechanics are unambiguous (the
defining `mov.b32 {%rs1100, %rs1103}, %r2798` at s3366 has no successor
anywhere in the entry, and `%r2798` is `cvt.rn.f16x2.e4m3x2 %r2798, %rs128` of
the input element loaded at s176). What is *not* derivable from the PTX is
whether this really is a semantic skip connection from the block input (which
would require the input patch's per-lane layout to coincide with an mma C
operand), or whether the input patch registers happen to alias a value the
compiler could have recomputed from phase 8's D. *Missing:* the high-level
source, or a numeric run showing whether phase 9's output equals
`pack(D8)·W9 + table + input`.
## 7. Quick acceptance index
| requirement | where |
|---|---|
| phase table for all 38 phases, M/16·N/8·K/32 == mma checked, mismatches named | §2.2: the identity holds on **all 38** once the tool's `M = 16·\|A\|`, `N = 8·\|B\|` are divided by `k = K/32`; the flagged rows 8, 13…35, 37, 38 are re-derived there (the tool's `K` column is right, its `M`,`N` and `full`/`band` label wrong) |
| weight image extent | §6 U5 (212256 bytes, per-block) |
| phases that read no weight operand | §2.2 and §3/E6(b), E7(f): phases 7 and 8 — phase 7's A and B operands both come from E6's packs of phase 5's D, with A frag 0 **bit-identical** to B frag 0 (s4853 vs s4925) and the later ones the same data with the two halves swapped (s4865 vs s4937); phase 8's A is E7's probability packs (s8720 ff.) and its B is E7's `movmatrix` transposes of phase 6's D (s8598 ff.) |
| every epilogue named | §2.1 (38 rows), §3 (38 `###` sections) |
| the norms: mean-subtracting LN or RMS? | §3/E12: raw sum of squares, only `2⁻¹³` added, no mean and no `1/N`; prologue (s3812 ff.) identical structure → **both are RMS norms**, with a per-column gain and the bias deferred to the next GEMM's C |
| attention: does the score have a row max? | §3/E7(b),(c): **no** — all 96 `max.f16x2` are the clamp lower bound `−0.55615234375`, all 96 `min.f16x2` the upper; the only warp shuffles are the 16 `shfl.sync.bfly` row sums |
| attention: the score's bias operand | §3/E6(a): the mma C operand, 48 distinct pairs from the 12288-byte f16 table at `W+6336`, tile-major `512*(4*(n>>1)+m)`, one value per score element; identity → §6 U2 |
| activations | §3/E13(a), E15, E17…E33: `out = x·(0.5 + y·(0.412109375 − 0.0810546875·|y|))`, `y = clamp(x,±2)` — the **same clamped cubic as enc0's E13**, byte-identical constants |
| patch merge / surface writes | §3/E36(b) (12 stores to `param+48`), E37(b) (4 stores to `param+56`), E38(f) (3 `sust` to `param+112/+120/+128`) |
| final texture-reading epilogue | §3/E38: 4 staged words, real 5-value row max, softmax, 9 `tex.2d`, 3×3 `fma` gather, sigmoid, 0.25 scale, two `shfl.sync.down` steps |
| per-launch table into the plane arena | §4: exactly one — E36's 1536 bytes per block; `param+48` is written and never read |
| cross-lane reductions | §5 |
| uncharacterised | §6 U1–U9 |