Upload web/test_gates.js with huggingface_hub
Browse files- web/test_gates.js +46 -0
web/test_gates.js
CHANGED
|
@@ -135,6 +135,52 @@ console.log("\nthe audit must see the sign of zero (`!==` cannot):");
|
|
| 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);
|
|
|
|
| 135 |
ok(bad !== null, `auditTile flags the -0 (${bad || "NOT CAUGHT"})`);
|
| 136 |
}
|
| 137 |
|
| 138 |
+
// ---- the audit's sampling strategy ------------------------------------------
|
| 139 |
+
// A bounds-guard off-by-one or a pack-tail padding bug corrupts the LAST
|
| 140 |
+
// row/column only. At the live logits shape (n = 16512) that is 1 cell in
|
| 141 |
+
// 16512, so uniformly random sampling essentially never lands on it. The audit
|
| 142 |
+
// now spends its first cells on the structural danger points deliberately.
|
| 143 |
+
// This measures both strategies against that named bug class.
|
| 144 |
+
console.log("\nthe audit must catch a LAST-COLUMN bug (uniform sampling cannot):");
|
| 145 |
+
{
|
| 146 |
+
const d = { m: 64, k: 16, n: 512 }; // n wide, like the real unembed
|
| 147 |
+
const Xq = rnd(d.m * d.k, () => (Math.random() * 256 - 128) | 0);
|
| 148 |
+
const Wq = rnd(d.k * d.n, () => (Math.random() * 256 - 128) | 0);
|
| 149 |
+
const rs = Float32Array.from({ length: d.m }, () => Math.random() + 0.5);
|
| 150 |
+
const cs = Float32Array.from({ length: d.n }, () => Math.random() + 0.5);
|
| 151 |
+
const good = V.bgemmJS(Xq, Wq, rs, cs, { ...d, batch: 1 }, L);
|
| 152 |
+
|
| 153 |
+
const corrupt = () => { // last column only
|
| 154 |
+
const g = Float32Array.from(good);
|
| 155 |
+
for (let i = 0; i < d.m; i++) g[i * d.n + (d.n - 1)] = 0;
|
| 156 |
+
return g;
|
| 157 |
+
};
|
| 158 |
+
// the OLD strategy: every cell uniform-random
|
| 159 |
+
const uniformAudit = (got, nCells) => {
|
| 160 |
+
for (let t = 0; t < nCells; t++) {
|
| 161 |
+
const i = (Math.random() * d.m) | 0, j = (Math.random() * d.n) | 0;
|
| 162 |
+
let acc = 0;
|
| 163 |
+
for (let p = 0; p < d.k; p++) acc += mul[(Xq[i * d.k + p] & 0xFF) * 256 + (Wq[p * d.n + j] & 0xFF)];
|
| 164 |
+
if (V.bitDiff(got[i * d.n + j], V.epi(acc, rs[i], cs[j]))) return true;
|
| 165 |
+
}
|
| 166 |
+
return false;
|
| 167 |
+
};
|
| 168 |
+
const TRIALS = 300;
|
| 169 |
+
let uniHits = 0, stratHits = 0;
|
| 170 |
+
for (let t = 0; t < TRIALS; t++) {
|
| 171 |
+
if (uniformAudit(corrupt(), 12)) uniHits++;
|
| 172 |
+
if (V.auditTile(Xq, Wq, rs, cs, d, corrupt(), L, 12) !== null) stratHits++;
|
| 173 |
+
}
|
| 174 |
+
console.log(` uniform 12 cells : caught ${uniHits}/${TRIALS} audits (expected ~${(100*(1-Math.pow(1-1/d.n,12))).toFixed(1)}%)`);
|
| 175 |
+
console.log(` stratified 12 : caught ${stratHits}/${TRIALS} audits`);
|
| 176 |
+
ok(stratHits === TRIALS, "stratified sampling catches the last-column bug on EVERY audit");
|
| 177 |
+
ok(uniHits < TRIALS * 0.25, "uniform sampling misses it almost always — the strategy, not the cell count, is what changed");
|
| 178 |
+
// and it must not cry wolf on a clean kernel
|
| 179 |
+
let fp = 0;
|
| 180 |
+
for (let t = 0; t < TRIALS; t++) if (V.auditTile(Xq, Wq, rs, cs, d, good, L, 12) !== null) fp++;
|
| 181 |
+
ok(fp === 0, `no false positives on the clean kernel (${TRIALS} audits)`);
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
console.log(pass ? "\nGATE TEST PASSED — the gate rejects real bugs and accepts the real kernel."
|
| 185 |
: "\nGATE TEST FAILED");
|
| 186 |
process.exit(pass ? 0 : 1);
|