const F32_FIELDS = ["g", "params", "avg"];
const scratch = new ArrayBuffer(4);
const scratchF32 = new Float32Array(scratch);
const scratchU32 = new Uint32Array(scratch);
export function f32ToF16(value) {
scratchF32[0] = value;
const bits = scratchU32[0];
const sign = (bits >>> 16) & 0x8000;
const exponent = (bits >>> 23) & 0xff;
let mantissa = bits & 0x7fffff;
if (exponent === 0xff) {
return sign | 0x7c00 | (mantissa ? 0x200 : 0);
}
let e = exponent - 127 + 15;
if (e >= 0x1f) return sign | 0x7c00;
if (e <= 0) {
if (e < -10) return sign; mantissa |= 0x800000;
const shift = 14 - e;
const rounded = (mantissa + (1 << (shift - 1))) >>> shift;
return sign | rounded;
}
const rounded = mantissa + 0x0fff + ((mantissa >>> 13) & 1);
if (rounded & 0x800000) {
e += 1;
if (e >= 0x1f) return sign | 0x7c00;
return sign | (e << 10);
}
return sign | (e << 10) | ((rounded >>> 13) & 0x3ff);
}
export function f16ToF32(bits) {
const sign = bits & 0x8000 ? -1 : 1;
const exponent = (bits >>> 10) & 0x1f;
const mantissa = bits & 0x3ff;
if (exponent === 0) return sign * mantissa * 2 ** -24;
if (exponent === 0x1f) return mantissa ? NaN : sign * Infinity;
return sign * (1 + mantissa / 1024) * 2 ** (exponent - 15);
}
export const WIRE_FORMATS = {
f32: null,
f16: { id: "f16", bits: 16, exp: 5, mant: 10, bias: 15, inf: true, target: 1024 },
f8e4m3: { id: "f8e4m3", bits: 8, exp: 4, mant: 3, bias: 7, inf: false, target: 192 },
f8e5m2: { id: "f8e5m2", bits: 8, exp: 5, mant: 2, bias: 15, inf: true, target: 1024 },
};
export function decodeMini(code, f) {
const maxExp = (1 << f.exp) - 1;
const sign = code >>> (f.exp + f.mant) ? -1 : 1;
const exp = (code >>> f.mant) & maxExp;
const mant = code & ((1 << f.mant) - 1);
if (exp === maxExp) {
if (f.inf) return mant ? NaN : sign * Infinity;
if (mant === (1 << f.mant) - 1) return NaN;
return sign * (1 + mant / (1 << f.mant)) * 2 ** (maxExp - f.bias);
}
if (exp === 0) return (sign * mant) / (1 << f.mant) * 2 ** (1 - f.bias);
return sign * (1 + mant / (1 << f.mant)) * 2 ** (exp - f.bias);
}
const tables = new Map();
function table(f) {
if (!tables.has(f.id)) {
const entries = [];
for (let code = 0; code < 1 << f.bits; code++) {
const value = decodeMini(code, f);
if (Number.isFinite(value)) entries.push({ code, value });
}
entries.sort((a, b) => a.value - b.value);
tables.set(f.id, {
values: Float64Array.from(entries.map((e) => e.value)),
codes: Uint16Array.from(entries.map((e) => e.code)),
});
}
return tables.get(f.id);
}
function encodeMini(value, f) {
const { values, codes } = table(f);
if (Number.isNaN(value)) return (1 << (f.exp + f.mant)) - 1 | (((1 << f.exp) - 1) << f.mant);
if (value <= values[0]) return codes[0];
if (value >= values[values.length - 1]) return codes[values.length - 1];
let lo = 0;
let hi = values.length - 1;
while (hi - lo > 1) {
const mid = (lo + hi) >> 1;
if (values[mid] <= value) lo = mid;
else hi = mid;
}
const dLo = value - values[lo];
const dHi = values[hi] - value;
if (dLo < dHi) return codes[lo];
if (dHi < dLo) return codes[hi];
return codes[lo] % 2 === 0 ? codes[lo] : codes[hi];
}
const ARRAYS = { 8: Uint8Array, 16: Uint16Array };
const bridges = new Map();
function bridge(f) {
if (!bridges.has(f.id)) {
const map = new Uint8Array(0x10000);
for (let code = 0; code < 0x10000; code++) {
map[code] = encodeMini(f16ToF32(code), f);
}
bridges.set(f.id, map);
}
return bridges.get(f.id);
}
export function quantize(values, f) {
let maxAbs = 0;
for (let i = 0; i < values.length; i++) {
const a = Math.abs(values[i]);
if (a > maxAbs && Number.isFinite(a)) maxAbs = a;
}
const scale = maxAbs > 0 ? f.target / maxAbs : 1;
const out = new ARRAYS[f.bits](values.length);
if (f.id === "f16") {
for (let i = 0; i < values.length; i++) out[i] = f32ToF16(values[i] * scale);
} else {
const via = bridge(f);
for (let i = 0; i < values.length; i++) out[i] = via[f32ToF16(values[i] * scale)];
}
return { scale, payload: out };
}
export function dequantize(payload, scale, f) {
const out = new Float32Array(payload.length);
const inv = 1 / scale;
if (f.id === "f16") {
for (let i = 0; i < payload.length; i++) out[i] = f16ToF32(payload[i]) * inv;
} else {
for (let i = 0; i < payload.length; i++) out[i] = decodeMini(payload[i], f) * inv;
}
return out;
}
export const quantizeF16 = (values) => quantize(values, WIRE_FORMATS.f16);
export const dequantizeF16 = (payload, scale) =>
dequantize(payload, scale, WIRE_FORMATS.f16);
export function encode(msg, { precision = "f32" } = {}) {
const field = F32_FIELDS.find((k) => msg[k] instanceof Float32Array);
let payload = field ? msg[field] : null;
const header = { ...msg };
let format = null;
if (field) {
delete header[field];
header._f32 = field;
const f = WIRE_FORMATS[precision];
if (f && payload.length) {
const q = quantize(payload, f);
header._fmt = f.id;
header._scale = q.scale;
payload = q.payload;
format = f;
}
}
let json = new TextEncoder().encode(JSON.stringify(header));
const pad = (4 - ((4 + json.length) % 4)) % 4;
if (pad) {
const padded = new Uint8Array(json.length + pad);
padded.set(json);
padded.fill(0x20, json.length); json = padded;
}
const buf = new ArrayBuffer(4 + json.length + (payload ? payload.byteLength : 0));
new DataView(buf).setUint32(0, json.length, true);
new Uint8Array(buf, 4, json.length).set(json);
if (payload) {
const Ctor = format ? ARRAYS[format.bits] : Float32Array;
new Ctor(buf, 4 + json.length, payload.length).set(payload);
}
return buf;
}
export function decode(buf) {
const view = new DataView(buf);
const headerLen = view.getUint32(0, true);
const json = new TextDecoder().decode(new Uint8Array(buf, 4, headerLen));
const msg = JSON.parse(json);
if (msg._f32) {
const offset = 4 + headerLen;
const field = msg._f32;
const f = msg._fmt ? WIRE_FORMATS[msg._fmt] : null;
if (f) {
const Ctor = ARRAYS[f.bits];
const raw = new Ctor(buf, offset, (buf.byteLength - offset) / (f.bits / 8));
msg[field] = dequantize(raw, msg._scale, f);
delete msg._fmt;
delete msg._scale;
} else {
msg[field] = new Float32Array(buf, offset, (buf.byteLength - offset) / 4);
}
delete msg._f32;
}
return msg;
}
export function roundTrip(values, precision) {
const f = WIRE_FORMATS[precision];
if (!f || !values.length) return null;
const { scale, payload } = quantize(values, f);
return dequantize(payload, scale, f);
}
export function channelBus(name, { onError = () => {}, precision = "f32" } = {}) {
const ch = new BroadcastChannel(name);
let bytes = 0;
const bus = {
onmessage() {},
postMessage: (msg) => {
const buf = encode(msg, { precision });
bytes += buf.byteLength;
ch.postMessage(buf);
},
close: () => ch.close(),
quantize: (values) => roundTrip(values, precision),
bytes: () => bytes,
};
ch.onmessage = (ev) => {
try {
bytes += ev.data.byteLength ?? 0;
bus.onmessage({ data: decode(ev.data) });
} catch (e) {
onError(`undecodable frame: ${e?.message ?? e}`);
}
};
return bus;
}
export function proxyBus(port, { tag = "bus", onError = () => {}, precision = "f32" } = {}) {
let depth = 0;
let bytes = 0;
const bus = {
onmessage() {},
postMessage(msg) {
const buf = encode(msg, { precision });
bytes += buf.byteLength;
port.postMessage({ t: tag, kind: msg.t, buf }, [buf]);
},
pressure: () => depth,
quantize: (values) => roundTrip(values, precision),
bytes: () => bytes,
close() {},
};
const prior = port.onmessage?.bind(port);
port.onmessage = (ev) => {
if (ev.data?.t === `${tag}:pressure`) {
depth = ev.data.depth;
return;
}
if (ev.data?.t !== tag) {
prior?.(ev);
return;
}
try {
bytes += ev.data.buf?.byteLength ?? 0;
bus.onmessage({ data: decode(ev.data.buf) });
} catch (e) {
onError(`undecodable frame: ${e?.message ?? e}`);
}
};
return bus;
}
export function proxyHost(
worker,
send,
{ tag = "bus", maxInflight = 1, maxQueue = 32, onDrop = () => {} } = {},
) {
let inflight = 0;
let round = null; const small = [];
const depth = () => small.length + (round ? 1 : 0) + inflight;
const reportPressure = () => worker.postMessage({ t: `${tag}:pressure`, depth: depth() });
function take() {
if (small.length) return small.shift();
if (round) {
const r = round;
round = null;
return r;
}
return null;
}
function pump() {
while (inflight < maxInflight) {
const next = take();
if (!next) break;
inflight += 1;
let settled;
try {
settled = send(next);
} catch (e) {
inflight -= 1;
onDrop(`send threw: ${e?.message ?? e}`);
continue;
}
Promise.resolve(settled)
.catch((e) => onDrop(`send failed: ${e?.message ?? e}`))
.finally(() => {
inflight -= 1;
reportPressure();
pump();
});
}
reportPressure();
}
const prior = worker.onmessage?.bind(worker);
worker.onmessage = (ev) => {
if (ev.data?.t !== tag) {
prior?.(ev);
return;
}
if (ev.data.kind === "round") {
if (round) onDrop("superseded a queued round");
round = ev.data.buf;
} else {
if (small.length >= maxQueue) {
small.shift();
onDrop("outbound queue full, dropped the oldest message");
}
small.push(ev.data.buf);
}
pump();
};
return {
deliver(buf) {
worker.postMessage({ t: tag, buf }, [buf]);
},
pressure: depth,
};
}