# Round 31 Track C Audit: `dq_f16` (`dense_mm.metal`) & `DW<F>` (`mma.metal`)

## 1. Summary & Scope
- **Owned files**:
  - `metal/kernels/dense_mm.metal` (`dq_f16` lines 28–66)
  - `metal/kernels/mma.metal` (`DW<T_IQ4_NL>`, `DW<T_IQ4_XS>` lines 26–69)
  - `metal/tests/dense_mm_parity.cpp` (`--dq-ab <base_dir> [type] [shape]` CLI support & uncontended pair filter)
- **Patch**: `/tmp/argon_r31_dq/argon_r31_dq.patch` (verified via `git -C vendor/strata apply --check`)
- **Parity**: 100% bitwise identical (`memcmp == 0`) across all 14 formats and all 13 shapes in `dense_mm_parity --dq-ab`, default `dense_mm_parity`, and `mma_parity`.

## 2. Key Findings & Shipped Optimizations

1. **DRAM Bandwidth Ceiling Diagnosis on Large Shapes (`2560x12288`, `2560x10240`, `2560x6144`, `6144x2560`)**:
   - On M5 (153.6 GB/s theoretical peak unified memory bandwidth), `dq_f16` on the large matrices already achieves **125–142 GB/s** (`81%–92%` of theoretical DRAM peak), dominated by writing the 62.9 MB (`2560x12288`) / 52.4 MB (`2560x10240`) FP16 output buffer `Wh`.

2. **Eliminating Divergent `constant`-Memory Table Init in `dq_f16<T_IQ4_XS / T_IQ4_NL>` (`dense_mm.metal`)**:
   - `load_tab<T_IQ4_NL>` previously executed a dynamic `for (int i = tid; i < 256; i += nth)` loop in every threadgroup (10,240+ threadgroups per matrix) with divergent `constant`-memory reads `kvalues_iq4nl[i & 15]` and `kvalues_iq4nl[i >> 4]`, which serialize across SIMD lanes on Apple GPUs.
   - Because `nth.x >= 64` for every `dq_f16` dispatch, threads `tid < 64` now populate all 256 `half2` entries of `tab` in 4 unrolled bank-conflict-free stores (`tab[tid + {0, 64, 128, 192}]`) directly from immediate register constants (`0xbfad9881u`, `0xf6eaddcfu`, `0x26190d01u`, `0x71594535u`), sharing the invariant low nibble `h0` across all 4 writes with zero `constant`-memory loads and zero loop overhead.

3. **Guarded `a.perm` & Inverse Row Mapping (`ro = gid.y`) for Sub-8-Bit Formats (`dense_mm.metal`)**:
   - Guarded the `a.perm` division/modulo inside `if (a.perm)` so `a.perm == 0` (~430 of 530 dispatches) executes zero integer divisions/modulos, and folded `k0 = 0` into `DW<F>::run(..., u, 0, w, p0, p1, tab)`.
   - For `a.perm != 0` (`320x10240p4`, 96 dispatches/chunk) on sub-8-bit formats (`fmt<F>::BB * 16 < fmt<F>::QK * 17`), inverted the bijection so output rows `ro = gid.y` are written contiguously in `Wh` and input row `r` is computed via shift/mask `(ro & 3u) * (a.n_out >> 2) + (ro >> 2)` when `a.perm == 4` (`1.03x–1.05x` speedup on `320x10240p4` for `IQ4_NL`, `Q4_0`, `Q5_0`, `Q5_1`).

4. **Decoupled Scale Load in `DW<T_IQ4_XS>` and `DW<T_IQ4_NL>` (`mma.metal`)**:
   - Unpacking the 32 `tab` values into `w[0..31]` before loading/applying the block scale `d` hides the device memory latency of the block scale header (`b[0..7]`) behind the threadgroup table lookups, matching the two-phase pattern of `DW<F>`.

## 3. Ablations Tested & Rejected (Not Shipped)
- **Dedicated `DW<T_Q8_0>` & `DW<T_IQ3_S>` fusing `* d` into the unpack loop**: Slightly regressed `6144x2560` (`0.98x`) compared to generic `DW<F>` + `deq<F>`, because `deq<F>` already unrolls fixed trip counts (`16` and `2`) while deferring `rdh(b)` until after the integer unpack loop.
- **`DW<T_Q2_0>` `0x6400` FP16 mantissa-OR trick & `rd32`**: Bitwise identical (`memcmp == 0`) once byte-masked (`q[g]`), but `0.99x` (`57.84 -> 58.15 ms`) vs `ushort` `p[0], p[1]` in `DW<T_Q2_0>` because `DW<T_Q2_0>` outputs `float w[16]` (requiring an extra `half`-to-`float` conversion per weight after the `half4` FMA).
- **`packed_uint4` / `uint* p` in `DW<T_IQ4_XS>`**: `0.99x` vs `ushort* p` because wider 32/128-bit loads delay the first `tab` lookup and increase live register pressure.
- **32x `simd_shuffle` nibble LUT in `DW<T_IQ4_XS / T_IQ4_NL>`**: `0.66x` on `2560x640` / `2560x512` (32 shuffles per thread vs 16 `half2` threadgroup loads).

## 4. Quiet-GPU Paired Benchmark Results (`dense_mm_parity --dq-ab`)
- `IQ4_XS`: `58.83 -> 58.56 ms` (`memcmp=0` on all shapes; `6144x2560` `1.01x`, `2560x640` `1.01x`, `2560x512` `1.01x`, `2560x48` `1.03x`, `10240x4` `1.07x`, `2560x1` `1.03x`)
- `IQ4_NL`: `64.70 -> 64.50 ms` (`memcmp=0` on all shapes; `320x10240p4` `44.9 -> 42.6 us` `1.05x`, `6144x2560` `1.01x`, `2560x640` `1.01x`, `640x2560` `1.01x`, `2560x512` `1.01x`, `2560x48` `1.05x`, `10240x4` `1.04x`, `2560x1` `1.06x`)
- `IQ3_S`: `57.02 -> 56.92 ms` (`memcmp=0` on all shapes; `2560x12288` `610.0 -> 606.7 us` `1.01x`, `2560x128` `1.07x`, `2560x48` `1.02x`)
- `320x10240p4` (`perm=4`): `Q4_0` `43.8 -> 42.4 us` (`1.03x`), `Q5_0` `46.2 -> 45.2 us` (`1.02x`), `Q5_1` `47.1 -> 46.5 us` (`1.01x`), `IQ4_NL` `44.9 -> 42.6 us` (`1.05x`), all `memcmp=0`.
