File size: 1,554 Bytes
99509b7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// A float -> int8 quantize has no answer for NaN/Inf. Before the guard, an Inf made the |max|
// scale Infinity and every value quantized to 0 ([0.5, Inf, 3] -> [0, 0, 0]), and a NaN was
// skipped by the |max| scan and then stored as 0 by the Int8Array -- training continued on
// zeros with no error. Every quantizer must now refuse, and finite inputs must be unchanged.
"use strict";
const V = require("./public/verified_core.js");

let fails = 0;
function ck(name, cond) { console.log((cond ? "  ok    " : "  FAIL  ") + name); if (!cond) fails++; }
function throwsNonFinite(fn) { try { fn(); return false; } catch (e) { return e.name === "NonFiniteError"; } }

const bad = [Float32Array.from([0.5, Infinity, 3, -1]), Float32Array.from([0.5, NaN, 3, -1]),
             Float32Array.from([-Infinity, 1, 2, 3])];
for (const X of bad) {
  const tag = Array.from(X).join(",");
  ck("quantize refuses [" + tag + "]", throwsNonFinite(() => V.quantize(X)));
  ck("quantizeRows refuses [" + tag + "]", throwsNonFinite(() => V.quantizeRows(X, 2, 2)));
  ck("quantizeCols refuses [" + tag + "]", throwsNonFinite(() => V.quantizeCols(X, 2, 2)));
  ck("rowAbsMax refuses [" + tag + "]", throwsNonFinite(() => V.rowAbsMax(X, 2, 2)));
}
const q = V.quantize(Float32Array.from([0.5, -1, 3]));
ck("finite input quantizes as before: [21, -42, 127]", Array.from(q.q).join() === "21,-42,127");

if (fails) { console.log("NONFINITE TEST FAILED: " + fails); process.exit(1); }
console.log("NONFINITE TEST PASSED — every quantizer refuses NaN/Inf instead of zeroing.");