Commit 6d11d06
committed
fix(v4-path-d): zero-init kkt_solve output buffer -> Path D NaN gone (0 NaN, 0 deadlock)
The Path D NaN (cells with chunks/seq>=3 or multi-head, only when mx.eval(FLA-naive ref) runs before
Path D) was NOT the sync hazard the handoff doc claimed -- every device-event/commit attempt
deadlocked because they solved a non-problem. Real root cause: kkt_solve writes only the
lower-triangular (T_chunk x T_chunk) region of its per-chunk output `a`; the strictly-upper lanes keep
whatever mx.empty allocates. Right after the ref eval MLX frees the reference's NaN-containing fp32
intermediates and mx.empty RECYCLES that freed NaN memory into `a`; downstream chunk GEMMs read the
full matrix (0*NaN=NaN) -> pipeline poison. Without the ref-eval the recycled memory is clean -> the
timing dependence.
Fix: mx.empty -> mx.zeros for `a` (one line). No device event / no command-buffer commit -> no
deadlock. tilelang-side changes reverted (fix entirely in cppmega).
M4 sequential harness (mx.eval(ref) before Path D): 8/8 launched, 5/8 parity-ok, 0 NaN, 0 deadlock,
completes cleanly. 3 originally-NaN cells now finite (varlen_64_32 fully parity-green); remaining
t128/mh mismatch is deterministic fp16 chunk-GEMM precision (separate, not the NaN). No Path C
regression (mamba3 path_c 89, sparse_mla_fp8+#6 65, metal-sync 12). RULE #1: single correct path.1 parent 29c112d commit 6d11d06
1 file changed
Lines changed: 12 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2416 | 2416 | | |
2417 | 2417 | | |
2418 | 2418 | | |
2419 | | - | |
| 2419 | + | |
| 2420 | + | |
| 2421 | + | |
| 2422 | + | |
| 2423 | + | |
| 2424 | + | |
| 2425 | + | |
| 2426 | + | |
| 2427 | + | |
| 2428 | + | |
| 2429 | + | |
| 2430 | + | |
2420 | 2431 | | |
2421 | 2432 | | |
2422 | 2433 | | |
| |||
0 commit comments