Quazim0t0 commited on
Commit
ba06800
Β·
verified Β·
1 Parent(s): 28a864a

Upload web/test_selfcorpus.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. web/test_selfcorpus.js +164 -0
web/test_selfcorpus.js ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Mutation-scoring the oracles against MY OWN bugs β€” July 2026.
2
+ //
3
+ // test_corpus.js scores the checks against someone else's bug taxonomy. That
4
+ // answers "how do my oracles do on kernel bugs an outsider wrote down". This
5
+ // file asks the harder question: this month produced four real bugs with
6
+ // names and fixes. What does the corpus of MY OWN bugs score?
7
+ //
8
+ // strippedBinding a layout:auto pipeline silently dropped the unused scale
9
+ // bindings, so the verify variant bound the wrong buffers.
10
+ // Modeled as: the kernel ignores the column scales.
11
+ // roundOnce the fused q+k+v sum ran in f64 and rounded once where the
12
+ // old code rounded to f32 after each add β€” a last-ulp spec
13
+ // fork that would split replicas.
14
+ // deadGate a gate whose pass was vacuous (tolerance compare, or no
15
+ // discriminating input) β€” a checker bug, not a kernel bug.
16
+ // rosterStall a gradient reached the leader but not one follower; the
17
+ // sync guard held SAFETY (no fork) but LIVENESS died β€” a
18
+ // live fleet parked for hours. A protocol bug: every
19
+ // computed value everywhere was correct.
20
+ //
21
+ // The instruments scored:
22
+ // properties the reference-free suite (relations + definitional anchors)
23
+ // differential the exact bit-level differential gate
24
+ // metaTest mutation-testing the GATES themselves (test_gates.js's job)
25
+ // liveness a protocol simulation: deliver gradients asymmetrically and
26
+ // require the run to finish with identical weights
27
+ const fs = require("fs");
28
+ const path = require("path");
29
+ const V = require("./public/verified_core.js");
30
+ const C = require("./test_corpus.js"); // propertySuite, differentialGate, quantize
31
+ const L = { mul: new Int16Array(fs.readFileSync(path.join(__dirname, "public", "mul_lut.bin")).buffer.slice(0)) };
32
+ const f32 = Math.fround;
33
+
34
+ let pass = true;
35
+ const ok = (c, msg) => { console.log(`${c ? " ok " : " FAIL"} ${msg}`); if (!c) pass = false; };
36
+
37
+ // ---- bug 1: strippedBinding (kernel ignores the column scales) --------------
38
+ // The real bug bound the wrong buffer; the observable effect is a kernel whose
39
+ // per-column scale is not the one the mirror used β€” a per-column scalar error.
40
+ function kStripped(Xq, Wq, rs, cs, d) {
41
+ return V.bgemmJS(Xq, Wq, rs, new Float32Array(cs.length).fill(1), d, L);
42
+ }
43
+ // ---- bug 2: roundOnce (epilogue analogue: one rounding instead of the chain) -
44
+ // The real bug was in a fused backward sum; its species is "right value, wrong
45
+ // rounding schedule". Injected here in the epilogue where the oracles look.
46
+ function kRoundOnce(Xq, Wq, rs, cs, d) {
47
+ const o = V.bgemmJS(Xq, Wq, rs, cs, { ...d, acc: true }, L);
48
+ if (d.acc) return o;
49
+ const { m, n } = d, batch = d.batch || 1, relu = !!d.relu;
50
+ const out = new Float32Array(o.length);
51
+ for (let bz = 0; bz < batch; bz++)
52
+ for (let i = 0; i < m; i++)
53
+ for (let j = 0; j < n; j++) {
54
+ let v = f32(o[(bz * m + i) * n + j] * rs[bz * m + i] * cs[bz * n + j]); // f64 chain, ONE rounding
55
+ if (relu && v < 0) v = 0;
56
+ out[(bz * m + i) * n + j] = v;
57
+ }
58
+ return out;
59
+ }
60
+
61
+ console.log("\nMy own July-2026 bugs, scored against every instrument I have.\n");
62
+ console.log("bug lives in properties differential metaTest liveness");
63
+ console.log("------------------------------------------------------------------------------");
64
+
65
+ // data-plane bugs: properties vs differential
66
+ {
67
+ const p1 = C.propertySuite(kStripped), d1 = C.differentialGate(kStripped);
68
+ console.log(`strippedBinding data/scale ${(p1 ? "CAUGHT" : "MISSED").padEnd(12)} ${(d1 ? "CAUGHT" : "MISSED").padEnd(14)} - -`);
69
+ // the theorem, again: ignoring cs is a per-column scalar β€” invisible to every
70
+ // relation AND to the unit-scale anchor (which pins cs=1, exactly what the
71
+ // bug substitutes). If a future property catches it, this assertion should
72
+ // be UPDATED, not deleted β€” it documents where the blindness boundary is.
73
+ ok(p1 === null, "properties are blind to strippedBinding (per-column scalar: the c*out theorem)");
74
+ ok(d1 !== null, `differential catches strippedBinding (${d1})`);
75
+
76
+ const p2 = C.propertySuite(kRoundOnce), d2 = C.differentialGate(kRoundOnce);
77
+ console.log(`roundOnce data/round ${(p2 ? "CAUGHT" : "MISSED").padEnd(12)} ${(d2 ? "CAUGHT" : "MISSED").padEnd(14)} - -`);
78
+ ok(p2 === null, "properties are blind to roundOnce (last-ulp; the anchor sits at rs=cs=1 where both schedules agree)");
79
+ ok(d2 !== null, `differential catches roundOnce (${d2})`);
80
+ }
81
+
82
+ // ---- bug 3: deadGate β€” a CHECKER bug; only a meta-test can see it -----------
83
+ // gateLive is the shipped exact gate; gateDead is the old tolerance gate. The
84
+ // meta-test feeds a known-bad kernel to a gate and demands rejection: a gate
85
+ // that accepts a known bug is dead, whatever it accepts elsewhere.
86
+ {
87
+ const randf = (n) => Float32Array.from({ length: n }, () => Math.random() * 2 - 1);
88
+ const mkGate = (exact) => (K) => {
89
+ for (const d of [{ m: 7, k: 33, n: 6, batch: 2, relu: true }, { m: 5, k: 9, n: 4, batch: 1, relu: false }]) {
90
+ const A = randf(d.batch * d.m * d.k), B = randf(d.batch * d.k * d.n);
91
+ const q = C.quantize(A, B, d);
92
+ const hw = K(q.x.q, q.wq, q.x.s, q.ws, d);
93
+ const ref = V.bgemmJS(q.x.q, q.wq, q.x.s, q.ws, d, L);
94
+ for (let i = 0; i < ref.length; i++) {
95
+ if (exact ? V.bitDiff(hw[i], ref[i]) : Math.abs(hw[i] - ref[i]) > Math.abs(ref[i]) * 1e-6 + 1e-6)
96
+ return "mismatch";
97
+ }
98
+ }
99
+ return null;
100
+ };
101
+ const gateLive = mkGate(true), gateDead = mkGate(false);
102
+ const metaTest = (gate) => gate(kRoundOnce) !== null; // must reject a known bug
103
+ const deadCaught = !metaTest(gateDead), liveOk = metaTest(gateLive);
104
+ console.log(`deadGate checker ${"-".padEnd(12)} ${"-".padEnd(14)} ${deadCaught ? "CAUGHT" : "MISSED"} -`);
105
+ ok(deadCaught, "metaTest catches the dead gate (tolerance gate waves the roundOnce bug through)");
106
+ ok(liveOk, "metaTest passes the live gate (exact gate rejects the same bug)");
107
+ }
108
+
109
+ // ---- bug 4: rosterStall β€” a PROTOCOL bug; only a liveness test can see it ----
110
+ // Three peers, deterministic per-step gradients, and a bus that delivers peer
111
+ // C's step-1 gradient to the leader but NOT to follower B (the production
112
+ // incident's exact shape). Every computed value on every peer is correct, so
113
+ // no data oracle can fire. The old protocol (wait, then halt) loses liveness;
114
+ // the repair protocol (ask the leader, who retains 8 steps) finishes the run
115
+ // with identical weights everywhere.
116
+ {
117
+ const STEPS = 5, PEERS = ["L", "B", "C"];
118
+ const gradOf = (peer, step) => (peer.charCodeAt(0) * 31 + step * 7) % 100; // deterministic
119
+ function run(repair) {
120
+ const weights = { L: 0, B: 0, C: 0 };
121
+ const retained = new Map(); // leader's grad store
122
+ for (let s = 0; s < STEPS; s++) {
123
+ const inbox = {};
124
+ for (const p of PEERS) inbox[p] = { [p]: gradOf(p, s) };
125
+ for (const from of PEERS)
126
+ for (const to of PEERS) {
127
+ if (from === to) continue;
128
+ if (s === 1 && from === "C" && to === "B") continue; // the asymmetric drop
129
+ inbox[to][from] = gradOf(from, s);
130
+ }
131
+ for (const p of PEERS) retained.set(`${s}:${p}`, gradOf(p, s)); // leader retains
132
+ for (const p of PEERS) {
133
+ const missing = PEERS.filter((q) => !(q in inbox[p]));
134
+ for (const q of missing) {
135
+ if (!repair) return { halted: `${p} missing ${q}@${s}` }; // old: guard stops
136
+ inbox[p][q] = retained.get(`${s}:${q}`); // new: leader repairs, bit-exact
137
+ }
138
+ // strict roster order, like the real averaging
139
+ weights[p] += PEERS.reduce((a, q) => a + inbox[p][q], 0) / PEERS.length;
140
+ }
141
+ }
142
+ return { weights };
143
+ }
144
+ const oldP = run(false), newP = run(true);
145
+ const identical = newP.weights && newP.weights.L === newP.weights.B && newP.weights.B === newP.weights.C;
146
+ console.log(`rosterStall protocol ${"-".padEnd(12)} ${"-".padEnd(14)} - ${oldP.halted && identical ? "CAUGHT" : "MISSED"}`);
147
+ ok(!!oldP.halted, `liveness test catches the old protocol (halts: ${oldP.halted})`);
148
+ ok(identical, "repair protocol finishes the run with identical weights on all three peers");
149
+ }
150
+
151
+ console.log(`
152
+ scoreboard, my own bugs:
153
+ properties 0/2 (of the data-plane bugs they could address β€” the c*out theorem, both times)
154
+ differential 2/2 (of the data-plane bugs)
155
+ metaTest 1/1 (the checker bug β€” only mutation-testing the gate sees it)
156
+ liveness 1/1 (the protocol bug β€” no data oracle can fire when every value is correct)
157
+
158
+ Half of this month's bugs did not live in the kernels at all. The instruments
159
+ that caught them are not better oracles β€” they are DIFFERENT instruments:
160
+ tests of the checkers, and tests of the protocol. Union: 4/4, but only
161
+ because the population defines the instrument, not the other way round.`);
162
+
163
+ console.log(pass ? "\nSELF-CORPUS TEST PASSED" : "\nSELF-CORPUS TEST FAILED");
164
+ process.exit(pass ? 0 : 1);