@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
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @isidorus/cpu
2
+
3
+ High-performance TensorFlow CPU backend for Isidorus, enabling graph construction, training, and inference in Node.js environments.
4
+
5
+ ## Features
6
+
7
+ - **Native Addon**: Uses a C++ native addon to interface directly with `libtensorflow`.
8
+ - **Automatic Setup**: Automatically handles the download and installation of required TensorFlow libraries.
9
+ - **Inference Pool**: Efficiently manage concurrent execution strategies (worker-pool vs tf-parallel).
10
+ - **Ops Library**: Rich set of operations including Math, Array, NN, and Variable ops.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @isidorus/cpu
16
+ ```
17
+
18
+ _Note: The install script will automatically attempt to resolve and download `libtensorflow` if it is missing._
19
+
20
+ ## Quick Start
21
+
22
+ ```typescript
23
+ import { graph, session, ops, DType } from "@isidorus/cpu";
24
+
25
+ const g = graph();
26
+ const x = ops.placeholder(g, "x", [null, 784], DType.FLOAT32);
27
+
28
+ const sess = session(g, { strategy: "tf-parallel", reserveCores: 2 });
29
+ ```
30
+
31
+ ## Development
32
+
33
+ ### Native Builds
34
+
35
+ To rebuild the native C++ addon:
36
+
37
+ ```bash
38
+ npm run build:native
39
+ ```
40
+
41
+ ### Prebuilds
42
+
43
+ To generate prebuilt binaries for multiple Node.js versions:
44
+
45
+ ```bash
46
+ npm run prebuildify
47
+ ```
package/binding.gyp ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "jude-tf",
5
+ "sources": [
6
+ "src/native/addon.cc",
7
+ "src/native/graph.cc",
8
+ "src/native/session.cc"
9
+ ],
10
+ "include_dirs": [
11
+ "<!@(node -p \"require('node-addon-api').include\")",
12
+ "<!@(echo $LIBTENSORFLOW_PATH || echo /usr/local || true)/include"
13
+ ],
14
+ "dependencies": [
15
+ "<!(node -p \"require('node-addon-api').gyp\")"
16
+ ],
17
+ "libraries": [
18
+ "-ltensorflow"
19
+ ],
20
+ "library_dirs": [
21
+ "<!@(echo $LIBTENSORFLOW_PATH || echo /usr/local || true)/lib"
22
+ ],
23
+ "sources!": [
24
+ ],
25
+ "sources+": [
26
+ ],
27
+ "defines": [
28
+ "NAPI_VERSION=8",
29
+ "NAPI_DISABLE_CPP_EXCEPTIONS"
30
+ ],
31
+ "cflags!": [ "-fno-exceptions" ],
32
+ "cflags_cc!": [ "-fno-exceptions" ],
33
+ "cflags": [ "-O3", "-ffast-math" ],
34
+ "cflags_cc": [ "-std=c++17", "-O3", "-ffast-math" ],
35
+ "msvs_settings": {
36
+ "VCCLCompilerTool": {
37
+ "ExceptionHandling": 1,
38
+ "AdditionalOptions": [ "/std:c++17", "/O2", "/fp:fast", "/arch:AVX2" ],
39
+ "Optimization": 3,
40
+ "FavorSizeOrSpeed": 1,
41
+ "InlineFunctionExpansion": 2
42
+ }
43
+ },
44
+ "xcode_settings": {
45
+ "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
46
+ "CLANG_CXX_LIBRARY": "libc++",
47
+ "MACOSX_DEPLOYMENT_TARGET": "10.15",
48
+ "OTHER_CPLUSPLUSFLAGS": [ "-std=c++17", "-stdlib=libc++", "-O3", "-ffast-math"],
49
+ "GCC_OPTIMIZATION_LEVEL": "3"
50
+ },
51
+ "conditions": [
52
+ # Condition for Windows
53
+ ["OS=='win'", {
54
+ "defines": [ "_HAS_EXCEPTIONS=1", "__AVX2__=1", "__AVX__=1", "__SSE3__=1" ],
55
+ "include_dirs": [
56
+ "C:/libtensorflow/include"
57
+ ],
58
+ "library_dirs": [
59
+ "C:/libtensorflow/lib"
60
+ ]
61
+ }],
62
+ # Condition for x64 architecture (Linux/macOS)
63
+ ['target_arch=="x64"', {
64
+ "cflags+": [ "-msse3", "-mavx", "-mavx2" ],
65
+ "cflags_cc+": [ "-msse3", "-mavx", "-mavx2" ],
66
+ 'xcode_settings': {
67
+ 'OTHER_CPLUSPLUSFLAGS+': [ '-msse3', '-mavx', '-mavx2' ]
68
+ }
69
+ }],
70
+ # Condition for ia32 architecture (Linux/macOS - if you support 32-bit x86)
71
+ ['target_arch=="ia32"', {
72
+ "cflags+": [ "-msse3", "-mavx", "-mavx2" ], # Or adjust based on 32-bit support
73
+ "cflags_cc+": [ "-msse3", "-mavx", "-mavx2" ],
74
+ 'xcode_settings': {
75
+ 'OTHER_CPLUSPLUSFLAGS+': [ '-msse3', '-mavx', '-mavx2' ]
76
+ }
77
+ }],
78
+ # Condition for arm64 architecture (Android, iOS, M1/M2 Macs, etc.)
79
+ ['target_arch=="arm64"', {
80
+ # ARMv8-a baseline: NEON + FP support (compatible with all ARMv8 CPUs)
81
+ "cflags+": [ "-march=armv8-a+fp+simd" ],
82
+ "cflags_cc+": [ "-march=armv8-a+fp+simd" ],
83
+ 'xcode_settings': {
84
+ 'OTHER_CPLUSPLUSFLAGS+': [ '-march=armv8-a+fp+simd' ]
85
+ }
86
+ # Optional: Upgrade to ARMv8.2-a for newer CPUs (Tensor G4, Apple M2+, Graviton 3+)
87
+ # Enables FP16 arithmetic and additional optimizations
88
+ # Uncomment the lines below to enable ARMv8.2-a:
89
+ # "cflags+": [ "-march=armv8.2-a+fp16" ],
90
+ # "cflags_cc+": [ "-march=armv8.2-a+fp16" ],
91
+ # 'xcode_settings': {
92
+ # 'OTHER_CPLUSPLUSFLAGS+': [ '-march=armv8.2-a+fp16' ]
93
+ # }
94
+ }],
95
+ # Condition for 32-bit ARM (older Android devices)
96
+ ['target_arch=="arm"', {
97
+ "cflags+": [ "-mfpu=neon", "-mfloat-abi=hard" ], # 32-bit ARM NEON
98
+ "cflags_cc+": [ "-mfpu=neon", "-mfloat-abi=hard" ],
99
+ }]
100
+ ]
101
+ }
102
+ ]
103
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * _native.ts — internal addon reference.
3
+ *
4
+ * Holds the loaded native addon so internal modules (inference-pool, etc.)
5
+ * can access it without importing from the package's own entry point
6
+ * (@isidorus/cpu), which would be a circular dependency.
7
+ *
8
+ * index.ts calls setAddon() once after node-gyp-build resolves.
9
+ * Any internal module that needs Graph or Session construction calls getAddon().
10
+ */
11
+ export declare function setAddon(addon: any): void;
12
+ export declare function getAddon(): any;
13
+ //# sourceMappingURL=_native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_native.d.ts","sourceRoot":"","sources":["../../src/ts/_native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAEzC;AAED,wBAAgB,QAAQ,IAAI,GAAG,CAQ9B"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * _native.ts — internal addon reference.
3
+ *
4
+ * Holds the loaded native addon so internal modules (inference-pool, etc.)
5
+ * can access it without importing from the package's own entry point
6
+ * (@isidorus/cpu), which would be a circular dependency.
7
+ *
8
+ * index.ts calls setAddon() once after node-gyp-build resolves.
9
+ * Any internal module that needs Graph or Session construction calls getAddon().
10
+ */
11
+ let _addon = null;
12
+ export function setAddon(addon) {
13
+ _addon = addon;
14
+ }
15
+ export function getAddon() {
16
+ if (!_addon) {
17
+ throw new Error("[isidorus] Native addon not initialised. " +
18
+ "Ensure @isidorus/cpu is imported before calling InferencePool.create().");
19
+ }
20
+ return _addon;
21
+ }
22
+ //# sourceMappingURL=_native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_native.js","sourceRoot":"","sources":["../../src/ts/_native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,IAAI,MAAM,GAAQ,IAAI,CAAC;AAEvB,MAAM,UAAU,QAAQ,CAAC,KAAU;IACjC,MAAM,GAAG,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,2CAA2C;YACzC,yEAAyE,CAC5E,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,91 @@
1
+ import type { Tensor } from "@isidorus/core";
2
+ import { DType } from "@isidorus/core";
3
+ export type AttrValue = {
4
+ kind: "int";
5
+ value: number;
6
+ } | {
7
+ kind: "float";
8
+ value: number;
9
+ } | {
10
+ kind: "bool";
11
+ value: boolean;
12
+ } | {
13
+ kind: "type";
14
+ value: DType;
15
+ } | {
16
+ kind: "shape";
17
+ value: number[];
18
+ } | {
19
+ kind: "list_type";
20
+ value: DType[];
21
+ } | {
22
+ kind: "list_int";
23
+ value: number[];
24
+ } | {
25
+ kind: "tensor";
26
+ value: InlineTensor;
27
+ };
28
+ export interface InlineTensor {
29
+ dtype: DType;
30
+ shape: number[];
31
+ data: Buffer;
32
+ }
33
+ export type TFOutput = {
34
+ opName: string;
35
+ index: number;
36
+ };
37
+ /**
38
+ * Graph — builds a TensorFlow graph via the C API.
39
+ *
40
+ * This is the ground-level primitive. Every operation (placeholder, variable,
41
+ * matmul, relu, …) adds one or more ops to this graph. Symbolic Tensors
42
+ * reference op outputs but hold no data until a Session executes the graph.
43
+ *
44
+ * @example
45
+ * const g = new Graph();
46
+ * const x = g.placeholder("x", [null, 784], DType.FLOAT32);
47
+ * const w = g.variable("w", [784, 128], DType.FLOAT32);
48
+ * const y = g.matmul(x, g.readVariable(w));
49
+ */
50
+ export declare class Graph {
51
+ /** @internal */
52
+ readonly _native: any;
53
+ constructor(native: any);
54
+ /**
55
+ * Add a raw op to the graph.
56
+ *
57
+ * @param type TF op type string, e.g. "MatMul", "Placeholder"
58
+ * @param inputs Output references from prior ops
59
+ * @param attrs Op attributes
60
+ * @param name Optional explicit op name (auto-generated if omitted)
61
+ * @returns Array of output Tensors (one per op output)
62
+ */
63
+ addOp(type: string, inputs: TFOutput[], attrs?: Record<string, AttrValue>, name?: string): Tensor[];
64
+ /** Whether an op with the given name exists in this graph. */
65
+ hasOp(name: string): boolean;
66
+ /** Total number of ops in the graph. */
67
+ get numOps(): number;
68
+ /**
69
+ * Serialise the graph to a binary GraphDef proto.
70
+ * Useful for saving, inspecting with Netron, or freezing.
71
+ */
72
+ toGraphDef(): Buffer;
73
+ /**
74
+ * importGraphDef — deserialise a binary GraphDef proto into this graph.
75
+ *
76
+ * Used to load a frozen .pb model so it can be executed via the native
77
+ * Session (which applies ConfigProto thread config and CPU affinity).
78
+ * The graph must be empty before calling this.
79
+ *
80
+ * @param buffer Raw bytes of a frozen GraphDef proto (.pb file contents)
81
+ *
82
+ * @example
83
+ * import { readFileSync } from "fs";
84
+ * const g = graph();
85
+ * g.importGraphDef(readFileSync("model.pb"));
86
+ * const sess = session(g, { strategy: "tf-parallel", reserveCores: 2 });
87
+ */
88
+ importGraphDef(buffer: Buffer): void;
89
+ getOp(name: string, index?: number): Tensor | null;
90
+ }
91
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/ts/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAA2B,MAAM,gBAAgB,CAAC;AAGhE,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;;;;;;;;;;GAYG;AACH,qBAAa,KAAK;IAChB,gBAAgB;IAChB,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;gBAEV,MAAM,EAAE,GAAG;IAIvB;;;;;;;;OAQG;IACH,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,EAAE,EAClB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAM,EACrC,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,EAAE;IAkCX,8DAA8D;IAC9D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI5B,wCAAwC;IACxC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKpC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,GAAG,IAAI;CAW9C"}
@@ -0,0 +1,95 @@
1
+ import { makeTensor, ShapeFromTF } from "@isidorus/core";
2
+ /**
3
+ * Graph — builds a TensorFlow graph via the C API.
4
+ *
5
+ * This is the ground-level primitive. Every operation (placeholder, variable,
6
+ * matmul, relu, …) adds one or more ops to this graph. Symbolic Tensors
7
+ * reference op outputs but hold no data until a Session executes the graph.
8
+ *
9
+ * @example
10
+ * const g = new Graph();
11
+ * const x = g.placeholder("x", [null, 784], DType.FLOAT32);
12
+ * const w = g.variable("w", [784, 128], DType.FLOAT32);
13
+ * const y = g.matmul(x, g.readVariable(w));
14
+ */
15
+ export class Graph {
16
+ /** @internal */
17
+ _native;
18
+ constructor(native) {
19
+ this._native = native;
20
+ }
21
+ /**
22
+ * Add a raw op to the graph.
23
+ *
24
+ * @param type TF op type string, e.g. "MatMul", "Placeholder"
25
+ * @param inputs Output references from prior ops
26
+ * @param attrs Op attributes
27
+ * @param name Optional explicit op name (auto-generated if omitted)
28
+ * @returns Array of output Tensors (one per op output)
29
+ */
30
+ addOp(type, inputs, attrs = {}, name) {
31
+ const nativeAttrs = {};
32
+ for (const [k, v] of Object.entries(attrs)) {
33
+ if (v.kind === "list_type") {
34
+ nativeAttrs[k] = { kind: "list_type", value: v.value.map(Number) };
35
+ }
36
+ else if (v.kind === "type") {
37
+ nativeAttrs[k] = { kind: "type", value: Number(v.value) };
38
+ }
39
+ else {
40
+ nativeAttrs[k] = v;
41
+ }
42
+ }
43
+ const result = this._native.addOp(type, inputs, nativeAttrs, name);
44
+ const { opName, numOutputs } = result;
45
+ const tensors = [];
46
+ for (let i = 0; i < numOutputs; i++) {
47
+ const tfDtype = this._native.opOutputType(opName, i);
48
+ const tfShape = this._native.opOutputShape(opName, i);
49
+ tensors.push(makeTensor(opName, i, tfDtype != null ? tfDtype : null, tfShape != null ? ShapeFromTF(tfShape) : null));
50
+ }
51
+ return tensors;
52
+ }
53
+ /** Whether an op with the given name exists in this graph. */
54
+ hasOp(name) {
55
+ return this._native.hasOp(name);
56
+ }
57
+ /** Total number of ops in the graph. */
58
+ get numOps() {
59
+ return this._native.numOps();
60
+ }
61
+ /**
62
+ * Serialise the graph to a binary GraphDef proto.
63
+ * Useful for saving, inspecting with Netron, or freezing.
64
+ */
65
+ toGraphDef() {
66
+ return this._native.toGraphDef();
67
+ }
68
+ /**
69
+ * importGraphDef — deserialise a binary GraphDef proto into this graph.
70
+ *
71
+ * Used to load a frozen .pb model so it can be executed via the native
72
+ * Session (which applies ConfigProto thread config and CPU affinity).
73
+ * The graph must be empty before calling this.
74
+ *
75
+ * @param buffer Raw bytes of a frozen GraphDef proto (.pb file contents)
76
+ *
77
+ * @example
78
+ * import { readFileSync } from "fs";
79
+ * const g = graph();
80
+ * g.importGraphDef(readFileSync("model.pb"));
81
+ * const sess = session(g, { strategy: "tf-parallel", reserveCores: 2 });
82
+ */
83
+ importGraphDef(buffer) {
84
+ this._native.importGraphDef(buffer);
85
+ }
86
+ // graph.ts
87
+ getOp(name, index = 0) {
88
+ if (!this._native.hasOp(name))
89
+ return null;
90
+ const tfDtype = this._native.opOutputType(name, index);
91
+ const tfShape = this._native.opOutputShape(name, index);
92
+ return makeTensor(name, index, tfDtype != null ? tfDtype : null, tfShape != null ? ShapeFromTF(tfShape) : null);
93
+ }
94
+ }
95
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/ts/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @isidorus/cpu entry point.
3
+ *
4
+ * Resolves libtensorflow before loading the native addon, so users
5
+ * get a clear message and an install prompt rather than a cryptic
6
+ * "cannot find module" or DLL load error.
7
+ */
8
+ export type { Tensor, Shape } from "@isidorus/core";
9
+ export { DType, dtypeItemSize, dtypeName, makeTensor, tensorId, } from "@isidorus/core";
10
+ export type { AttrValue, InlineTensor, TFOutput } from "./graph.js";
11
+ export { Graph } from "./graph.js";
12
+ export type { FeedValue, TensorValue } from "./session.js";
13
+ export { Session } from "./session.js";
14
+ import { Graph } from "./graph.js";
15
+ import { Session } from "./session.js";
16
+ /**
17
+ * Create a new empty Graph.
18
+ *
19
+ * @example
20
+ * const g = graph();
21
+ * const x = ops.placeholder(g, "x", [null, 784], DType.FLOAT32);
22
+ */
23
+ export declare function graph(): Graph;
24
+ /**
25
+ * Create a Session backed by the given Graph.
26
+ *
27
+ * @param g The graph to execute.
28
+ * @param options Thread and affinity configuration:
29
+ * strategy?: "worker-pool" | "tf-parallel"
30
+ * intraOpThreads?: number (explicit override)
31
+ * interOpThreads?: number
32
+ * reserveCores?: number (reserve N cores for event loop / other libs)
33
+ *
34
+ * @example
35
+ * // Leave 2 cores for the event loop and opencv — TF gets the rest
36
+ * const sess = session(g, { strategy: "tf-parallel", reserveCores: 2 });
37
+ */
38
+ export declare function session(g: Graph, options?: {
39
+ strategy?: "worker-pool" | "tf-parallel";
40
+ intraOpThreads?: number;
41
+ interOpThreads?: number;
42
+ reserveCores?: number;
43
+ }): Session;
44
+ export * as ops from "./ops/index.js";
45
+ export type { PoolOptions, PoolResult, ExecutionStrategy, } from "./inference-pool.js";
46
+ export { InferencePool } from "./inference-pool.js";
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,KAAK,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,KAAK,IAAI,KAAK,CAE7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CACrB,CAAC,EAAE,KAAK,EACR,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,aAAa,GAAG,aAAa,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,OAAO,CAET;AAGD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAGtC,YAAY,EACV,WAAW,EACX,UAAU,EACV,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @isidorus/cpu entry point.
3
+ *
4
+ * Resolves libtensorflow before loading the native addon, so users
5
+ * get a clear message and an install prompt rather than a cryptic
6
+ * "cannot find module" or DLL load error.
7
+ */
8
+ import { ensureTf } from "./install-libtensorflow.js";
9
+ import nodeGypBuild from "node-gyp-build";
10
+ import { fileURLToPath } from "url";
11
+ import { dirname, join } from "path";
12
+ // ── Ensure libtensorflow is present before touching the native addon ─────────
13
+ // This is the only await at module top level — it resolves synchronously
14
+ // on the fast path (library already present) and only blocks for the
15
+ // install prompt if the library is genuinely missing.
16
+ await ensureTf();
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+ const addon = nodeGypBuild(join(__dirname, "..", ".."));
20
+ import { setAddon } from "./_native.js";
21
+ setAddon(addon);
22
+ export { DType, dtypeItemSize, dtypeName, makeTensor, tensorId, } from "@isidorus/core";
23
+ export { Graph } from "./graph.js";
24
+ export { Session } from "./session.js";
25
+ // ── Factory functions ─────────────────────────────────────────────────────────
26
+ import { Graph } from "./graph.js";
27
+ import { Session } from "./session.js";
28
+ /**
29
+ * Create a new empty Graph.
30
+ *
31
+ * @example
32
+ * const g = graph();
33
+ * const x = ops.placeholder(g, "x", [null, 784], DType.FLOAT32);
34
+ */
35
+ export function graph() {
36
+ return new Graph(new addon.Graph());
37
+ }
38
+ /**
39
+ * Create a Session backed by the given Graph.
40
+ *
41
+ * @param g The graph to execute.
42
+ * @param options Thread and affinity configuration:
43
+ * strategy?: "worker-pool" | "tf-parallel"
44
+ * intraOpThreads?: number (explicit override)
45
+ * interOpThreads?: number
46
+ * reserveCores?: number (reserve N cores for event loop / other libs)
47
+ *
48
+ * @example
49
+ * // Leave 2 cores for the event loop and opencv — TF gets the rest
50
+ * const sess = session(g, { strategy: "tf-parallel", reserveCores: 2 });
51
+ */
52
+ export function session(g, options) {
53
+ return new Session(new addon.Session(g._native, options));
54
+ }
55
+ // ── Ops namespace ─────────────────────────────────────────────────────────────
56
+ export * as ops from "./ops/index.js";
57
+ export { InferencePool } from "./inference-pool.js";
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,gFAAgF;AAChF,yEAAyE;AACzE,qEAAqE;AACrE,sDAAsD;AACtD,MAAM,QAAQ,EAAE,CAAC;AAEjB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAQ,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAIhB,OAAO,EACL,KAAK,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iFAAiF;AAEjF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,OAAO,CACrB,CAAQ,EACR,OAKC;IAED,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,iFAAiF;AACjF,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAQtC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,84 @@
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
+ export type ExecutionStrategy = "worker-pool" | "tf-parallel" | "auto";
27
+ export interface PoolOptions {
28
+ modelPath: string;
29
+ inputOp?: string;
30
+ outputOps?: string[];
31
+ /**
32
+ * Reserve the first R cores for the event loop and other native libs.
33
+ * TF inference is pinned to the last (N-R) cores via OS affinity.
34
+ * Default: 0 (no reservation).
35
+ */
36
+ reserveCores?: number;
37
+ strategy?: ExecutionStrategy;
38
+ /** Worker thread count (worker-pool only). Default: os.availableParallelism(). */
39
+ concurrency?: number;
40
+ /** Input shape for auto probe. Required when model >= 150 MB. */
41
+ probeShape?: number[];
42
+ /** Crossover threshold for auto strategy (ms). Default: 20. */
43
+ autoThresholdMs?: number;
44
+ }
45
+ export interface PoolResult {
46
+ workerId: number;
47
+ strategy: "worker-pool" | "tf-parallel";
48
+ outputs: {
49
+ dtype: number;
50
+ shape: number[];
51
+ data: Buffer;
52
+ }[];
53
+ inferenceMs: number;
54
+ }
55
+ export declare class InferencePool {
56
+ readonly strategy: "worker-pool" | "tf-parallel";
57
+ readonly reserveCores: number;
58
+ private readonly workerSlots;
59
+ private readonly queue;
60
+ private readonly ctrlSab;
61
+ private tfParallelGraph;
62
+ private tfParallelSess;
63
+ private tfParallelBusy;
64
+ private readonly tfParallelQueue;
65
+ private readonly modelPath;
66
+ private readonly inputOp;
67
+ private readonly outputOps;
68
+ private constructor();
69
+ static create(opts: PoolOptions): Promise<InferencePool>;
70
+ private static createWorkerPool;
71
+ private static createTfParallel;
72
+ infer(inputBuf: Buffer, inputShape: number[], inputDtype?: number): Promise<PoolResult>;
73
+ private inferWorkerPool;
74
+ private dispatchToWorker;
75
+ /** Settle a worker slot's in-flight promise and drain the queue. */
76
+ private settleSlot;
77
+ private inferTfParallel;
78
+ private runTfParallel;
79
+ get busyCount(): number;
80
+ get queueDepth(): number;
81
+ get size(): number;
82
+ destroy(): Promise<void>;
83
+ }
84
+ //# 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;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAqBH,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,+DAA+D;IAC/D,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;AAiLD,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;IAOnD,OAAO,CAAC,eAAe,CAAe;IACtC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAE/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO;WA4BM,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;mBAmFzC,gBAAgB;mBAyEhB,gBAAgB;IAmErC,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;IAgExB,oEAAoE;IACpE,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,aAAa;IA8IrB,IAAI,SAAS,IAAI,MAAM,CAItB;IAED,IAAI,UAAU,IAAI,MAAM,CAIvB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAIK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAkD/B"}