Upload web/TEST_RESULTS.md with huggingface_hub
Browse files- web/TEST_RESULTS.md +26 -1
web/TEST_RESULTS.md
CHANGED
|
@@ -9,7 +9,7 @@ against the verified units at init.
|
|
| 9 |
| `test_core.js` | float trainer converges, replicas bit-identical | PASS β loss 33.71 β 0.000000, replica diff 0.000e+0 |
|
| 10 |
| `test_verified.js` | training THROUGH the int8 units converges, replicas bit-identical | PASS β loss 300.6 β 1.41, replica diff 0.000e+0 |
|
| 11 |
| `test_ieee.js` | the JS epilogue mirror is IEEE-754 spec-correct, not merely agreeable | PASS β 500k+ checks, 0 disagreements; rejects the old round-once mirror on 34% of inputs |
|
| 12 |
-
| `test_gates.js` | the exact kernel gate rejects real bugs, accepts the real kernel | PASS β 5/5 injected bugs rejected, clean kernel accepted |
|
| 13 |
| `test_metamorphic.js` | correctness properties that need no reference implementation | PASS β 6/6 properties hold; catches stride/swap/acc= mutants |
|
| 14 |
| `test_corpus.js` | mutation-scores the oracles with an external bug taxonomy | PASS β properties 2/4 (2/2 loop, 0/2 math), differential 4/4, control clean |
|
| 15 |
| `test_optimizer.js` | DaisyAdam beats SGD through the units, deterministic replicas | PASS β 1.59 vs 1.95, replica diff 0.000e+0 |
|
|
@@ -151,6 +151,31 @@ the GPU chain matches the new-spec mirror exactly and differs from the
|
|
| 151 |
old-spec composition. Two-device live run: step 141/300 with identical loss
|
| 152 |
(6.23958) on both replicas, per-step weight-hash divergence checks silent.
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
One bug was caught during the rework, by the bit-identity check itself: the
|
| 155 |
fused q+k+v sum initially ran in f64 and rounded once, where the old code
|
| 156 |
rounded to f32 after each add β a last-ulp fork that would have split
|
|
|
|
| 9 |
| `test_core.js` | float trainer converges, replicas bit-identical | PASS β loss 33.71 β 0.000000, replica diff 0.000e+0 |
|
| 10 |
| `test_verified.js` | training THROUGH the int8 units converges, replicas bit-identical | PASS β loss 300.6 β 1.41, replica diff 0.000e+0 |
|
| 11 |
| `test_ieee.js` | the JS epilogue mirror is IEEE-754 spec-correct, not merely agreeable | PASS β 500k+ checks, 0 disagreements; rejects the old round-once mirror on 34% of inputs |
|
| 12 |
+
| `test_gates.js` | the exact kernel gate rejects real bugs, accepts the real kernel | PASS β 5/5 injected bugs rejected, clean kernel accepted, audit sees the sign of zero |
|
| 13 |
| `test_metamorphic.js` | correctness properties that need no reference implementation | PASS β 6/6 properties hold; catches stride/swap/acc= mutants |
|
| 14 |
| `test_corpus.js` | mutation-scores the oracles with an external bug taxonomy | PASS β properties 2/4 (2/2 loop, 0/2 math), differential 4/4, control clean |
|
| 15 |
| `test_optimizer.js` | DaisyAdam beats SGD through the units, deterministic replicas | PASS β 1.59 vs 1.95, replica diff 0.000e+0 |
|
|
|
|
| 151 |
old-spec composition. Two-device live run: step 141/300 with identical loss
|
| 152 |
(6.23958) on both replicas, per-step weight-hash divergence checks silent.
|
| 153 |
|
| 154 |
+
## The sign of zero (RDNA2 ISA audit)
|
| 155 |
+
|
| 156 |
+
Reading the RDNA2 shader ISA against our determinism assumptions confirmed
|
| 157 |
+
three of them on real hardware and exposed one blind spot in our own gates:
|
| 158 |
+
|
| 159 |
+
- `V_DOT4_I32_I8` is an exact packed int8 dot with int32 accumulate β the
|
| 160 |
+
DP4A path's exactness is an ISA guarantee, not a tested coincidence.
|
| 161 |
+
- f32 add/multiply are 0.5 ULP (correctly rounded) β the epilogue mirror's
|
| 162 |
+
foundation. `V_RCP_F32` is 1 ULP β division stays off the GPU, as designed.
|
| 163 |
+
- Rounding mode and denorm flushing are **runtime MODE-register state**
|
| 164 |
+
(`S_ROUND_MODE` / `S_DENORM_MODE`, per wave, driver-controlled) β which is
|
| 165 |
+
why the exact gates re-run on every device at every init rather than
|
| 166 |
+
trusting a device model. (Denorm flush is additionally unreachable in the
|
| 167 |
+
shipped math: the 1e-8 scale floor keeps every epilogue product β₯ ~1e-16 in
|
| 168 |
+
magnitude, far above the ~1.2e-38 subnormal threshold.)
|
| 169 |
+
- The blind spot: RDNA2 has non-IEEE instruction variants a compiler may pick
|
| 170 |
+
β output modifiers and DX9-legacy multiplies that **flush β0 to +0**. Our
|
| 171 |
+
gates compared f32 outputs with JS `!==`, for which `-0 !== 0` is *false*:
|
| 172 |
+
a β0-flushing kernel would pass every gate, then fork the fleet at the sync
|
| 173 |
+
guard, which hashes raw bits. All gate and audit comparisons now compare
|
| 174 |
+
**bit patterns** (`bitDiff`), i.e. exactly what the replica hash sees.
|
| 175 |
+
`test_gates.js` proves the fix non-vacuously: a `-0` planted where the units
|
| 176 |
+
produce `+0` is invisible to `!==` (sanity-checked in the test) and flagged
|
| 177 |
+
by the repaired `auditTile`.
|
| 178 |
+
|
| 179 |
One bug was caught during the rework, by the bit-identity check itself: the
|
| 180 |
fused q+k+v sum initially ran in f64 and rounded once, where the old code
|
| 181 |
rounded to f32 after each add β a last-ulp fork that would have split
|