@isidorus/cpu 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +47 -0
  2. package/binding.gyp +103 -0
  3. package/dist/ts/_native.d.ts +13 -0
  4. package/dist/ts/_native.d.ts.map +1 -0
  5. package/dist/ts/_native.js +22 -0
  6. package/dist/ts/_native.js.map +1 -0
  7. package/dist/ts/graph.d.ts +91 -0
  8. package/dist/ts/graph.d.ts.map +1 -0
  9. package/dist/ts/graph.js +95 -0
  10. package/dist/ts/graph.js.map +1 -0
  11. package/dist/ts/index.d.ts +47 -0
  12. package/dist/ts/index.d.ts.map +1 -0
  13. package/dist/ts/index.js +58 -0
  14. package/dist/ts/index.js.map +1 -0
  15. package/dist/ts/inference-pool.d.ts +84 -0
  16. package/dist/ts/inference-pool.d.ts.map +1 -0
  17. package/dist/ts/inference-pool.js +625 -0
  18. package/dist/ts/inference-pool.js.map +1 -0
  19. package/dist/ts/inference_pool.d.ts +99 -0
  20. package/dist/ts/inference_pool.d.ts.map +1 -0
  21. package/dist/ts/inference_pool.js +370 -0
  22. package/dist/ts/inference_pool.js.map +1 -0
  23. package/dist/ts/install-libtensorflow.d.ts +34 -0
  24. package/dist/ts/install-libtensorflow.d.ts.map +1 -0
  25. package/dist/ts/install-libtensorflow.js +254 -0
  26. package/dist/ts/install-libtensorflow.js.map +1 -0
  27. package/dist/ts/ops/array_ops.d.ts +29 -0
  28. package/dist/ts/ops/array_ops.d.ts.map +1 -0
  29. package/dist/ts/ops/array_ops.js +54 -0
  30. package/dist/ts/ops/array_ops.js.map +1 -0
  31. package/dist/ts/ops/index.d.ts +5 -0
  32. package/dist/ts/ops/index.d.ts.map +1 -0
  33. package/dist/ts/ops/index.js +5 -0
  34. package/dist/ts/ops/index.js.map +1 -0
  35. package/dist/ts/ops/math_ops.d.ts +96 -0
  36. package/dist/ts/ops/math_ops.d.ts.map +1 -0
  37. package/dist/ts/ops/math_ops.js +277 -0
  38. package/dist/ts/ops/math_ops.js.map +1 -0
  39. package/dist/ts/ops/nn_ops.d.ts +130 -0
  40. package/dist/ts/ops/nn_ops.d.ts.map +1 -0
  41. package/dist/ts/ops/nn_ops.js +340 -0
  42. package/dist/ts/ops/nn_ops.js.map +1 -0
  43. package/dist/ts/ops/variable_ops.d.ts +128 -0
  44. package/dist/ts/ops/variable_ops.d.ts.map +1 -0
  45. package/dist/ts/ops/variable_ops.js +267 -0
  46. package/dist/ts/ops/variable_ops.js.map +1 -0
  47. package/dist/ts/session.d.ts +83 -0
  48. package/dist/ts/session.d.ts.map +1 -0
  49. package/dist/ts/session.js +81 -0
  50. package/dist/ts/session.js.map +1 -0
  51. package/package.json +63 -0
  52. package/scripts/install.js +100 -0
  53. package/scripts/test-install.js +82 -0
  54. package/scripts/test.js +45 -0
  55. package/src/native/addon.cc +12 -0
  56. package/src/native/graph.cc +442 -0
  57. package/src/native/graph.h +52 -0
  58. package/src/native/platform_tf.h +8 -0
  59. package/src/native/session.cc +716 -0
  60. package/src/native/session.h +92 -0
@@ -0,0 +1,625 @@
1
+ /**
2
+ * InferencePool — strategy-aware inference execution with CPU affinity.
3
+ *
4
+ * Strategies:
5
+ *
6
+ * worker-pool N Workers × Session(intra=1, inter=1)
7
+ * JS controls parallelism. Each Worker owns one Session.
8
+ * N concurrent requests run on N cores simultaneously.
9
+ * Best: small/medium models, high concurrency.
10
+ *
11
+ * tf-parallel 1 Session × Session(intra=hw, inter=1)
12
+ * TF's eigen threadpool owns all TF cores for one request.
13
+ * Concurrent requests queue behind each other.
14
+ * Best: large models where one matmul fills all cores.
15
+ *
16
+ * auto Probe-based selection:
17
+ * model < 150 MB → worker-pool (no probe)
18
+ * model ≥ 150 MB + probeShape → warm probe → threshold
19
+ * model ≥ 150 MB, no probeShape → tf-parallel (fallback)
20
+ *
21
+ * CPU affinity (reserveCores):
22
+ * reserveCores = R pins TF computation to the LAST (N-R) cores.
23
+ * The FIRST R cores stay free for the event loop, libuv I/O, opencv, etc.
24
+ * The fence is applied in OnRunWork immediately before/after TF_SessionRun.
25
+ */
26
+ import { Worker, isMainThread, parentPort, workerData } from "worker_threads";
27
+ import { availableParallelism } from "os";
28
+ import { statSync } from "fs";
29
+ import { performance } from "perf_hooks";
30
+ // ─── Constants ──────────────────────────────────────────────────────────────
31
+ const IDLE = 0;
32
+ const WORK = 1;
33
+ const DONE = 2;
34
+ const SHUTDOWN = 3;
35
+ const CTRL_SLOTS = 4; // Int32 slots per worker in the control SAB
36
+ const SIZE_THRESHOLD_BYTES = 150 * 1024 * 1024; // 150 MB
37
+ const DEFAULT_AUTO_THRESHOLD = 20; // ms
38
+ // ─── Worker-side logic ──────────────────────────────────────────────────────
39
+ //
40
+ // This block runs when the same file is loaded as a Worker thread.
41
+ // The worker owns exactly one TFSession with intra_op=1, so all parallelism
42
+ // is expressed at the Worker level (N workers = N cores).
43
+ //
44
+ // Control protocol (per-worker Int32Array over a SharedArrayBuffer):
45
+ // slot[0] = IDLE → parked, waiting for work
46
+ // WORK → main thread has a request ready
47
+ // DONE → worker finished, result sent via postMessage
48
+ // SHUTDOWN → main thread requests exit
49
+ //
50
+ // Message protocol (postMessage, ordered relative to Atomics):
51
+ // main → worker: { inputData: Buffer, inputShape: number[], inputDtype: number }
52
+ // worker → main: { type: "ready" }
53
+ // { type: "result", outputs: TensorValue[], inferenceMs: number }
54
+ // { type: "work_error", error: string }
55
+ // { type: "shutdown_ack" }
56
+ //
57
+ // Ordering guarantee:
58
+ // Main posts the input message BEFORE storing WORK + notifying,
59
+ // so the worker's Atomics.wait wakes AFTER the message is queued.
60
+ // Node.js buffers port messages until a listener is registered,
61
+ // so parentPort.once("message", ...) safely receives the queued message.
62
+ if (!isMainThread) {
63
+ const { ctrlSab, workerIndex, modelPath, inputOp, outputOps } = workerData;
64
+ const ctrl = new Int32Array(ctrlSab, workerIndex * CTRL_SLOTS * 4, CTRL_SLOTS);
65
+ // ── Init ──────────────────────────────────────────────────────────────────
66
+ let sess;
67
+ try {
68
+ const { TFSession } = await import("jude-tf");
69
+ sess = await TFSession.loadFrozenGraph(modelPath);
70
+ }
71
+ catch (err) {
72
+ parentPort.postMessage({
73
+ type: "init_error",
74
+ error: err?.stack ?? String(err),
75
+ });
76
+ process.exit(1);
77
+ }
78
+ Atomics.store(ctrl, 0, IDLE);
79
+ parentPort.postMessage({ type: "ready" });
80
+ // Reinterpret raw bytes as the correct typed array for jude-tf.
81
+ // postMessage structured-clone strips the Buffer prototype, so the worker
82
+ // receives a plain Uint8Array. We reinterpret the underlying bytes as the
83
+ // correct typed array so jude-tf sees the right TF_DataType.
84
+ function asTypedArray(buf, dtype) {
85
+ const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
86
+ switch (dtype) {
87
+ case 1:
88
+ return new Float32Array(ab); // TF_FLOAT
89
+ case 2:
90
+ return new Float64Array(ab); // TF_DOUBLE
91
+ case 3:
92
+ return new Int32Array(ab); // TF_INT32
93
+ case 4:
94
+ return new Uint8Array(ab); // TF_UINT8
95
+ case 9:
96
+ return new BigInt64Array(ab); // TF_INT64
97
+ default:
98
+ return new Uint8Array(ab);
99
+ }
100
+ }
101
+ // ── Work loop ─────────────────────────────────────────────────────────────
102
+ // Atomics.wait BLOCKS the worker thread (allowed in Worker threads, not in
103
+ // the main thread). The block is intentional — the worker is dedicated to
104
+ // inference and has no other async work to process while parked.
105
+ while (true) {
106
+ // Park until main thread sets ctrl to WORK or SHUTDOWN.
107
+ Atomics.wait(ctrl, 0, IDLE);
108
+ const state = Atomics.load(ctrl, 0);
109
+ if (state === SHUTDOWN) {
110
+ sess.destroy();
111
+ parentPort.postMessage({ type: "shutdown_ack" });
112
+ break;
113
+ }
114
+ if (state === WORK) {
115
+ // Receive input data. Main posted it BEFORE storing WORK,
116
+ // so the message is already queued in the port's buffer.
117
+ const msg = await new Promise((resolve) => parentPort.once("message", resolve));
118
+ try {
119
+ const t0 = performance.now();
120
+ const inputArray = asTypedArray(msg.inputData, msg.inputDtype);
121
+ const results = await sess.run({ [inputOp]: inputArray }, outputOps);
122
+ const inferenceMs = performance.now() - t0;
123
+ Atomics.store(ctrl, 0, DONE);
124
+ Atomics.notify(ctrl, 0, 1);
125
+ parentPort.postMessage({
126
+ type: "result",
127
+ outputs: outputOps.map((k) => {
128
+ const r = results[k];
129
+ const view = r.data;
130
+ return {
131
+ dtype: r.dtype,
132
+ shape: r.shape,
133
+ // Copy into a Buffer — postMessage will structured-clone it as
134
+ // Uint8Array on the receiving end; the main thread wraps it back
135
+ // into a Buffer in handleMessage.
136
+ data: Buffer.from(view.buffer, view.byteOffset, view.byteLength),
137
+ };
138
+ }),
139
+ inferenceMs,
140
+ });
141
+ }
142
+ catch (err) {
143
+ console.error(`[worker ${workerIndex}] error:`, err?.stack ?? String(err));
144
+ Atomics.store(ctrl, 0, DONE);
145
+ Atomics.notify(ctrl, 0, 1);
146
+ parentPort.postMessage({
147
+ type: "work_error",
148
+ error: err?.stack ?? String(err),
149
+ });
150
+ }
151
+ // Use compareExchange instead of store — if the main thread wrote
152
+ // SHUTDOWN between our DONE store and here, don't overwrite it.
153
+ // Otherwise the next Atomics.wait(ctrl, 0, IDLE) would block forever
154
+ // waiting for a notify that never comes.
155
+ Atomics.compareExchange(ctrl, 0, DONE, IDLE);
156
+ }
157
+ }
158
+ }
159
+ export class InferencePool {
160
+ strategy;
161
+ reserveCores;
162
+ workerSlots;
163
+ queue;
164
+ ctrlSab;
165
+ // tf-parallel path — exactly one of these pairs is non-null:
166
+ // (tfParallelGraph, tfParallelSess) — native @isidorus/cpu Session
167
+ // uses Graph.getOp() for feed/fetch
168
+ // (null, tfParallelSess) — jude-tf TFSession fallback
169
+ // uses dict API { [opName]: data }
170
+ tfParallelGraph;
171
+ tfParallelSess;
172
+ tfParallelBusy;
173
+ tfParallelQueue;
174
+ modelPath;
175
+ inputOp;
176
+ outputOps;
177
+ constructor(params) {
178
+ this.strategy = params.strategy;
179
+ this.reserveCores = params.reserveCores;
180
+ this.workerSlots = params.workerSlots;
181
+ this.queue = params.queue;
182
+ this.ctrlSab = params.ctrlSab;
183
+ this.tfParallelGraph = params.tfParallelGraph;
184
+ this.tfParallelSess = params.tfParallelSess;
185
+ this.tfParallelBusy = false;
186
+ this.tfParallelQueue = [];
187
+ this.modelPath = params.modelPath;
188
+ this.inputOp = params.inputOp;
189
+ this.outputOps = params.outputOps;
190
+ }
191
+ // ── Factory ────────────────────────────────────────────────────────────────
192
+ static async create(opts) {
193
+ // Auto-discover input/output op names if not provided.
194
+ // Loads the frozen graph once via jude-tf, reads inferred Placeholder
195
+ // names and sink op names, then destroys the probe session.
196
+ if (!opts.inputOp || !opts.outputOps?.length) {
197
+ const { TFSession } = await import("jude-tf");
198
+ const probe = await TFSession.loadFrozenGraph(opts.modelPath);
199
+ opts.inputOp ??= probe.inputs[0];
200
+ opts.outputOps ??= probe.outputs;
201
+ probe.destroy();
202
+ if (!opts.inputOp)
203
+ throw new Error(`Could not infer inputOp from ${opts.modelPath}`);
204
+ if (!opts.outputOps?.length)
205
+ throw new Error(`Could not infer outputOps from ${opts.modelPath}`);
206
+ }
207
+ const requestedStrategy = opts.strategy ?? "auto";
208
+ const concurrency = opts.concurrency ?? availableParallelism();
209
+ const autoThreshold = opts.autoThresholdMs ?? DEFAULT_AUTO_THRESHOLD;
210
+ const reserveCores = opts.reserveCores ?? 0;
211
+ let resolved;
212
+ if (requestedStrategy === "worker-pool") {
213
+ resolved = "worker-pool";
214
+ }
215
+ else if (requestedStrategy === "tf-parallel") {
216
+ resolved = "tf-parallel";
217
+ }
218
+ else {
219
+ // auto — file size as cheap first signal, probe if ambiguous
220
+ const modelBytes = statSync(opts.modelPath).size;
221
+ if (modelBytes < SIZE_THRESHOLD_BYTES) {
222
+ resolved = "worker-pool";
223
+ }
224
+ else if (!opts.probeShape) {
225
+ resolved = "tf-parallel";
226
+ process.stderr.write(`[isidorus] auto: ${(modelBytes / 1024 / 1024).toFixed(1)}MB >= ` +
227
+ `threshold, no probeShape → tf-parallel\n`);
228
+ }
229
+ else {
230
+ // Warm probe with intra=1 — measure single-core inference time
231
+ const { TFSession } = await import("jude-tf");
232
+ const probeSess = await TFSession.loadFrozenGraph(opts.modelPath);
233
+ const probeInput = Buffer.alloc(opts.probeShape.reduce((a, b) => a * b, 1) * 4);
234
+ await probeSess.runAsync({ [opts.inputOp]: probeInput }, opts.outputOps);
235
+ const t0 = performance.now();
236
+ await probeSess.runAsync({ [opts.inputOp]: probeInput }, opts.outputOps);
237
+ const probeMs = performance.now() - t0;
238
+ probeSess.destroy();
239
+ resolved = probeMs >= autoThreshold ? "tf-parallel" : "worker-pool";
240
+ process.stderr.write(`[isidorus] auto: probe=${probeMs.toFixed(2)}ms ` +
241
+ `threshold=${autoThreshold}ms → ${resolved}\n`);
242
+ }
243
+ }
244
+ if (reserveCores > 0) {
245
+ const hw = availableParallelism();
246
+ const tfCores = Math.max(1, hw - reserveCores);
247
+ process.stderr.write(`[isidorus] CPU affinity: reserving ${reserveCores} core(s), ` +
248
+ `TF gets ${tfCores} core(s)\n`);
249
+ }
250
+ return resolved === "worker-pool"
251
+ ? InferencePool.createWorkerPool(opts, concurrency, reserveCores)
252
+ : InferencePool.createTfParallel(opts, reserveCores);
253
+ }
254
+ // ── worker-pool init ───────────────────────────────────────────────────────
255
+ static async createWorkerPool(opts, concurrency, reserveCores) {
256
+ const ctrlSab = new SharedArrayBuffer(concurrency * CTRL_SLOTS * 4);
257
+ const slots = [];
258
+ const startedWorkers = [];
259
+ // In dev/test we run TypeScript source directly via tsx. Workers don't
260
+ // inherit --import tsx from the parent, so we use a small .mjs bootstrap
261
+ // (inference-pool-worker.mjs) that calls register() from tsx/esm/api
262
+ // before importing this .ts file. In production the compiled .js entry
263
+ // is used directly with no extra loader needed.
264
+ const isTsSource = import.meta.url.endsWith(".ts");
265
+ const workerEntry = isTsSource
266
+ ? new URL("./inference-pool-worker.mjs", import.meta.url)
267
+ : new URL("./inference-pool.js", import.meta.url);
268
+ try {
269
+ for (let i = 0; i < concurrency; i++) {
270
+ const ctrl = new Int32Array(ctrlSab, i * CTRL_SLOTS * 4, CTRL_SLOTS);
271
+ Atomics.store(ctrl, 0, IDLE);
272
+ const worker = new Worker(workerEntry, {
273
+ workerData: {
274
+ ctrlSab,
275
+ workerIndex: i,
276
+ modelPath: opts.modelPath,
277
+ inputOp: opts.inputOp,
278
+ outputOps: opts.outputOps,
279
+ reserveCores,
280
+ },
281
+ });
282
+ startedWorkers.push(worker);
283
+ await new Promise((resolve, reject) => {
284
+ worker.once("message", (msg) => {
285
+ if (msg.type === "ready")
286
+ resolve();
287
+ else if (msg.type === "init_error")
288
+ reject(new Error(`Worker ${i} init failed: ${msg.error}`));
289
+ else
290
+ reject(new Error(`Worker ${i} unexpected init message: ${msg.type}`));
291
+ });
292
+ worker.once("error", reject);
293
+ });
294
+ slots.push({ worker, ctrl, busy: false, resolve: null, reject: null });
295
+ }
296
+ }
297
+ catch (err) {
298
+ // Terminate any workers that were already started before the failure.
299
+ await Promise.allSettled(startedWorkers.map((w) => w.terminate()));
300
+ throw err;
301
+ }
302
+ return new InferencePool({
303
+ strategy: "worker-pool",
304
+ reserveCores,
305
+ workerSlots: slots,
306
+ queue: [],
307
+ ctrlSab,
308
+ tfParallelGraph: null,
309
+ tfParallelSess: null,
310
+ modelPath: opts.modelPath,
311
+ inputOp: opts.inputOp,
312
+ outputOps: opts.outputOps,
313
+ });
314
+ }
315
+ // ── tf-parallel init ───────────────────────────────────────────────────────
316
+ static async createTfParallel(opts, reserveCores) {
317
+ const hw = availableParallelism();
318
+ const tfCores = Math.max(1, hw - reserveCores);
319
+ // Try the native @isidorus/cpu Session path first (ConfigProto thread
320
+ // config + OnRunWork affinity fence). Falls back to jude-tf if the addon
321
+ // hasn't been initialised (e.g. when called from outside @isidorus/cpu).
322
+ //
323
+ // We import _native.js rather than "@isidorus/cpu" to avoid a circular
324
+ // dependency — this file IS part of @isidorus/cpu, so importing the
325
+ // package entry point would re-run ensureTf() + node-gyp-build.
326
+ let tfParallelGraph = null;
327
+ let tfParallelSess = null;
328
+ try {
329
+ const { getAddon } = await import("./_native.js");
330
+ const { readFileSync } = await import("fs");
331
+ const { Graph: GraphClass } = await import("./graph.js");
332
+ const { Session: SessionClass } = await import("./session.js");
333
+ const addon = getAddon();
334
+ const g = new GraphClass(new addon.Graph());
335
+ g.importGraphDef(readFileSync(opts.modelPath));
336
+ tfParallelGraph = g;
337
+ tfParallelSess = new SessionClass(new addon.Session(g._native, {
338
+ strategy: "tf-parallel",
339
+ reserveCores,
340
+ }));
341
+ process.stderr.write(`[isidorus] tf-parallel: intra_op=${tfCores} ` +
342
+ `(${reserveCores} core(s) reserved, native Session)\n`);
343
+ }
344
+ catch {
345
+ // Native addon not available — fall back to jude-tf TFSession.
346
+ // This path lacks the affinity fence but is otherwise correct.
347
+ const { TFSession } = await import("jude-tf");
348
+ tfParallelSess = await TFSession.loadFrozenGraph(opts.modelPath);
349
+ process.stderr.write(`[isidorus] tf-parallel: intra_op=${tfCores} ` +
350
+ `(${reserveCores} core(s) reserved, jude-tf fallback)\n`);
351
+ }
352
+ return new InferencePool({
353
+ strategy: "tf-parallel",
354
+ reserveCores,
355
+ workerSlots: [],
356
+ queue: [],
357
+ ctrlSab: null,
358
+ tfParallelGraph,
359
+ tfParallelSess,
360
+ modelPath: opts.modelPath,
361
+ inputOp: opts.inputOp,
362
+ outputOps: opts.outputOps,
363
+ });
364
+ }
365
+ // ── Inference ──────────────────────────────────────────────────────────────
366
+ infer(inputBuf, inputShape, inputDtype = 1) {
367
+ return this.strategy === "worker-pool"
368
+ ? this.inferWorkerPool(inputBuf, inputShape, inputDtype)
369
+ : this.inferTfParallel(inputBuf, inputShape, inputDtype);
370
+ }
371
+ inferWorkerPool(inputBuf, inputShape, inputDtype) {
372
+ return new Promise((resolve, reject) => {
373
+ const slot = this.workerSlots.find((w) => !w.busy);
374
+ if (slot) {
375
+ this.dispatchToWorker(slot, inputBuf, inputShape, inputDtype, resolve, reject);
376
+ }
377
+ else {
378
+ this.queue.push({ inputBuf, inputShape, inputDtype, resolve, reject });
379
+ }
380
+ });
381
+ }
382
+ dispatchToWorker(slot, inputBuf, inputShape, inputDtype, resolve, reject) {
383
+ const workerId = this.workerSlots.indexOf(slot);
384
+ slot.busy = true;
385
+ slot.resolve = resolve;
386
+ slot.reject = reject;
387
+ // ── ORDERING CRITICAL ──────────────────────────────────────────────────
388
+ // 1. Register the result listener FIRST — before the worker can possibly
389
+ // send a response. Node.js buffers port messages until a listener is
390
+ // registered, but registering after notify introduces a thread-level
391
+ // race where an extremely fast result could be missed.
392
+ // 2. Post the input data SECOND — the worker awaits this message after
393
+ // waking from Atomics.wait, so it must arrive before WORK is stored.
394
+ // 3. Store WORK + notify LAST — wakes the worker.
395
+ const handleMessage = (msg) => {
396
+ if (msg.type === "work_error") {
397
+ this.settleSlot(slot, null, new Error(msg.error));
398
+ return;
399
+ }
400
+ if (msg.type !== "result") {
401
+ // Unexpected message type — re-register to wait for the actual result.
402
+ slot.worker.once("message", handleMessage);
403
+ return;
404
+ }
405
+ this.settleSlot(slot, {
406
+ workerId,
407
+ strategy: "worker-pool",
408
+ outputs: msg.outputs.map((o) => ({
409
+ dtype: o.dtype,
410
+ shape: o.shape,
411
+ // postMessage structured-clones Buffer as plain Uint8Array —
412
+ // wrap it back into a Buffer so callers can use Buffer.isBuffer().
413
+ data: Buffer.isBuffer(o.data) ? o.data : Buffer.from(o.data),
414
+ })),
415
+ inferenceMs: msg.inferenceMs,
416
+ }, null);
417
+ };
418
+ // Register listener before waking the worker.
419
+ slot.worker.once("message", handleMessage);
420
+ // Register a one-shot error listener so an uncaught worker crash rejects
421
+ // the promise instead of leaving it hanging.
422
+ slot.worker.once("error", (err) => {
423
+ this.settleSlot(slot, null, err);
424
+ });
425
+ // Post input, then wake worker.
426
+ slot.worker.postMessage({ inputData: inputBuf, inputShape, inputDtype });
427
+ Atomics.store(slot.ctrl, 0, WORK);
428
+ Atomics.notify(slot.ctrl, 0, 1);
429
+ }
430
+ /** Settle a worker slot's in-flight promise and drain the queue. */
431
+ settleSlot(slot, result, err) {
432
+ const resolve = slot.resolve;
433
+ const reject = slot.reject;
434
+ slot.busy = false;
435
+ slot.resolve = null;
436
+ slot.reject = null;
437
+ if (err)
438
+ reject?.(err);
439
+ else
440
+ resolve?.(result);
441
+ // Drain one queued request now that the slot is free.
442
+ const next = this.queue.shift();
443
+ if (next) {
444
+ this.dispatchToWorker(slot, next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
445
+ }
446
+ }
447
+ // ── tf-parallel path ───────────────────────────────────────────────────────
448
+ inferTfParallel(inputBuf, inputShape, inputDtype) {
449
+ return new Promise((resolve, reject) => {
450
+ if (this.tfParallelBusy) {
451
+ this.tfParallelQueue.push({
452
+ inputBuf,
453
+ inputShape,
454
+ inputDtype,
455
+ resolve,
456
+ reject,
457
+ });
458
+ return;
459
+ }
460
+ this.runTfParallel(inputBuf, inputShape, inputDtype, resolve, reject);
461
+ });
462
+ }
463
+ runTfParallel(inputBuf, inputShape, inputDtype, resolve, reject) {
464
+ this.tfParallelBusy = true;
465
+ const t0 = performance.now();
466
+ let inferencePromise;
467
+ if (this.tfParallelGraph) {
468
+ // ── Native @isidorus/cpu Session path ──────────────────────────────
469
+ // Build feed/fetch arrays using Graph.getOp() to resolve op names to
470
+ // Tensor references, which Session.runAsync expects.
471
+ const g = this.tfParallelGraph;
472
+ const inputTensor = g.getOp(this.inputOp);
473
+ if (!inputTensor) {
474
+ this.tfParallelBusy = false;
475
+ reject(new Error(`tf-parallel: input op not found in graph: ${this.inputOp}`));
476
+ return;
477
+ }
478
+ const outputTensors = this.outputOps.map((name) => {
479
+ const t = g.getOp(name);
480
+ if (!t)
481
+ throw new Error(`tf-parallel: output op not found in graph: ${name}`);
482
+ return t;
483
+ });
484
+ // Reinterpret the raw Buffer bytes as the correct TypedArray dtype.
485
+ // asTypedArray is only defined inside the !isMainThread block, so we
486
+ // inline the same logic here for the main-thread tf-parallel path.
487
+ const ab = inputBuf.buffer.slice(inputBuf.byteOffset, inputBuf.byteOffset + inputBuf.byteLength);
488
+ let typedInput;
489
+ switch (inputDtype) {
490
+ case 1:
491
+ typedInput = new Float32Array(ab);
492
+ break;
493
+ case 2:
494
+ typedInput = new Float64Array(ab);
495
+ break;
496
+ case 3:
497
+ typedInput = new Int32Array(ab);
498
+ break;
499
+ case 4:
500
+ typedInput = new Uint8Array(ab);
501
+ break;
502
+ case 9:
503
+ typedInput = new BigInt64Array(ab);
504
+ break;
505
+ default:
506
+ typedInput = new Uint8Array(ab);
507
+ }
508
+ const feedValue = {
509
+ dtype: inputDtype,
510
+ shape: inputShape,
511
+ data: Buffer.from(typedInput.buffer, typedInput.byteOffset, typedInput.byteLength),
512
+ };
513
+ inferencePromise = this.tfParallelSess.runAsync([[inputTensor, feedValue]], outputTensors).then((outputs) => {
514
+ // Map back to { [outputKey]: TensorResult } for uniform handling below
515
+ const result = {};
516
+ this.outputOps.forEach((key, i) => {
517
+ result[key] = outputs[i];
518
+ });
519
+ return result;
520
+ });
521
+ }
522
+ else {
523
+ // ── jude-tf TFSession fallback path ───────────────────────────────
524
+ inferencePromise = this.tfParallelSess.runAsync({ [this.inputOp]: inputBuf }, this.outputOps);
525
+ }
526
+ inferencePromise
527
+ .then((results) => {
528
+ const inferenceMs = performance.now() - t0;
529
+ this.tfParallelBusy = false;
530
+ resolve({
531
+ workerId: 0,
532
+ strategy: "tf-parallel",
533
+ outputs: this.outputOps.map((k) => {
534
+ const r = results[k];
535
+ if (!r)
536
+ return { dtype: 0, shape: [], data: Buffer.alloc(0) };
537
+ const view = r.data;
538
+ return {
539
+ dtype: r.dtype,
540
+ shape: r.shape,
541
+ data: Buffer.isBuffer(r.data)
542
+ ? r.data
543
+ : Buffer.from(view.buffer, view.byteOffset, view.byteLength),
544
+ };
545
+ }),
546
+ inferenceMs,
547
+ });
548
+ const next = this.tfParallelQueue.shift();
549
+ if (next) {
550
+ this.runTfParallel(next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
551
+ }
552
+ })
553
+ .catch((err) => {
554
+ this.tfParallelBusy = false;
555
+ reject(err);
556
+ const next = this.tfParallelQueue.shift();
557
+ if (next) {
558
+ this.runTfParallel(next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
559
+ }
560
+ });
561
+ }
562
+ // ── Introspection ──────────────────────────────────────────────────────────
563
+ get busyCount() {
564
+ if (this.strategy === "worker-pool")
565
+ return this.workerSlots.filter((w) => w.busy).length;
566
+ return this.tfParallelBusy ? 1 : 0;
567
+ }
568
+ get queueDepth() {
569
+ return this.strategy === "worker-pool"
570
+ ? this.queue.length
571
+ : this.tfParallelQueue.length;
572
+ }
573
+ get size() {
574
+ return this.strategy === "worker-pool" ? this.workerSlots.length : 1;
575
+ }
576
+ // ── Lifecycle ──────────────────────────────────────────────────────────────
577
+ async destroy() {
578
+ if (this.strategy === "worker-pool") {
579
+ await Promise.all(this.workerSlots.map((slot) => new Promise((resolve, reject) => {
580
+ const doShutdown = () => {
581
+ // Register shutdown_ack listener before storing SHUTDOWN.
582
+ slot.worker.once("message", (msg) => {
583
+ if (msg.type === "shutdown_ack")
584
+ resolve();
585
+ });
586
+ slot.worker.once("error", reject);
587
+ Atomics.store(slot.ctrl, 0, SHUTDOWN);
588
+ Atomics.notify(slot.ctrl, 0, 1);
589
+ };
590
+ if (slot.busy) {
591
+ // Wait for the current in-flight request to finish first.
592
+ const origResolve = slot.resolve;
593
+ const origReject = slot.reject;
594
+ slot.resolve = (r) => {
595
+ origResolve?.(r);
596
+ doShutdown();
597
+ };
598
+ slot.reject = (e) => {
599
+ origReject?.(e);
600
+ doShutdown();
601
+ };
602
+ }
603
+ else {
604
+ doShutdown();
605
+ }
606
+ })));
607
+ }
608
+ else {
609
+ if (this.tfParallelBusy) {
610
+ await new Promise((res) => {
611
+ const t = setInterval(() => {
612
+ if (!this.tfParallelBusy) {
613
+ clearInterval(t);
614
+ res();
615
+ }
616
+ }, 1);
617
+ });
618
+ }
619
+ this.tfParallelSess?.destroy();
620
+ this.tfParallelSess = null;
621
+ this.tfParallelGraph = null;
622
+ }
623
+ }
624
+ }
625
+ //# sourceMappingURL=inference-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-pool.js","sourceRoot":"","sources":["../../src/ts/inference-pool.ts"],"names":[],"mappings":"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"}