@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.
- package/README.md +47 -0
- package/binding.gyp +103 -0
- package/dist/ts/_native.d.ts +13 -0
- package/dist/ts/_native.d.ts.map +1 -0
- package/dist/ts/_native.js +22 -0
- package/dist/ts/_native.js.map +1 -0
- package/dist/ts/graph.d.ts +91 -0
- package/dist/ts/graph.d.ts.map +1 -0
- package/dist/ts/graph.js +95 -0
- package/dist/ts/graph.js.map +1 -0
- package/dist/ts/index.d.ts +47 -0
- package/dist/ts/index.d.ts.map +1 -0
- package/dist/ts/index.js +58 -0
- package/dist/ts/index.js.map +1 -0
- package/dist/ts/inference-pool.d.ts +84 -0
- package/dist/ts/inference-pool.d.ts.map +1 -0
- package/dist/ts/inference-pool.js +625 -0
- package/dist/ts/inference-pool.js.map +1 -0
- package/dist/ts/inference_pool.d.ts +99 -0
- package/dist/ts/inference_pool.d.ts.map +1 -0
- package/dist/ts/inference_pool.js +370 -0
- package/dist/ts/inference_pool.js.map +1 -0
- package/dist/ts/install-libtensorflow.d.ts +34 -0
- package/dist/ts/install-libtensorflow.d.ts.map +1 -0
- package/dist/ts/install-libtensorflow.js +254 -0
- package/dist/ts/install-libtensorflow.js.map +1 -0
- package/dist/ts/ops/array_ops.d.ts +29 -0
- package/dist/ts/ops/array_ops.d.ts.map +1 -0
- package/dist/ts/ops/array_ops.js +54 -0
- package/dist/ts/ops/array_ops.js.map +1 -0
- package/dist/ts/ops/index.d.ts +5 -0
- package/dist/ts/ops/index.d.ts.map +1 -0
- package/dist/ts/ops/index.js +5 -0
- package/dist/ts/ops/index.js.map +1 -0
- package/dist/ts/ops/math_ops.d.ts +96 -0
- package/dist/ts/ops/math_ops.d.ts.map +1 -0
- package/dist/ts/ops/math_ops.js +277 -0
- package/dist/ts/ops/math_ops.js.map +1 -0
- package/dist/ts/ops/nn_ops.d.ts +130 -0
- package/dist/ts/ops/nn_ops.d.ts.map +1 -0
- package/dist/ts/ops/nn_ops.js +340 -0
- package/dist/ts/ops/nn_ops.js.map +1 -0
- package/dist/ts/ops/variable_ops.d.ts +128 -0
- package/dist/ts/ops/variable_ops.d.ts.map +1 -0
- package/dist/ts/ops/variable_ops.js +267 -0
- package/dist/ts/ops/variable_ops.js.map +1 -0
- package/dist/ts/session.d.ts +83 -0
- package/dist/ts/session.d.ts.map +1 -0
- package/dist/ts/session.js +81 -0
- package/dist/ts/session.js.map +1 -0
- package/package.json +63 -0
- package/scripts/install.js +100 -0
- package/scripts/test-install.js +82 -0
- package/scripts/test.js +45 -0
- package/src/native/addon.cc +12 -0
- package/src/native/graph.cc +442 -0
- package/src/native/graph.h +52 -0
- package/src/native/platform_tf.h +8 -0
- package/src/native/session.cc +716 -0
- package/src/native/session.h +92 -0
|
@@ -0,0 +1,99 @@
|
|
|
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 (see below).
|
|
17
|
+
*
|
|
18
|
+
* CPU affinity (reserveCores):
|
|
19
|
+
*
|
|
20
|
+
* reserveCores = R pins TF computation to the LAST (N-R) cores.
|
|
21
|
+
* The FIRST R cores are left free for the event loop, libuv I/O,
|
|
22
|
+
* opencv4nodejs, and other native libs.
|
|
23
|
+
*
|
|
24
|
+
* Without reservation, TF's eigen threads compete with the event loop
|
|
25
|
+
* and other native work for all cores. Under a large model this causes
|
|
26
|
+
* timer jitter, delayed I/O callbacks, and starvation of other addons.
|
|
27
|
+
*
|
|
28
|
+
* Example on an 8-core machine:
|
|
29
|
+
* reserveCores: 2 → cores 0-1: event loop + opencv
|
|
30
|
+
* cores 2-7: TF eigen threadpool
|
|
31
|
+
*
|
|
32
|
+
* The affinity fence is applied in OnRunWork (the libuv thread pool
|
|
33
|
+
* thread) immediately before TF_SessionRun and restored immediately
|
|
34
|
+
* after, so the libuv worker returns to unrestricted scheduling between
|
|
35
|
+
* inference calls.
|
|
36
|
+
*/
|
|
37
|
+
export type ExecutionStrategy = "worker-pool" | "tf-parallel" | "auto";
|
|
38
|
+
export interface PoolOptions {
|
|
39
|
+
modelPath: string;
|
|
40
|
+
inputOp: string;
|
|
41
|
+
outputOps: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Number of CPU cores to reserve for the event loop and other native libs
|
|
44
|
+
* (opencv, sharp, etc.). TF inference is pinned to the remaining cores.
|
|
45
|
+
*
|
|
46
|
+
* Default: 0 (no reservation — TF may use any core).
|
|
47
|
+
*
|
|
48
|
+
* Recommended: 1–2 on a dedicated inference server.
|
|
49
|
+
* Example: reserveCores=2 on an 8-core machine gives TF cores 2-7 and
|
|
50
|
+
* leaves cores 0-1 for the event loop and other work.
|
|
51
|
+
*/
|
|
52
|
+
reserveCores?: number;
|
|
53
|
+
/** Execution strategy. Default: "auto". */
|
|
54
|
+
strategy?: ExecutionStrategy;
|
|
55
|
+
/** Worker thread count (worker-pool). Default: os.availableParallelism(). */
|
|
56
|
+
concurrency?: number;
|
|
57
|
+
/** Input shape for auto probe run. Required when strategy="auto" and
|
|
58
|
+
* model size >= 150MB. */
|
|
59
|
+
probeShape?: number[];
|
|
60
|
+
/** Auto-detection threshold (ms). Default: 20ms. */
|
|
61
|
+
autoThresholdMs?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface PoolResult {
|
|
64
|
+
workerId: number;
|
|
65
|
+
strategy: "worker-pool" | "tf-parallel";
|
|
66
|
+
outputs: {
|
|
67
|
+
dtype: number;
|
|
68
|
+
shape: number[];
|
|
69
|
+
data: Buffer;
|
|
70
|
+
}[];
|
|
71
|
+
inferenceMs: number;
|
|
72
|
+
}
|
|
73
|
+
export declare class InferencePool {
|
|
74
|
+
readonly strategy: "worker-pool" | "tf-parallel";
|
|
75
|
+
readonly reserveCores: number;
|
|
76
|
+
private readonly workerSlots;
|
|
77
|
+
private readonly queue;
|
|
78
|
+
private readonly ctrlSab;
|
|
79
|
+
private tfParallelSess;
|
|
80
|
+
private tfParallelBusy;
|
|
81
|
+
private readonly tfParallelQueue;
|
|
82
|
+
private readonly modelPath;
|
|
83
|
+
private readonly inputOp;
|
|
84
|
+
private readonly outputOps;
|
|
85
|
+
private constructor();
|
|
86
|
+
static create(opts: PoolOptions): Promise<InferencePool>;
|
|
87
|
+
private static createWorkerPool;
|
|
88
|
+
private static createTfParallel;
|
|
89
|
+
infer(inputBuf: Buffer, inputShape: number[], inputDtype?: number): Promise<PoolResult>;
|
|
90
|
+
private inferWorkerPool;
|
|
91
|
+
private dispatchToWorker;
|
|
92
|
+
private inferTfParallel;
|
|
93
|
+
private runTfParallel;
|
|
94
|
+
get busyCount(): number;
|
|
95
|
+
get queueDepth(): number;
|
|
96
|
+
get size(): number;
|
|
97
|
+
destroy(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=inference_pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inference_pool.d.ts","sourceRoot":"","sources":["../../src/ts/inference_pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAoBH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;+BAC2B;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,GAAG,aAAa,CAAC;IACxC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;CACrB;AAuFD,qBAAa,aAAa;IACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO;WA0BM,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;mBAmEzC,gBAAgB;mBAkDhB,gBAAgB;IAmCrC,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,SAAI,GACb,OAAO,CAAC,UAAU,CAAC;IAMtB,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,gBAAgB;IA4CxB,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,aAAa;IAiDrB,IAAI,SAAS,IAAI,MAAM,CAItB;IAED,IAAI,UAAU,IAAI,MAAM,CAIvB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAIK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA6C/B"}
|
|
@@ -0,0 +1,370 @@
|
|
|
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 (see below).
|
|
17
|
+
*
|
|
18
|
+
* CPU affinity (reserveCores):
|
|
19
|
+
*
|
|
20
|
+
* reserveCores = R pins TF computation to the LAST (N-R) cores.
|
|
21
|
+
* The FIRST R cores are left free for the event loop, libuv I/O,
|
|
22
|
+
* opencv4nodejs, and other native libs.
|
|
23
|
+
*
|
|
24
|
+
* Without reservation, TF's eigen threads compete with the event loop
|
|
25
|
+
* and other native work for all cores. Under a large model this causes
|
|
26
|
+
* timer jitter, delayed I/O callbacks, and starvation of other addons.
|
|
27
|
+
*
|
|
28
|
+
* Example on an 8-core machine:
|
|
29
|
+
* reserveCores: 2 → cores 0-1: event loop + opencv
|
|
30
|
+
* cores 2-7: TF eigen threadpool
|
|
31
|
+
*
|
|
32
|
+
* The affinity fence is applied in OnRunWork (the libuv thread pool
|
|
33
|
+
* thread) immediately before TF_SessionRun and restored immediately
|
|
34
|
+
* after, so the libuv worker returns to unrestricted scheduling between
|
|
35
|
+
* inference calls.
|
|
36
|
+
*/
|
|
37
|
+
import { Worker, isMainThread, parentPort, workerData } from "worker_threads";
|
|
38
|
+
import { availableParallelism } from "os";
|
|
39
|
+
import { statSync } from "fs";
|
|
40
|
+
import { fileURLToPath } from "url";
|
|
41
|
+
import { performance } from "perf_hooks";
|
|
42
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
43
|
+
const IDLE = 0;
|
|
44
|
+
const WORK = 1;
|
|
45
|
+
const DONE = 2;
|
|
46
|
+
const SHUTDOWN = 3;
|
|
47
|
+
const CTRL_SLOTS = 4;
|
|
48
|
+
const SIZE_THRESHOLD_BYTES = 150 * 1024 * 1024; // 150 MB
|
|
49
|
+
const DEFAULT_AUTO_THRESHOLD = 20; // ms
|
|
50
|
+
// ─── Worker-side logic ──────────────────────────────────────────────────────
|
|
51
|
+
if (!isMainThread) {
|
|
52
|
+
const { ctrlSab, workerIndex, modelPath, inputOp, outputOps, reserveCores } = workerData;
|
|
53
|
+
const ctrl = new Int32Array(ctrlSab, workerIndex * CTRL_SLOTS * 4, CTRL_SLOTS);
|
|
54
|
+
const { TFSession } = await import("jude-tf");
|
|
55
|
+
const sess = await TFSession.loadFrozenGraph(modelPath);
|
|
56
|
+
// TODO: once @isidorus/cpu native Session is used here, pass reserveCores
|
|
57
|
+
// as a session option so the affinity fence is applied inside OnRunWork.
|
|
58
|
+
// For now we use jude-tf's session which doesn't have affinity support.
|
|
59
|
+
Atomics.store(ctrl, 0, IDLE);
|
|
60
|
+
parentPort.postMessage({ type: "ready" });
|
|
61
|
+
while (true) {
|
|
62
|
+
Atomics.wait(ctrl, 0, IDLE);
|
|
63
|
+
const state = Atomics.load(ctrl, 0);
|
|
64
|
+
if (state === SHUTDOWN) {
|
|
65
|
+
sess.destroy();
|
|
66
|
+
parentPort.postMessage({ type: "shutdown_ack" });
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
if (state === WORK) {
|
|
70
|
+
const msg = await new Promise((resolve) => parentPort.once("message", resolve));
|
|
71
|
+
const { inputData, inputShape, inputDtype } = msg;
|
|
72
|
+
const t0 = performance.now();
|
|
73
|
+
const results = await sess.run({ [inputOp]: inputData }, outputOps);
|
|
74
|
+
const inferenceMs = performance.now() - t0;
|
|
75
|
+
Atomics.store(ctrl, 0, DONE);
|
|
76
|
+
Atomics.notify(ctrl, 0, 1);
|
|
77
|
+
parentPort.postMessage({
|
|
78
|
+
type: "result",
|
|
79
|
+
outputs: outputOps.map((k) => results[k]),
|
|
80
|
+
inferenceMs,
|
|
81
|
+
});
|
|
82
|
+
Atomics.store(ctrl, 0, IDLE);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export class InferencePool {
|
|
87
|
+
strategy;
|
|
88
|
+
reserveCores;
|
|
89
|
+
workerSlots;
|
|
90
|
+
queue;
|
|
91
|
+
ctrlSab;
|
|
92
|
+
tfParallelSess;
|
|
93
|
+
tfParallelBusy;
|
|
94
|
+
tfParallelQueue;
|
|
95
|
+
modelPath;
|
|
96
|
+
inputOp;
|
|
97
|
+
outputOps;
|
|
98
|
+
constructor(params) {
|
|
99
|
+
this.strategy = params.strategy;
|
|
100
|
+
this.reserveCores = params.reserveCores;
|
|
101
|
+
this.workerSlots = params.workerSlots;
|
|
102
|
+
this.queue = params.queue;
|
|
103
|
+
this.ctrlSab = params.ctrlSab;
|
|
104
|
+
this.tfParallelSess = params.tfParallelSess;
|
|
105
|
+
this.tfParallelBusy = false;
|
|
106
|
+
this.tfParallelQueue = [];
|
|
107
|
+
this.modelPath = params.modelPath;
|
|
108
|
+
this.inputOp = params.inputOp;
|
|
109
|
+
this.outputOps = params.outputOps;
|
|
110
|
+
}
|
|
111
|
+
// ── Factory ────────────────────────────────────────────────────────────────
|
|
112
|
+
static async create(opts) {
|
|
113
|
+
const requestedStrategy = opts.strategy ?? "auto";
|
|
114
|
+
const concurrency = opts.concurrency ?? availableParallelism();
|
|
115
|
+
const autoThreshold = opts.autoThresholdMs ?? DEFAULT_AUTO_THRESHOLD;
|
|
116
|
+
const reserveCores = opts.reserveCores ?? 0;
|
|
117
|
+
let resolved;
|
|
118
|
+
if (requestedStrategy === "worker-pool") {
|
|
119
|
+
resolved = "worker-pool";
|
|
120
|
+
}
|
|
121
|
+
else if (requestedStrategy === "tf-parallel") {
|
|
122
|
+
resolved = "tf-parallel";
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// auto
|
|
126
|
+
const modelBytes = statSync(opts.modelPath).size;
|
|
127
|
+
if (modelBytes < SIZE_THRESHOLD_BYTES) {
|
|
128
|
+
resolved = "worker-pool";
|
|
129
|
+
}
|
|
130
|
+
else if (!opts.probeShape) {
|
|
131
|
+
resolved = "tf-parallel";
|
|
132
|
+
process.stderr.write(`[isidorus] auto: ${(modelBytes / 1024 / 1024).toFixed(1)}MB >= ` +
|
|
133
|
+
`threshold, no probeShape → tf-parallel\n`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// Probe with intra=1 (worker-pool config) to measure single-core time.
|
|
137
|
+
const { TFSession } = await import("jude-tf");
|
|
138
|
+
const probeSess = await TFSession.loadFrozenGraph(opts.modelPath);
|
|
139
|
+
const probeInput = Buffer.alloc(opts.probeShape.reduce((a, b) => a * b, 1) * 4);
|
|
140
|
+
await probeSess.runAsync({ [opts.inputOp]: probeInput }, opts.outputOps);
|
|
141
|
+
const t0 = performance.now();
|
|
142
|
+
await probeSess.runAsync({ [opts.inputOp]: probeInput }, opts.outputOps);
|
|
143
|
+
const probeMs = performance.now() - t0;
|
|
144
|
+
probeSess.destroy();
|
|
145
|
+
resolved = probeMs >= autoThreshold ? "tf-parallel" : "worker-pool";
|
|
146
|
+
process.stderr.write(`[isidorus] auto: probe=${probeMs.toFixed(2)}ms ` +
|
|
147
|
+
`threshold=${autoThreshold}ms → ${resolved}\n`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (reserveCores > 0) {
|
|
151
|
+
const hw = availableParallelism();
|
|
152
|
+
const tfCores = Math.max(1, hw - reserveCores);
|
|
153
|
+
process.stderr.write(`[isidorus] CPU affinity: reserving ${reserveCores} core(s) ` +
|
|
154
|
+
`for event loop/other libs, TF gets ${tfCores} core(s)\n`);
|
|
155
|
+
}
|
|
156
|
+
return resolved === "worker-pool"
|
|
157
|
+
? InferencePool.createWorkerPool(opts, concurrency, reserveCores)
|
|
158
|
+
: InferencePool.createTfParallel(opts, reserveCores);
|
|
159
|
+
}
|
|
160
|
+
// ── worker-pool init ───────────────────────────────────────────────────────
|
|
161
|
+
static async createWorkerPool(opts, concurrency, reserveCores) {
|
|
162
|
+
const ctrlSab = new SharedArrayBuffer(concurrency * CTRL_SLOTS * 4);
|
|
163
|
+
const slots = [];
|
|
164
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
165
|
+
for (let i = 0; i < concurrency; i++) {
|
|
166
|
+
const ctrl = new Int32Array(ctrlSab, i * CTRL_SLOTS * 4, CTRL_SLOTS);
|
|
167
|
+
Atomics.store(ctrl, 0, IDLE);
|
|
168
|
+
const worker = new Worker(__filename, {
|
|
169
|
+
workerData: {
|
|
170
|
+
ctrlSab,
|
|
171
|
+
workerIndex: i,
|
|
172
|
+
modelPath: opts.modelPath,
|
|
173
|
+
inputOp: opts.inputOp,
|
|
174
|
+
outputOps: opts.outputOps,
|
|
175
|
+
reserveCores, // passed to worker for future native session
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
await new Promise((resolve, reject) => {
|
|
179
|
+
worker.once("message", (msg) => {
|
|
180
|
+
if (msg.type === "ready")
|
|
181
|
+
resolve();
|
|
182
|
+
else
|
|
183
|
+
reject(new Error(`Unexpected worker init: ${msg.type}`));
|
|
184
|
+
});
|
|
185
|
+
worker.once("error", reject);
|
|
186
|
+
});
|
|
187
|
+
slots.push({ worker, ctrl, busy: false, resolve: null, reject: null });
|
|
188
|
+
}
|
|
189
|
+
return new InferencePool({
|
|
190
|
+
strategy: "worker-pool",
|
|
191
|
+
reserveCores,
|
|
192
|
+
workerSlots: slots,
|
|
193
|
+
queue: [],
|
|
194
|
+
ctrlSab,
|
|
195
|
+
tfParallelSess: null,
|
|
196
|
+
modelPath: opts.modelPath,
|
|
197
|
+
inputOp: opts.inputOp,
|
|
198
|
+
outputOps: opts.outputOps,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// ── tf-parallel init ───────────────────────────────────────────────────────
|
|
202
|
+
static async createTfParallel(opts, reserveCores) {
|
|
203
|
+
const hw = availableParallelism();
|
|
204
|
+
const tfCores = Math.max(1, hw - reserveCores);
|
|
205
|
+
// Once @isidorus/cpu's native Graph+Session is used here, we'll
|
|
206
|
+
// construct the Session with:
|
|
207
|
+
// { strategy: "tf-parallel", reserveCores }
|
|
208
|
+
// and the C++ ConfigProto + affinity fencing take effect.
|
|
209
|
+
// For now we load via jude-tf (which uses its own session).
|
|
210
|
+
const { TFSession } = await import("jude-tf");
|
|
211
|
+
const sess = await TFSession.loadFrozenGraph(opts.modelPath);
|
|
212
|
+
process.stderr.write(`[isidorus] tf-parallel: intra_op=${tfCores} ` +
|
|
213
|
+
`(${reserveCores} core(s) reserved)\n`);
|
|
214
|
+
return new InferencePool({
|
|
215
|
+
strategy: "tf-parallel",
|
|
216
|
+
reserveCores,
|
|
217
|
+
workerSlots: [],
|
|
218
|
+
queue: [],
|
|
219
|
+
ctrlSab: null,
|
|
220
|
+
tfParallelSess: sess,
|
|
221
|
+
modelPath: opts.modelPath,
|
|
222
|
+
inputOp: opts.inputOp,
|
|
223
|
+
outputOps: opts.outputOps,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// ── Inference ──────────────────────────────────────────────────────────────
|
|
227
|
+
infer(inputBuf, inputShape, inputDtype = 1) {
|
|
228
|
+
return this.strategy === "worker-pool"
|
|
229
|
+
? this.inferWorkerPool(inputBuf, inputShape, inputDtype)
|
|
230
|
+
: this.inferTfParallel(inputBuf, inputShape, inputDtype);
|
|
231
|
+
}
|
|
232
|
+
inferWorkerPool(inputBuf, inputShape, inputDtype) {
|
|
233
|
+
return new Promise((resolve, reject) => {
|
|
234
|
+
const slot = this.workerSlots.find((w) => !w.busy);
|
|
235
|
+
if (slot) {
|
|
236
|
+
this.dispatchToWorker(slot, inputBuf, inputShape, inputDtype, resolve, reject);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
this.queue.push({ inputBuf, inputShape, inputDtype, resolve, reject });
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
dispatchToWorker(slot, inputBuf, inputShape, inputDtype, resolve, reject) {
|
|
244
|
+
const workerId = this.workerSlots.indexOf(slot);
|
|
245
|
+
slot.busy = true;
|
|
246
|
+
slot.resolve = resolve;
|
|
247
|
+
slot.reject = reject;
|
|
248
|
+
slot.worker.postMessage({ inputData: inputBuf, inputShape, inputDtype });
|
|
249
|
+
Atomics.store(slot.ctrl, 0, WORK);
|
|
250
|
+
Atomics.notify(slot.ctrl, 0, 1);
|
|
251
|
+
slot.worker.once("message", (msg) => {
|
|
252
|
+
if (msg.type !== "result")
|
|
253
|
+
return;
|
|
254
|
+
slot.busy = false;
|
|
255
|
+
slot.resolve = null;
|
|
256
|
+
slot.reject = null;
|
|
257
|
+
resolve({
|
|
258
|
+
workerId,
|
|
259
|
+
strategy: "worker-pool",
|
|
260
|
+
outputs: msg.outputs,
|
|
261
|
+
inferenceMs: msg.inferenceMs,
|
|
262
|
+
});
|
|
263
|
+
const next = this.queue.shift();
|
|
264
|
+
if (next) {
|
|
265
|
+
this.dispatchToWorker(slot, next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
inferTfParallel(inputBuf, inputShape, inputDtype) {
|
|
270
|
+
return new Promise((resolve, reject) => {
|
|
271
|
+
if (this.tfParallelBusy) {
|
|
272
|
+
this.tfParallelQueue.push({
|
|
273
|
+
inputBuf,
|
|
274
|
+
inputShape,
|
|
275
|
+
inputDtype,
|
|
276
|
+
resolve,
|
|
277
|
+
reject,
|
|
278
|
+
});
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
this.runTfParallel(inputBuf, inputShape, inputDtype, resolve, reject);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
runTfParallel(inputBuf, inputShape, inputDtype, resolve, reject) {
|
|
285
|
+
this.tfParallelBusy = true;
|
|
286
|
+
const t0 = performance.now();
|
|
287
|
+
this.tfParallelSess.runAsync({ [this.inputOp]: inputBuf }, this.outputOps)
|
|
288
|
+
.then((results) => {
|
|
289
|
+
const inferenceMs = performance.now() - t0;
|
|
290
|
+
this.tfParallelBusy = false;
|
|
291
|
+
resolve({
|
|
292
|
+
workerId: 0,
|
|
293
|
+
strategy: "tf-parallel",
|
|
294
|
+
outputs: this.outputOps.map((k) => results[k]),
|
|
295
|
+
inferenceMs,
|
|
296
|
+
});
|
|
297
|
+
const next = this.tfParallelQueue.shift();
|
|
298
|
+
if (next) {
|
|
299
|
+
this.runTfParallel(next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
.catch((err) => {
|
|
303
|
+
this.tfParallelBusy = false;
|
|
304
|
+
reject(err);
|
|
305
|
+
const next = this.tfParallelQueue.shift();
|
|
306
|
+
if (next) {
|
|
307
|
+
this.runTfParallel(next.inputBuf, next.inputShape, next.inputDtype, next.resolve, next.reject);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
// ── Introspection ──────────────────────────────────────────────────────────
|
|
312
|
+
get busyCount() {
|
|
313
|
+
if (this.strategy === "worker-pool")
|
|
314
|
+
return this.workerSlots.filter((w) => w.busy).length;
|
|
315
|
+
return this.tfParallelBusy ? 1 : 0;
|
|
316
|
+
}
|
|
317
|
+
get queueDepth() {
|
|
318
|
+
return this.strategy === "worker-pool"
|
|
319
|
+
? this.queue.length
|
|
320
|
+
: this.tfParallelQueue.length;
|
|
321
|
+
}
|
|
322
|
+
get size() {
|
|
323
|
+
return this.strategy === "worker-pool" ? this.workerSlots.length : 1;
|
|
324
|
+
}
|
|
325
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
326
|
+
async destroy() {
|
|
327
|
+
if (this.strategy === "worker-pool") {
|
|
328
|
+
await Promise.all(this.workerSlots.map((slot) => new Promise((resolve, reject) => {
|
|
329
|
+
const doShutdown = () => {
|
|
330
|
+
slot.worker.once("message", (msg) => {
|
|
331
|
+
if (msg.type === "shutdown_ack")
|
|
332
|
+
resolve();
|
|
333
|
+
});
|
|
334
|
+
Atomics.store(slot.ctrl, 0, SHUTDOWN);
|
|
335
|
+
Atomics.notify(slot.ctrl, 0, 1);
|
|
336
|
+
};
|
|
337
|
+
if (slot.busy) {
|
|
338
|
+
const origRes = slot.resolve;
|
|
339
|
+
const origRej = slot.reject;
|
|
340
|
+
slot.resolve = (r) => {
|
|
341
|
+
origRes?.(r);
|
|
342
|
+
doShutdown();
|
|
343
|
+
};
|
|
344
|
+
slot.reject = (e) => {
|
|
345
|
+
origRej?.(e);
|
|
346
|
+
doShutdown();
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
doShutdown();
|
|
351
|
+
}
|
|
352
|
+
})));
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
if (this.tfParallelBusy) {
|
|
356
|
+
await new Promise((res) => {
|
|
357
|
+
const t = setInterval(() => {
|
|
358
|
+
if (!this.tfParallelBusy) {
|
|
359
|
+
clearInterval(t);
|
|
360
|
+
res();
|
|
361
|
+
}
|
|
362
|
+
}, 1);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
this.tfParallelSess?.destroy();
|
|
366
|
+
this.tfParallelSess = null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=inference_pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inference_pool.js","sourceRoot":"","sources":["../../src/ts/inference_pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,+EAA+E;AAC/E,MAAM,IAAI,GAAG,CAAC,CAAC;AACf,MAAM,IAAI,GAAG,CAAC,CAAC;AACf,MAAM,IAAI,GAAG,CAAC,CAAC;AACf,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,SAAS;AACzD,MAAM,sBAAsB,GAAG,EAAE,CAAC,CAAC,KAAK;AAuCxC,+EAA+E;AAE/E,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,GACzE,UAOC,CAAC;IAEJ,MAAM,IAAI,GAAG,IAAI,UAAU,CACzB,OAAO,EACP,WAAW,GAAG,UAAU,GAAG,CAAC,EAC5B,UAAU,CACX,CAAC;IAEF,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACxD,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IAExE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7B,UAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAE3C,OAAO,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAEpC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,UAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;YAClD,MAAM;QACR,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,GAAG,GAAQ,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7C,UAAW,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CACrC,CAAC;YAEF,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,GAI7C,CAAC;YAEF,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAE3C,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAE3B,UAAW,CAAC,WAAW,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACzC,WAAW;aACZ,CAAC,CAAC;YAEH,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;AACH,CAAC;AAoBD,MAAM,OAAO,aAAa;IACf,QAAQ,CAAgC;IACxC,YAAY,CAAS;IAEb,WAAW,CAAe;IAC1B,KAAK,CAAe;IACpB,OAAO,CAA2B;IAC3C,cAAc,CAAa;IAC3B,cAAc,CAAU;IACf,eAAe,CAAe;IAC9B,SAAS,CAAS;IAClB,OAAO,CAAS;IAChB,SAAS,CAAW;IAErC,YAAoB,MAUnB;QACC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,8EAA8E;IAE9E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAiB;QACnC,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,oBAAoB,EAAE,CAAC;QAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,IAAI,sBAAsB,CAAC;QACrE,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;QAE5C,IAAI,QAAuC,CAAC;QAE5C,IAAI,iBAAiB,KAAK,aAAa,EAAE,CAAC;YACxC,QAAQ,GAAG,aAAa,CAAC;QAC3B,CAAC;aAAM,IAAI,iBAAiB,KAAK,aAAa,EAAE,CAAC;YAC/C,QAAQ,GAAG,aAAa,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,OAAO;YACP,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;YACjD,IAAI,UAAU,GAAG,oBAAoB,EAAE,CAAC;gBACtC,QAAQ,GAAG,aAAa,CAAC;YAC3B,CAAC;iBAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC5B,QAAQ,GAAG,aAAa,CAAC;gBACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oBAAoB,CAAC,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;oBAC/D,0CAA0C,CAC7C,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,uEAAuE;gBACvE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC9C,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAClE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAC/C,CAAC;gBAEF,MAAM,SAAS,CAAC,QAAQ,CACtB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAC9B,IAAI,CAAC,SAAS,CACf,CAAC;gBACF,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBAC7B,MAAM,SAAS,CAAC,QAAQ,CACtB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAC9B,IAAI,CAAC,SAAS,CACf,CAAC;gBACF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBACvC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAEpB,QAAQ,GAAG,OAAO,IAAI,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;gBACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;oBAC/C,aAAa,aAAa,QAAQ,QAAQ,IAAI,CACjD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC;YAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sCAAsC,YAAY,WAAW;gBAC3D,sCAAsC,OAAO,YAAY,CAC5D,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,KAAK,aAAa;YAC/B,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC;YACjE,CAAC,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzD,CAAC;IAED,8EAA8E;IAEtE,MAAM,CAAC,KAAK,CAAC,gBAAgB,CACnC,IAAiB,EACjB,WAAmB,EACnB,YAAoB;QAEpB,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,WAAW,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC;QACpE,MAAM,KAAK,GAAiB,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,UAAU,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;YACrE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAE7B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE;gBACpC,UAAU,EAAE;oBACV,OAAO;oBACP,WAAW,EAAE,CAAC;oBACd,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,YAAY,EAAE,6CAA6C;iBAC5D;aACF,CAAC,CAAC;YAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAQ,EAAE,EAAE;oBAClC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;wBAAE,OAAO,EAAE,CAAC;;wBAC/B,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChE,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,OAAO,IAAI,aAAa,CAAC;YACvB,QAAQ,EAAE,aAAa;YACvB,YAAY;YACZ,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,EAAE;YACT,OAAO;YACP,cAAc,EAAE,IAAI;YACpB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAEtE,MAAM,CAAC,KAAK,CAAC,gBAAgB,CACnC,IAAiB,EACjB,YAAoB;QAEpB,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC;QAE/C,gEAAgE;QAChE,8BAA8B;QAC9B,8CAA8C;QAC9C,0DAA0D;QAC1D,4DAA4D;QAC5D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oCAAoC,OAAO,GAAG;YAC5C,IAAI,YAAY,sBAAsB,CACzC,CAAC;QAEF,OAAO,IAAI,aAAa,CAAC;YACvB,QAAQ,EAAE,aAAa;YACvB,YAAY;YACZ,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,IAAI;YACb,cAAc,EAAE,IAAI;YACpB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAE9E,KAAK,CACH,QAAgB,EAChB,UAAoB,EACpB,UAAU,GAAG,CAAC;QAEd,OAAO,IAAI,CAAC,QAAQ,KAAK,aAAa;YACpC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC;YACxD,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;IAEO,eAAe,CACrB,QAAgB,EAChB,UAAoB,EACpB,UAAkB;QAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACnD,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,CACnB,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,UAAU,EACV,OAAO,EACP,MAAM,CACP,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CACtB,IAAgB,EAChB,QAAgB,EAChB,UAAoB,EACpB,UAAkB,EAClB,OAAgC,EAChC,MAA0B;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEhC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAQ,EAAE,EAAE;YACvC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAClC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YAEnB,OAAO,CAAC;gBACN,QAAQ;gBACR,QAAQ,EAAE,aAAa;gBACvB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,WAAW,EAAE,GAAG,CAAC,WAAW;aAC7B,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,CACnB,IAAI,EACJ,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,CACZ,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CACrB,QAAgB,EAChB,UAAoB,EACpB,UAAkB;QAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;oBACxB,QAAQ;oBACR,UAAU;oBACV,UAAU;oBACV,OAAO;oBACP,MAAM;iBACP,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CACnB,QAAgB,EAChB,UAAoB,EACpB,UAAkB,EAClB,OAAgC,EAChC,MAA0B;QAE1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC,cAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC;aACxE,IAAI,CAAC,CAAC,OAAY,EAAE,EAAE;YACrB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAC3C,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,OAAO,CAAC;gBACN,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,aAAa;gBACvB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACtD,WAAW;aACZ,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,aAAa,CAChB,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,CACZ,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;YACpB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,aAAa,CAChB,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,CACZ,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;IAED,8EAA8E;IAE9E,IAAI,SAAS;QACX,IAAI,IAAI,CAAC,QAAQ,KAAK,aAAa;YACjC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACvD,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,KAAK,aAAa;YACpC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YACnB,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;IAClC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,8EAA8E;IAE9E,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YACpC,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,WAAW,CAAC,GAAG,CAClB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACpC,MAAM,UAAU,GAAG,GAAG,EAAE;oBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAQ,EAAE,EAAE;wBACvC,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;4BAAE,OAAO,EAAE,CAAC;oBAC7C,CAAC,CAAC,CAAC;oBACH,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;oBACtC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClC,CAAC,CAAC;gBACF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;oBAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC5B,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE;wBACnB,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;wBACb,UAAU,EAAE,CAAC;oBACf,CAAC,CAAC;oBACF,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE;wBAClB,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;wBACb,UAAU,EAAE,CAAC;oBACf,CAAC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,UAAU,EAAE,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CACL,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,IAAI,OAAO,CAAO,CAAC,GAAG,EAAE,EAAE;oBAC9B,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE;wBACzB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;4BACzB,aAAa,CAAC,CAAC,CAAC,CAAC;4BACjB,GAAG,EAAE,CAAC;wBACR,CAAC;oBACH,CAAC,EAAE,CAAC,CAAC,CAAC;gBACR,CAAC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* install-libtensorflow.ts
|
|
3
|
+
*
|
|
4
|
+
* Alpha-phase libtensorflow resolver.
|
|
5
|
+
*
|
|
6
|
+
* Resolution order:
|
|
7
|
+
* 1. LIBTENSORFLOW_PATH env var
|
|
8
|
+
* 2. Hardcoded platform default paths
|
|
9
|
+
* 3. Interactive prompt — install automatically or print instructions
|
|
10
|
+
*
|
|
11
|
+
* Called once at package load time (from index.ts) before the native
|
|
12
|
+
* addon is required. If resolution fails the process exits with a
|
|
13
|
+
* clear diagnostic rather than a cryptic "cannot find module" error.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the libtensorflow path.
|
|
17
|
+
* Returns { tfPath, source } where source explains how it was found.
|
|
18
|
+
* Returns null if not found.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveTfPath(): {
|
|
21
|
+
tfPath: string;
|
|
22
|
+
source: string;
|
|
23
|
+
} | null;
|
|
24
|
+
/**
|
|
25
|
+
* Ensure libtensorflow is available. Called once at package load time.
|
|
26
|
+
*
|
|
27
|
+
* If the library is found, returns the resolved path and sets
|
|
28
|
+
* LIBTENSORFLOW_PATH in the environment so the native addon can find it.
|
|
29
|
+
*
|
|
30
|
+
* If not found, prompts the user to install automatically or prints
|
|
31
|
+
* manual installation instructions, then exits.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ensureTf(): Promise<string>;
|
|
34
|
+
//# sourceMappingURL=install-libtensorflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-libtensorflow.d.ts","sourceRoot":"","sources":["../../src/ts/install-libtensorflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAwGH;;;;GAIG;AACH,wBAAgB,aAAa,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6BzE;AAkFD;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CA4EhD"}
|