Upload web/test_gates.js with huggingface_hub
Browse files- web/test_gates.js +24 -2
web/test_gates.js
CHANGED
|
@@ -32,7 +32,9 @@ function inputs(d) {
|
|
| 32 |
return { Xq, Wq, rs, cs };
|
| 33 |
}
|
| 34 |
|
| 35 |
-
// exact gate: int32 accumulator with !==, then f32 epilogue
|
|
|
|
|
|
|
| 36 |
function gateExact(kernel, shapes) {
|
| 37 |
for (const d of shapes) {
|
| 38 |
const { Xq, Wq, rs, cs } = inputs(d);
|
|
@@ -41,7 +43,7 @@ function gateExact(kernel, shapes) {
|
|
| 41 |
for (let i = 0; i < accRef.length; i++) if (accHw[i] !== accRef[i]) return `acc @${i}`;
|
| 42 |
const hw = kernel(Xq, Wq, rs, cs, d, L);
|
| 43 |
const ref = V.bgemmJS(Xq, Wq, rs, cs, d, L);
|
| 44 |
-
for (let i = 0; i < ref.length; i++) if (hw[i]
|
| 45 |
}
|
| 46 |
return null;
|
| 47 |
}
|
|
@@ -113,6 +115,26 @@ ok(oldMissedRounding && newCatchesRounding,
|
|
| 113 |
const oldMissedStride = gateOld(mutant("batchStride")) === null;
|
| 114 |
console.log(` note batchStride under the old gate: ${oldMissedStride ? "MISSED" : "caught (batch>1 was in the shape)"}`);
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
console.log(pass ? "\nGATE TEST PASSED — the gate rejects real bugs and accepts the real kernel."
|
| 117 |
: "\nGATE TEST FAILED");
|
| 118 |
process.exit(pass ? 0 : 1);
|
|
|
|
| 32 |
return { Xq, Wq, rs, cs };
|
| 33 |
}
|
| 34 |
|
| 35 |
+
// exact gate: int32 accumulator with !==, then f32 epilogue compared AT THE
|
| 36 |
+
// BIT LEVEL (V.bitDiff) — `!==` can't see -0 vs +0, and the fleet's replica
|
| 37 |
+
// checks hash raw bytes, so the gate must compare what the hash sees.
|
| 38 |
function gateExact(kernel, shapes) {
|
| 39 |
for (const d of shapes) {
|
| 40 |
const { Xq, Wq, rs, cs } = inputs(d);
|
|
|
|
| 43 |
for (let i = 0; i < accRef.length; i++) if (accHw[i] !== accRef[i]) return `acc @${i}`;
|
| 44 |
const hw = kernel(Xq, Wq, rs, cs, d, L);
|
| 45 |
const ref = V.bgemmJS(Xq, Wq, rs, cs, d, L);
|
| 46 |
+
for (let i = 0; i < ref.length; i++) if (V.bitDiff(hw[i], ref[i])) return `epilogue @${i}`;
|
| 47 |
}
|
| 48 |
return null;
|
| 49 |
}
|
|
|
|
| 115 |
const oldMissedStride = gateOld(mutant("batchStride")) === null;
|
| 116 |
console.log(` note batchStride under the old gate: ${oldMissedStride ? "MISSED" : "caught (batch>1 was in the shape)"}`);
|
| 117 |
|
| 118 |
+
// ---- the sign of zero -------------------------------------------------------
|
| 119 |
+
// Real ISAs have non-IEEE modes that flush -0 to +0 (RDNA2 output modifiers /
|
| 120 |
+
// DX9-legacy multiplies). JS `!==` treats -0 === 0, so a value-level gate is
|
| 121 |
+
// BLIND to that flush — yet the sync guard hashes raw bits, so it would fork
|
| 122 |
+
// the fleet. The audit must therefore compare bit patterns.
|
| 123 |
+
console.log("\nthe audit must see the sign of zero (`!==` cannot):");
|
| 124 |
+
{
|
| 125 |
+
const d = { m: 2, k: 4, n: 2 };
|
| 126 |
+
const Xq = new Int8Array(d.m * d.k); // all zero -> acc = 0 -> epi = +0
|
| 127 |
+
const Wq = rnd(d.k * d.n, () => (Math.random() * 256 - 128) | 0);
|
| 128 |
+
const rs = Float32Array.from({ length: d.m }, () => Math.random() + 0.5);
|
| 129 |
+
const cs = Float32Array.from({ length: d.n }, () => Math.random() + 0.5);
|
| 130 |
+
const got = V.bgemmJS(Xq, Wq, rs, cs, { ...d, batch: 1 }, L);
|
| 131 |
+
ok(got.every((v) => !V.bitDiff(v, 0)), "sanity: the units produce +0 here");
|
| 132 |
+
got[1] = -0; // what a -0-flushing device's INVERSE would look like; either direction diverges the hash
|
| 133 |
+
ok(got.every((v) => v === 0), "sanity: `!==` cannot tell the corrupted output apart");
|
| 134 |
+
const bad = V.auditTile(Xq, Wq, rs, cs, d, got, L, 400); // 400 samples over 4 cells: hits the bad cell w.p. 1-(3/4)^400
|
| 135 |
+
ok(bad !== null, `auditTile flags the -0 (${bad || "NOT CAUGHT"})`);
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
console.log(pass ? "\nGATE TEST PASSED — the gate rejects real bugs and accepts the real kernel."
|
| 139 |
: "\nGATE TEST FAILED");
|
| 140 |
process.exit(pass ? 0 : 1);
|