# Round 35 Track C: MTP Draft Kernels (`mtp.metal` / `mtp_chain.metal`) & `router.metal` Optimization Report

- **Agent**: `argon-r35-mtp-and-router-opt` (`gemini-4-argon`)
- **Patch**: `/tmp/argon_r35_mtp/argon_r35_mtp.patch` (verified clean with `git -C vendor/strata apply --check`)
- **Owned files**:
  - `metal/src/engine/msl/mtp.metal`
  - `metal/src/engine/msl/mtp_chain.metal`
  - `metal/kernels/router.metal`
  - `metal/tests/route_parity.cpp`

---

## 1. Summary of Changes & Root Causes

### A. `metal/src/engine/msl/mtp.metal` (`mtp_rms_xprep`, `mtp_combine_gnorm`, `mtp_xprep`)
1. **`mtp_rms_xprep`**:
   - **Pre-offset + unrolled reduction (`a.n == 2560` and `a.n == 10240`)**: Pre-offset `xrp = xr + tid` and specialized the two MTP widths (`2560` for `mtp.pre_fc_norm_embedding.weight`, 10 steps of 256; `10240` for `mtp.pre_fc_norm_hidden.weight`, 40 steps of 256) with `#pragma clang loop unroll(full)` so all loads use constant immediate offsets `[256 * i]`.
   - **Prepared-output loop specialization & division elimination**:
     - For `a.n == 2560 && a.xp_n == 2560`, `a.n / 16 == 160 < 256`, so each thread `tid < 160` executes at most 1 iteration (`if (tid < 160)`), eliminating the loop back-edge and all three runtime integer divisions (`a.n / a.xp_n`, `i / per`, `i % per`).
     - For `a.n == 10240 && a.xp_n == 2560`, `per == 160` and `a.n / a.xp_n == 4` are compile-time constants (`q = i / 160u, k = i - q * 160u`), replacing expensive 32-bit runtime `udiv`/`urem` sequences on AGX with a single constant magic-multiply.
2. **`mtp_combine_gnorm`**:
   - Pre-offset `rp = r + tid`, `o += tid`, and `w += tid` in the `n == 2560` fast path so all 40 unrolled loads/stores (`hp`, `ep`, `rp`, `w`, `o`) use constant immediate offsets `[256 * i]`.
3. **`mtp_xprep`**:
   - Specialized `per == 160u ? gid / 160u : gid / per` and `i = gid - t * per` to avoid runtime integer division/modulo for `n == 2560`.

### B. `metal/src/engine/msl/mtp_chain.metal` (`mtp_embed`, `mtp_slop_pen`, `mtp_pick`)
1. **`mtp_embed<F>` (-15.8% to -31.6% across all 13 GGUF formats)**:
   - Previously, `mtp_embed<F>` called `X<F>::load(posv, posv, u, ps, xsum)` on every unit to read 16 or 32 `float` indices from global buffer `posv` (`0.0f .. 2559.0f`), computed unused `xsum[0..1]`, converted `int(ps[j])` back to `int`, and performed 16 or 32 dynamic-index scalar scatter stores `y[pos] = ...` plus runtime-indexed `kind_scale<F>(pos)`.
   - Because unit base offset `p0` (and `p1` for `UNIT == 32`) is always a multiple of 16 (`16 * u`, `32 * u`, or the K-quant block/subblock formula), `(p0 + j) & 7 == j & 7`, `(p0 + j) & 3 == j & 3`, and `(p0 + j) & 1 == j & 1`.
   - Replaced `X<F>::load(posv, ...)` and scalar scatter stores with direct analytical unit offset `p0`/`p1`, compile-time constant `kind_scale<F>(j)`, and coalesced `float4` stores to `y + p0` (and `y + p1`), plus `if (U <= 256) { if (int(tid) < U) ... }` loop elimination for `n == 2560`.
2. **`mtp_slop_pen` (-31.0% to -96.7%)**:
   - **Fast-exit when `a.j == 0 && !any_knob` (`mode=0`)**: Immediately writes `state[0] = a.state` on `tid == 0` and returns without barriers or table scans (`24.90 us -> 0.81 us`, **-96.7%**).
   - **Parallel token classification (`kNewline` / `kBlank`)**: Both `slop4::kNewline` (200 tokens) and `slop4::kBlank` (222 tokens) fit within the 256-thread threadgroup (`tid < 200`, `tid < 222`), replacing 6 serial 422-element constant-memory linear scans on `tid == 0` with a single parallel compare across the threadgroup.
   - **Zero `thread` stack frame (`mtp_slop_penalties`)**: Emits penalties directly into `threadgroup int ids[80]` and `threadgroup float vals[80]` using file-scope `constant int32_t` tables and `#pragma clang loop unroll(full)` instead of allocating `slop4::Pen pen[80]` (640B) + 20 local arrays on the per-thread DRAM stack.
   - **Parallel `inverse[]` lookup & `lg[ids[tid]]` hold/removed evaluation**: Replaced serial `tid == 0` global memory loops over `inverse[pen[i].id]` and `lg[ids[i]]` with parallel evaluation across `tid < count`.

### C. `metal/kernels/router.metal` & `metal/tests/route_parity.cpp`
1. **`route_body` in `router.metal` (-0.2% to -2.1%)**:
   - Unrolled the per-rank argmax and butterfly reduction loops and replaced `if ((ex & 31) == lane) v[ex / 32] = -INFINITY;` (dynamic register-array indexing that forced `v[16]` to spill to stack memory) with `#pragma clang loop unroll(full) for (int i = 0; i < 16; ++i) v[i] = (ex == lane + 32 * i) ? -INFINITY : v[i];` so `v[0..15]` remains in scalar registers while keeping the initial threadgroup barrier that synchronizes `X<F>::load` across simdgroups.
2. **`route_parity.cpp`**:
   - Added `--mtp-ab BASE_MTP_METAL` for paired bitwise parity and timing of `mtp_rms_xprep` (`n=2560` and `n=10240`), `mtp_combine_gnorm`, and `mtp_xprep`, and aligned buffer placement during paired timing in `--router-ab`.

---

## 2. Quiet-GPU Benchmarks & Bitwise Parity Verification (Apple M5)

### A. `route_parity --mtp-ab` (`mtp.metal`)
| Kernel | Shape | Baseline (us) | Candidate (us) | Ratio | Delta | Parity |
|---|---|---:|---:|---:|---:|---|
| `mtp_rms_xprep` | `n=2560, nt=1` | 2.895 | 2.223 | 0.7676 | **-23.24%** | BITWISE PASS |
| `mtp_rms_xprep` | `n=2560, nt=4` | 2.932 | 2.338 | 0.7945 | **-20.55%** | BITWISE PASS |
| `mtp_rms_xprep` | `n=2560, nt=8` | 2.959 | 2.370 | 0.7981 | **-20.19%** | BITWISE PASS |
| `mtp_rms_xprep` | `n=10240, nt=1` | 7.893 | 5.060 | 0.6390 | **-36.10%** | BITWISE PASS |
| `mtp_rms_xprep` | `n=10240, nt=4` | 8.352 | 5.626 | 0.6745 | **-32.55%** | BITWISE PASS |
| `mtp_rms_xprep` | `n=10240, nt=8` | 8.398 | 5.801 | 0.6879 | **-31.21%** | BITWISE PASS |
| `mtp_combine_gnorm` | `hc=4, nt=1` | 2.901 | 2.888 | 0.9962 | **-0.38%** | BITWISE PASS |
| `mtp_combine_gnorm` | `hc=4, nt=4` | 3.097 | 3.067 | 0.9896 | **-1.04%** | BITWISE PASS |
| `mtp_combine_gnorm` | `hc=4, nt=8` | 3.804 | 3.798 | 0.9995 | **-0.05%** | BITWISE PASS |
| `mtp_xprep` | `rows=8, n=2560` | 2.154 | 2.133 | 0.9899 | **-1.01%** | BITWISE PASS |

In `comb_fold_parity 0 mtp bench` (cold 16-copy DRAM walk of the full hidden branch `mtp_rms_xprep` + `fc_hidden` GEMV + `mtp_combine_gnorm`):
- All `n = 1..8` pass `ALL PASS`.
- Cold batched hidden branch time improved from `94.1 us -> 65.5 us` (`n=1`), `102.0 us -> 96.3 us` (`n=2`), `156.3 us -> 150.7 us` (`n=3`), `190.4 us -> 184.9 us` (`n=4`), `366.6 us -> 361.2 us` (`n=8`).

### B. `sample_parity --mtp` (`mtp_chain.metal`)
| Kernel | Config | Baseline (us) | Candidate (us) | Ratio | Delta | Parity |
|---|---|---:|---:|---:|---:|---|
| `mtp_pick` | `nv=40525` | 3.501 | 3.508 | 0.9820 | **-1.80%** | BITWISE PASS |
| `mtp_pick` | `nv=248320` | 15.084 | 15.092 | 0.9996 | **-0.04%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=40525, mode=0` | 24.895 | 0.876 | 0.0351 | **-96.49%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=40525, mode=1` | 34.803 | 10.254 | 0.2944 | **-70.56%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=40525, mode=2` | 41.072 | 14.822 | 0.3607 | **-63.93%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=248320, mode=0` | 24.904 | 0.814 | 0.0327 | **-96.73%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=248320, mode=1` | 57.137 | 31.043 | 0.5435 | **-45.65%** | BITWISE PASS |
| `mtp_slop_pen` | `nv=248320, mode=2` | 87.128 | 60.116 | 0.6903 | **-30.97%** | BITWISE PASS |
| `mtp_embed` | `format=30 (BF16)` | 1.618 | 1.112 | 0.6842 | **-31.58%** | BITWISE PASS |
| `mtp_embed` | `format=8 (Q8_0)` | 1.616 | 1.169 | 0.7225 | **-27.75%** | BITWISE PASS |
| `mtp_embed` | `format=2 (Q4_0)` | 1.592 | 1.177 | 0.7409 | **-25.91%** | BITWISE PASS |
| `mtp_embed` | `format=6 (Q5_0)` | 1.614 | 1.264 | 0.7822 | **-21.78%** | BITWISE PASS |
| `mtp_embed` | `format=20 (IQ4_NL)` | 1.714 | 1.289 | 0.7530 | **-24.70%** | BITWISE PASS |
| `mtp_embed` | `format=23 (IQ4_XS)` | 1.599 | 1.300 | 0.8144 | **-18.56%** | BITWISE PASS |
| `mtp_embed` | `format=42 (Q2_0)` | 1.639 | 1.182 | 0.7229 | **-27.71%** | BITWISE PASS |
| `mtp_embed` | `format=21 (IQ3_S)` | 1.730 | 1.451 | 0.8361 | **-16.39%** | BITWISE PASS |
| `mtp_embed` | `format=11 (Q3_K)` | 1.971 | 1.437 | 0.7294 | **-27.06%** | BITWISE PASS |
| `mtp_embed` | `format=12 (Q4_K)` | 1.923 | 1.440 | 0.7505 | **-24.95%** | BITWISE PASS |
| `mtp_embed` | `format=13 (Q5_K)` | 1.941 | 1.529 | 0.7855 | **-21.45%** | BITWISE PASS |
| `mtp_embed` | `format=14 (Q6_K)` | 1.719 | 1.346 | 0.7830 | **-21.70%** | BITWISE PASS |
| `mtp_embed` | `format=18 (IQ3_XXS)` | 1.622 | 1.366 | 0.8423 | **-15.77%** | BITWISE PASS |

### C. `route_parity --router-ab` (`router.metal`)
- `type=30 (BF16)`: `nt=1..8, split=0/1` all `PASS` with median ratios `0.9874 .. 0.9977` (**-0.2% to -1.3%**).
- `type=8 (Q8_0)`: `nt=1..8, split=0/1` all `PASS` with median ratios `0.9787 .. 0.9981` (**-0.2% to -2.1%**).
- Standalone `route_parity` (400 windows, K=512 + K=256 MoCE) and `prompt_parity`: `ALL PASS`.
