|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| const assert = require("assert");
|
| const Wire = require("./public/wire.js");
|
| const Shard = require("./public/shard.js");
|
|
|
| const SPEC = { family: "llama", layers: 6, hidden: 64, heads: 4, kvHeads: 2, vocab: 128 };
|
| const PLAN = [{ id: "p1", index: 0, lo: 0, hi: 2, head: true },
|
| { id: "p7", index: 1, lo: 2, hi: 4, head: false },
|
| { id: "p3", index: 2, lo: 4, hi: 6, head: false }];
|
| function assign(over) { return Object.assign({ repo: "owner/model", revision: "main", spec: SPEC, plan: PLAN, mine: 1, fingerprint: 123 }, over || {}); }
|
|
|
| function bitsEqual(a, b) {
|
| if (a.length !== b.length) return false;
|
| const ua = new Uint32Array(a.buffer, a.byteOffset, a.length);
|
| const ub = new Uint32Array(b.buffer, b.byteOffset, b.length);
|
| for (let i = 0; i < ua.length; i++) if (ua[i] !== ub[i]) return false;
|
| return true;
|
| }
|
|
|
| let failed = 0;
|
| function t(name, fn) {
|
| try { fn(); console.log(` ok ${name}`); }
|
| catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
|
| }
|
|
|
| console.log("\nDaisyChain-Infer — wire protocol\n");
|
|
|
| t("hello round-trips, including the backend string", () => {
|
| const b = Wire.packHello(1234.5, 0xDEADBEEF, "webgpu");
|
| assert.strictEqual(Wire.tagOf(b), Wire.HELLO);
|
| const h = Wire.unpackHello(b);
|
| assert.strictEqual(Math.fround(1234.5), h.capacity);
|
| assert.strictEqual(h.probeHash, 0xDEADBEEF);
|
| assert.strictEqual(h.backend, "webgpu");
|
| });
|
|
|
| t("assignment round-trips the model identity and the plan", () => {
|
| const a = Wire.unpackAssign(Wire.packAssign(assign()));
|
| assert.strictEqual(a.repo, "owner/model");
|
| assert.strictEqual(a.revision, "main");
|
| assert.strictEqual(a.mine, 1);
|
| assert.strictEqual(a.spec.layers, 6);
|
| assert.deepStrictEqual(a.plan.map(s2 => [s2.lo, s2.hi]), [[0, 2], [2, 4], [4, 6]]);
|
| });
|
|
|
|
|
|
|
|
|
|
|
| t("an assignment carries no weight data", () => {
|
| const buf = Wire.packAssign(assign({ spec: Object.assign({}, SPEC, { hidden: 4096, layers: 80, vocab: 128000 }) }));
|
| assert.ok(buf.byteLength < 2048, `assignment is ${buf.byteLength} bytes — it must never carry weights`);
|
| });
|
|
|
|
|
|
|
| t("a plan that does not cover every layer is refused", () => {
|
| const gap = [{ id: "p1", lo: 0, hi: 2, head: true }, { id: "p2", lo: 3, hi: 6, head: false }];
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ plan: gap }))), /cover 5 of 6/);
|
| const over = [{ id: "p1", lo: 0, hi: 4, head: true }, { id: "p2", lo: 2, hi: 6, head: false }];
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ plan: over }))), /cover 8 of 6/);
|
| const oob = [{ id: "p1", lo: 0, hi: 9, head: true }];
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ plan: oob }))), /out of bounds/);
|
| });
|
|
|
| t("an assignment whose stage 0 is not the head is refused", () => {
|
| const bad = [{ id: "p1", lo: 0, hi: 3, head: false }, { id: "p2", lo: 3, hi: 6, head: true }];
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ plan: bad }))), /stage 0 must be the head/);
|
| });
|
|
|
|
|
|
|
|
|
| t("a malformed repo id is refused", () => {
|
| for (const repo of ["", "nope", "../../etc/passwd", "owner/name/extra", "owner/na me"])
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ repo }))), /repo id/, `accepted "${repo}"`);
|
| });
|
|
|
| t("an assignment with no valid stage index for this device is refused", () => {
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ mine: 9 }))), /stage index/);
|
| assert.throws(() => Wire.unpackAssign(Wire.packAssign(assign({ mine: -1 }))), /stage index/);
|
| });
|
|
|
| t("ready round-trips", () => {
|
| const r = Wire.unpackReady(Wire.packReady(2, true, "loaded"));
|
| assert.strictEqual(r.stageIndex, 2);
|
| assert.strictEqual(r.ok, true);
|
| const bad = Wire.unpackReady(Wire.packReady(1, false, "out of memory"));
|
| assert.strictEqual(bad.ok, false);
|
| assert.strictEqual(bad.note, "out of memory");
|
| });
|
|
|
| t("activation round-trips and carries both hashes", () => {
|
| const hidden = new Float32Array(16 * 32);
|
| for (let i = 0; i < hidden.length; i++) hidden[i] = Math.cos(i) * 0.5;
|
| const buf = Wire.packAct(7, 3, 2, hidden, Shard.hashF32, 0x5150);
|
| const a = Wire.unpackAct(buf, Shard.hashF32);
|
| assert.strictEqual(a.seq, 7);
|
| assert.strictEqual(a.tokenIdx, 3);
|
| assert.strictEqual(a.nextIndex, 2);
|
| assert.strictEqual(a.modelHash, 0x5150);
|
| assert.ok(bitsEqual(a.hidden, hidden), "hidden state changed on the wire");
|
| });
|
|
|
|
|
|
|
| t("a corrupted activation is caught by its hash", () => {
|
| const hidden = new Float32Array(64).fill(1.5);
|
| const buf = Wire.packAct(1, 0, 1, hidden, Shard.hashF32, 9);
|
| new Float32Array(buf, 24)[10] = 1.5000001;
|
| assert.throws(() => Wire.unpackAct(buf, Shard.hashF32), /integrity hash/);
|
| });
|
|
|
| t("-0 in an activation survives, and is distinguished from +0", () => {
|
|
|
|
|
|
|
| const hidden = new Float32Array(8);
|
| hidden[3] = -0;
|
| const buf = Wire.packAct(1, 0, 1, hidden, Shard.hashF32, 9);
|
| const a = Wire.unpackAct(buf, Shard.hashF32);
|
| assert.ok(Object.is(a.hidden[3], -0), "-0 did not survive the wire");
|
| new Float32Array(buf, 24)[3] = 0;
|
| assert.throws(() => Wire.unpackAct(buf, Shard.hashF32), /integrity hash/);
|
| });
|
|
|
| t("token and done round-trip", () => {
|
| const tk = Wire.unpackToken(Wire.packToken(4, 1337, 42));
|
| assert.deepStrictEqual([tk.seq, tk.id, tk.total], [4, 1337, 42]);
|
| assert.strictEqual(Wire.tagOf(Wire.packDone(9)), Wire.DONE);
|
| });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function walkLap(plan) {
|
|
|
|
|
| const ran = [];
|
| let addr = 0, guard = 0;
|
| for (;;) {
|
| if (++guard > 100) throw new Error("lap did not terminate — the ring is cycling");
|
| let actor = null;
|
| for (const s of plan) if (Wire.classifyAct(addr, s.index) === "mine") {
|
| if (actor !== null) throw new Error(`two stages both claim address ${addr}`);
|
| actor = s.index;
|
| }
|
| if (actor === null) {
|
| if (Wire.classifyAct(addr, 0) !== "return") throw new Error(`address ${addr} is claimed by nobody`);
|
| return ran;
|
| }
|
| ran.push(actor);
|
| addr = Wire.routeAfter(plan, actor).address;
|
| }
|
| }
|
|
|
| t("a lap visits every stage exactly once and terminates at the head", () => {
|
| for (const n of [1, 2, 3, 5, 8]) {
|
| const plan = Array.from({ length: n }, (_, i) => ({ id: "p" + i, index: i, lo: i, hi: i + 1, head: i === 0 }));
|
| assert.deepStrictEqual(walkLap(plan), plan.map(s => s.index),
|
| `a ${n}-stage ring did not visit each stage exactly once in order`);
|
| }
|
| });
|
|
|
| t("the return leg is addressed differently from stage 0", () => {
|
| const plan = [{ id: "p0", index: 0 }, { id: "p1", index: 1 }];
|
| const last = Wire.routeAfter(plan, 1);
|
| assert.strictEqual(last.to, "p0", "the last stage must hand back to the head");
|
| assert.ok(last.isReturn, "the last hop must be flagged as the return leg");
|
| assert.notStrictEqual(last.address, 0,
|
| "the return leg is addressed as stage 0 — the head will re-run its own blocks and the lap will never close");
|
| assert.strictEqual(Wire.classifyAct(last.address, 0), "return");
|
| assert.strictEqual(Wire.classifyAct(0, 0), "mine");
|
| });
|
|
|
| t("a single-stage ring returns to itself immediately", () => {
|
| const solo = [{ id: "p0", index: 0 }];
|
| const hop = Wire.routeAfter(solo, 0);
|
| assert.ok(hop.isReturn && hop.to === "p0");
|
| assert.deepStrictEqual(walkLap(solo), [0]);
|
| });
|
|
|
| t("every sentinel is distinct and cannot collide with a step number", () => {
|
| const tags = [Wire.FRAG, Wire.HELLO, Wire.ASSIGN, Wire.READY, Wire.ACT, Wire.TOKEN, Wire.DONE];
|
| assert.strictEqual(new Set(tags).size, tags.length, "two sentinels share a value");
|
| for (const t2 of tags) assert.ok(t2 < 0, `sentinel ${t2} is not negative — it could be mistaken for data`);
|
|
|
|
|
| for (const t2 of tags) assert.ok(t2 === Wire.FRAG || t2 <= -20, `sentinel ${t2} overlaps DaisyChain-Web's range`);
|
| });
|
|
|
| console.log(failed ? `\n${failed} failure(s)\n` : "\nall wire checks passed\n");
|
| process.exit(failed ? 1 : 0);
|
|
|