Quazim0t0 commited on
Commit
62c9296
·
verified ·
1 Parent(s): db5fafd

Upload web/test_ieee.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. web/test_ieee.js +121 -0
web/test_ieee.js CHANGED
@@ -78,6 +78,39 @@ function mulF32Spec(a, b) {
78
  // what WGSL `f32(s) * a * b` means: left-associative, rounded after every step
79
  const epiSpec = (s, a, b) => mulF32Spec(mulF32Spec(i32ToF32Spec(s), a), b);
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  // ---- checks -----------------------------------------------------------------
82
  let pass = true;
83
  const ok = (c, msg) => { console.log(`${c ? " ok " : " FAIL"} ${msg}`); if (!c) pass = false; };
@@ -123,6 +156,94 @@ const asF32 = (x) => { f32buf[0] = x; return f32buf[0]; };
123
  ok(bad === 0, `mulF32Spec matches the correctly-rounded product on ${n} draws (subnormal..overflow)`);
124
  }
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  // ---- the actual point: is Verified.epi the spec, or just agreeable? ---------
127
  console.log("\nVerified.epi vs the oracle, over the range the kernels produce:");
128
  let mism = 0, n = 0;
 
78
  // what WGSL `f32(s) * a * b` means: left-associative, rounded after every step
79
  const epiSpec = (s, a, b) => mulF32Spec(mulF32Spec(i32ToF32Spec(s), a), b);
80
 
81
+ // ADDITION, same discipline: exact BigInt sum of the two scaled significands,
82
+ // one rounding. An exact zero sum from nonzero operands is +0 under RNE;
83
+ // -0 + -0 keeps its -0 (IEEE 754-2019 §6.3).
84
+ function addF32Spec(a, b) {
85
+ if (a === 0 && b === 0) return (signbit(a) && signbit(b)) ? -0 : 0;
86
+ if (a === 0) return b;
87
+ if (b === 0) return a;
88
+ const A = decomposeF32(a), B = decomposeF32(b);
89
+ const e0 = Math.min(A.exp2, B.exp2);
90
+ const T = (A.neg ? -A.mant : A.mant) * (1n << BigInt(A.exp2 - e0))
91
+ + (B.neg ? -B.mant : B.mant) * (1n << BigInt(B.exp2 - e0));
92
+ if (T === 0n) return 0;
93
+ return roundToF32(T < 0n, T < 0n ? -T : T, e0);
94
+ }
95
+
96
+ // FUSED multiply-add: the product is NEVER rounded — exact BigInt product plus
97
+ // the exact addend, ONE rounding. This is what a hardware FMA computes, and
98
+ // (per neural-rdna2's fma golden, which this mirrors) the float64 shortcut
99
+ // fround(a*b + c) double-rounds on rare ties and is NOT a valid reference in
100
+ // general. Finite inputs only, like the rest of this oracle.
101
+ function fmaF32Spec(a, b, c) {
102
+ const spNeg = signbit(a) !== signbit(b);
103
+ let P = 0n, ep = 0;
104
+ if (a !== 0 && b !== 0) { const A = decomposeF32(a), B = decomposeF32(b); P = A.mant * B.mant; ep = A.exp2 + B.exp2; }
105
+ let Cm = 0n, ec = 0;
106
+ const scNeg = signbit(c);
107
+ if (c !== 0) { const C = decomposeF32(c); Cm = C.mant; ec = C.exp2; }
108
+ const e0 = Math.min(ep, ec);
109
+ const T = (spNeg ? -P : P) * (1n << BigInt(ep - e0)) + (scNeg ? -Cm : Cm) * (1n << BigInt(ec - e0));
110
+ if (T === 0n) return (spNeg && scNeg) ? -0 : 0; // exact zero: -0 only if both parts negative
111
+ return roundToF32(T < 0n, T < 0n ? -T : T, e0);
112
+ }
113
+
114
  // ---- checks -----------------------------------------------------------------
115
  let pass = true;
116
  const ok = (c, msg) => { console.log(`${c ? " ok " : " FAIL"} ${msg}`); if (!c) pass = false; };
 
156
  ok(bad === 0, `mulF32Spec matches the correctly-rounded product on ${n} draws (subnormal..overflow)`);
157
  }
158
 
159
+ // ---- addition: certify every fround(a+b) mirror step in the codebase --------
160
+ // fround(a+b) is correctly rounded for f32 operands because f64 has >= 2p+2
161
+ // bits of precision (53 >= 50, Figueroa's theorem) — double rounding is
162
+ // innocuous for ADD. That claim guards every per-add rounding schedule we
163
+ // ship, so it gets checked against the from-the-definition oracle, including
164
+ // operand pairs with exponent gaps far beyond 53 bits.
165
+ console.log("\naddF32Spec vs Math.fround(a+b), including extreme exponent gaps:");
166
+ {
167
+ let bad = 0, n = 0;
168
+ const mags = [1, 1e-3, 1e-8, 1e-20, 1e-38, 1e-42, 3e38, 1e30, 0.5, 127];
169
+ for (let t = 0; t < 300000; t++) {
170
+ const a = asF32((Math.random() * 2 - 1) * mags[(Math.random() * mags.length) | 0]);
171
+ const b = asF32((Math.random() * 2 - 1) * mags[(Math.random() * mags.length) | 0]);
172
+ n++;
173
+ if (!Object.is(addF32Spec(a, b), f32(a + b))) {
174
+ if (bad++ < 3) console.log(` ${a} + ${b} spec=${addF32Spec(a, b)} fround=${f32(a + b)}`);
175
+ }
176
+ }
177
+ ok(bad === 0, `addF32Spec matches fround(a+b) on ${n} draws — the per-add mirror schedule is the correctly-rounded sum`);
178
+ ok(Object.is(addF32Spec(-0, -0), -0) && Object.is(addF32Spec(asF32(1e-20), asF32(-1e-20)), 0),
179
+ "signed zero on sums: -0 + -0 = -0, exact cancellation = +0");
180
+ }
181
+
182
+ // ---- fused multiply-add ------------------------------------------------------
183
+ console.log("\nfmaF32Spec: single rounding, cross-checked against an independent oracle:");
184
+ {
185
+ // 1) fused must actually differ from the round-twice composition, or the
186
+ // oracle proves nothing (cancellation is where they part ways)
187
+ let differ = 0, n = 0;
188
+ for (let t = 0; t < 100000; t++) {
189
+ const a = asF32((Math.random() * 2 - 1) * 1e3);
190
+ const b = asF32((Math.random() * 2 - 1) * 1e3);
191
+ const c = asF32(-(a * b));
192
+ n++;
193
+ if (!Object.is(fmaF32Spec(a, b, c), f32(f32(a * b) + c))) differ++;
194
+ }
195
+ ok(differ > 0, `fused differs from round-twice on ${differ}/${n} cancellation cases (single rounding is real)`);
196
+
197
+ // 2) cross-oracle: vectors generated by neural-rdna2's golden_fma_scalar
198
+ // (verbatim, exact big-int, different codebase/author-time). Bit-for-bit
199
+ // agreement means neither oracle was tuned to the other.
200
+ let vecs = null;
201
+ try { vecs = JSON.parse(fs.readFileSync(path.join(__dirname, "test_vectors_fma.json"), "utf8")); } catch (e) {}
202
+ if (vecs) {
203
+ const buf = new ArrayBuffer(4), dv = new DataView(buf);
204
+ const fromBits = (u) => { dv.setUint32(0, u); return dv.getFloat32(0); };
205
+ const toBits = (x) => { dv.setFloat32(0, x); return dv.getUint32(0); };
206
+ let bad = 0;
207
+ for (const [ah, bh, ch, rh] of vecs.vectors) {
208
+ const r = fmaF32Spec(fromBits(parseInt(ah, 16)), fromBits(parseInt(bh, 16)), fromBits(parseInt(ch, 16)));
209
+ if (toBits(r) !== parseInt(rh, 16)) {
210
+ if (bad++ < 3) console.log(` ${ah},${bh},${ch}: js=${toBits(r).toString(16)} py=${rh}`);
211
+ }
212
+ }
213
+ ok(bad === 0, `agrees bit-for-bit with neural-rdna2's big-int fma golden on ${vecs.vectors.length} vectors (quantize-domain + cancellation + raw finite bits)`);
214
+ } else {
215
+ console.log(" note test_vectors_fma.json not present — cross-oracle check skipped");
216
+ }
217
+
218
+ // 3) the b2b immunity scan's fused emulation, validated: on the quantize
219
+ // domain (x >= 0, x*inv <= ~127.5, addend 0.5) the exact product spans
220
+ // <= 53 bits including the 0.5, so fround(x*inv + 0.5) IS the true fma
221
+ // there. That was an argument; this makes it a check.
222
+ let embad = 0, en = 0;
223
+ for (let t = 0; t < 300000; t++) {
224
+ const inv = asF32(0.25 + Math.random() * 500);
225
+ const x = asF32(Math.random() * 127.4 / inv);
226
+ en++;
227
+ if (!Object.is(f32(x * inv + 0.5), fmaF32Spec(x, inv, 0.5))) embad++;
228
+ }
229
+ ok(embad === 0, `on the quantize domain the f64 emulation equals the true fma (${en} draws) — test_b2b's immunity scan stands on a checked fact`);
230
+
231
+ // 4) and the immunity conclusion itself, re-run against the TRUE fma at the
232
+ // binade edges: raw last-ulp differences exist, none survives floor()
233
+ let raw = 0, fl = 0;
234
+ for (let k = 1; k <= 7; k++) {
235
+ const u = Math.pow(2, k - 23);
236
+ for (let t = 0; t < 150000; t++) {
237
+ const inv = asF32(0.25 + Math.random() * 500);
238
+ const x = asF32((Math.pow(2, k) - 0.5 + (Math.random() * 8 - 6) * u) / inv);
239
+ if (!(x >= 0)) continue;
240
+ const two = f32(f32(x * inv) + 0.5), fused = fmaF32Spec(x, inv, 0.5);
241
+ if (!Object.is(two, fused)) { raw++; if (Math.floor(two) !== Math.floor(fused)) fl++; }
242
+ }
243
+ }
244
+ ok(raw > 0 && fl === 0, `true-fma immunity: ${raw} last-ulp diffs at binade edges, ${fl} floor-visible`);
245
+ }
246
+
247
  // ---- the actual point: is Verified.epi the spec, or just agreeable? ---------
248
  console.log("\nVerified.epi vs the oracle, over the range the kernels produce:");
249
  let mism = 0, n = 0;