# Round 6 Track C Audit Report: Register-Cached `rv` in `gr_norm_h*` + 1-Simdgroup-Per-Head Barrier-Free `gdn_pre` & `gdn_post`

- **Agent:** `argon-gr-regs-and-gdn-post`
- **Device:** Apple M5 (10-core GPU, 24 GB unified memory)
- **Patch:** `/tmp/argon_r6_gr_gdn/argon_r6_gr_gdn.patch` (`git -C vendor/strata apply --check` clean)
- **Modified files (within owned boundaries):**
  - `metal/kernels/prompt.metal` (lines 171-319)
  - `metal/kernels/gdn_prompt.metal` (`gdn_pre` and `gdn_post`)
  - `metal/src/engine/window.cpp` (lines 3407 and 3412 only, inside 3402-3414 boundary)
  - `metal/tests/comb_fold_parity.cpp`
  - `metal/tests/gdn_prompt_parity.cpp`

---

## 1. Target 1: Register-Cached `rv` in `gr_norm_h`, `gr_norm_h4`, `gr_norm_h_moe`, `gr_norm_h_moec` (`metal/kernels/prompt.metal`)

### Design & Exact Arithmetic Preservation
- In `gr_norm_h` (`1` stream per threadgroup of `256` threads, `n = 2560 = 10 * 256`), Pass 1 now caches the updated residual stream values `rv[i] = v` (`float rv[10]`, `i = 0..9`) in registers and Pass 2 computes `o[d] = half(rv[i] * w[d] * rs)` directly from registers without re-reading `r[d]` from device memory.
- In `gr_norm_h4`, `gr_norm_h_moe`, and `gr_norm_h_moec` (`hc = 4` streams per threadgroup of `256` threads), Pass 1 caches `rv[c][i] = v` (`float rv[4][10]`) in registers and passes `rv` to `gr_norm_h_out`, which writes `o[d] = half(rv[c][i] * w[d] * rs)` directly from registers with zero device re-reads of `R` (`-83.89 MB` per call at `T=2048`, `-7.89 GB` across `96` calls at `T=1983`).

### Bitwise Parity & M5 GPU Benchmark (`comb_fold_parity` + `ple_moe_parity` + `prompt_parity`)
- **Bitwise Parity (`memcmp == 0`):** 100% PASS across `T in {1, 7, 64, 1024, 2048}` on both `R'` and `xnh` for `gr_norm_h_moec`, `gr_norm_h_moe`, `gr_norm_h4 (apply 0)`, and `gr_norm_h4 (apply 1)`.
- **M5 GPU Benchmark (`48` reps per command buffer, best of 3):**

| Kernel (`48` reps) | `T=1024` Baseline | `T=1024` Register `rv` | `T=1024` Delta | `T=2048` Baseline | `T=2048` Register `rv` | `T=2048` Delta |
|---|---:|---:|---:|---:|---:|---:|
| `gr_norm_h` (`apply 0`, `(hc, T)`) | 21.99 ms | 21.22 ms | **-0.77 ms (-3.5%)** | 45.45 ms | 44.07 ms | **-1.38 ms (-3.0%)** |
| `gr_norm_h4` (`apply 0`, `(1, T)`) | 24.84 ms | 23.38 ms | **-1.46 ms (-5.9%)** | 50.03 ms | 47.41 ms | **-2.62 ms (-5.2%)** |
| `gr_norm_h` (`apply 1`, `(hc, T)`) | 53.31 ms | 52.87 ms | **-0.44 ms (-0.8%)** | 108.05 ms | 107.60 ms | **-0.45 ms (-0.4%)** |
| `gr_norm_h4` (`apply 1`, `(1, T)`) | 44.05 ms | 43.52 ms | **-0.53 ms (-1.2%)** | 86.81 ms | 85.80 ms | **-1.01 ms (-1.2%)** |
| `gr_norm_h_moe` (`(1, T)`) | 47.92 ms | 47.71 ms | **-0.21 ms (-0.4%)** | 94.99 ms | 94.32 ms | **-0.67 ms (-0.7%)** |
| `gr_norm_h_moec` (`(1, T)`) | 83.74 ms | 83.53 ms | **-0.21 ms (-0.3%)** | 166.16 ms | 165.36 ms | **-0.80 ms (-0.5%)** |

*(Note: In standalone microbenchmarks where a single threadgroup's `40 KB` slice of `R[t]` remains hot in L1/SLC between Pass 1 and Pass 2, the savings reflect eliminated load instructions + L1/SLC traffic; in full-window execution with concurrent dispatches and cache pressure, eliminating the second `R` read avoids SLC eviction re-reads from DRAM.)*

---

## 2. Target 2: 1-Simdgroup-Per-Head Barrier-Free `gdn_pre` & `gdn_post` (`metal/kernels/gdn_prompt.metal` + `window.cpp`)

### Design & Exact Arithmetic Preservation
1. **Barrier-Free 1-Simdgroup-Per-Head `gdn_post` (`grid = (12, T)`, `128` threads = `4` heads/TG):**
   - Each simdgroup (`32` lanes) handles one head `h = int(tg.x) * 4 + int(sg)` (with automatic fallback to `h = sg == 0 ? int(tg.x) : hv` when launched with legacy `grid.x == 48`).
   - Lane `lane` (`0..31`) loads `ov0 = o[base]`, `ov1 = o[base + 32]`, `ov2 = o[base + 64]`, `ov3 = o[base + 96]` and computes:
     `p0 = simd_sum(ov0 * ov0)`, `p1 = simd_sum(ov1 * ov1)`, `p2 = simd_sum(ov2 * ov2)`, `p3 = simd_sum(ov3 * ov3)`,
     `tot = (p0 + p1) + (p2 + p3)`.
   - Because each `simd_sum` reduces the exact same 32 elements (`0..31`, `32..63`, `64..95`, `96..127`) as the 4 simdgroups in the original kernel and sums them with identical `(p0 + p1) + (p2 + p3)` parenthesization, the result is **100% bitwise identical (`memcmp == 0`)** while using **0 bytes of threadgroup memory, 0 `threadgroup_barrier`s, and 4x fewer threadgroups (`24,576` vs `98,304` at `T=2048`)**.

2. **Barrier-Free 1-Simdgroup-Per-Head `gdn_pre` (`grid = (8, T)`, `256` threads = `8` heads/TG):**
   - When launched with `grid.x == (h_k + h_v) / 8 = 8` (`2` key-head threadgroups + `6` value-head threadgroups per token, vs `40` threadgroups in the legacy grid; legacy `grid.x == 40` is also supported):
     - For `x < h_k / 8` (`2` TGs = `16` simdgroups for `16` key heads): each simdgroup (`32` lanes) owns one key head `kh = x * 8 + sg` and computes both `cv_q[0..3]` and `cv_k[0..3]` (`4` channels per lane) in registers.
     - L2 norms `tot_q = (sq0 + sq1) + (sq2 + sq3)` and `tot_k = (sk0 + sk1) + (sk2 + sk3)` and the dot product `kq = (p[0] + p[1]) + (p[2] + p[3])` are reduced within the single simdgroup in the exact same floating-point association order as `part[0..3]` and `part[4..7]` in the original kernel.
     - For `x >= h_k / 8` (`6` TGs = `48` simdgroups for `48` value heads): each simdgroup (`32` lanes) owns one value head `h = (x - 2) * 8 + sg` (`4` channels per lane).
   - Eliminates `threadgroup float part[8]` and `threadgroup float prod[128]` (`544 B` threadgroup memory -> `0 B`), eliminates all **3 `threadgroup_barrier`s** (`3 -> 0`), and cuts threadgroups by **5x (`8 * T` vs `40 * T`)** while remaining **100% bitwise identical (`memcmp == 0`)** on all 6 outputs (`qn`, `kn`, `vc`, `gb`, `kq`, `hist_out`).

### Bitwise Parity & M5 GPU Benchmark (`gdn_prompt_parity`)
- **Bitwise Parity (`memcmp == 0`):** Verified 100% bitwise identical (`PASS`) between packed 1-simdgroup-per-head `(8, T)` / `(12, T)` and legacy `(40, T)` / `(48, T)` across `T in {1, 3, 37, 300}`, and all 28 `gdn_step` recurrence parity checks pass (`history exact`).
- **M5 GPU Benchmark (`T = 2048` and `T = 1024`):**

| Benchmark Metric (`T = 2048`) | Baseline (`40xT` / `48xT`, barriers) | Optimized (`8xT` / `12xT`, 0 barriers, 0 tgmem) | Delta |
|---|---:|---:|---:|
| `gdn_pre` (1 layer, `T=2048`) | 1.542 ms | **1.293 ms** | **-0.249 ms (-16.1%)** |
| `gdn_pre` (36 GDN layers, `T=2048`, `f32=0`) | 55.51 ms (53.63 ms @ `T=1983`) | **46.63 ms** (45.15 ms @ `T=1983`) | **-8.88 ms (-16.0%)** |
| `gdn_pre` (36 GDN layers, `T=1024`, `f32=0`) | 27.68 ms | **22.52 ms** | **-5.16 ms (-18.6%)** |
| `gdn_post` (36 GDN layers, `T=2048`, `f32=0`) | 34.65 ms (34.12 ms @ `T=1983`) | **33.71 ms** | **-0.94 ms (-2.7%)** |
| `gdn_post` (36 GDN layers, `T=1024`, `f32=0`) | 17.10 ms | **16.54 ms** | **-0.56 ms (-3.3%)** |
| Full `gdn_pre + gdn_scanr_4 + gdn_post` (1 layer, `T=2048`, `f32=1`) | 9.828 ms | **9.565 ms** | **-0.263 ms (-2.7%)** |
| Full `gdn_pre + gdn_scanr_4 + gdn_post` (36 layers, `T=2048`, `f32=1`) | 353.81 ms | **344.34 ms** | **-9.47 ms (-2.7%)** |
