numbl 0.1.7 → 0.2.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 (91) hide show
  1. package/binding.gyp +53 -2
  2. package/dist-cli/cli.js +35560 -23939
  3. package/dist-lib/lib.js +42463 -31995
  4. package/dist-lib/numbl-core/executeCode.d.ts +20 -0
  5. package/dist-lib/numbl-core/helpers/reduction-helpers.d.ts +7 -2
  6. package/dist-lib/numbl-core/interpreter/builtins/datetime.d.ts +39 -0
  7. package/dist-lib/numbl-core/interpreter/builtins/index.d.ts +1 -0
  8. package/dist-lib/numbl-core/interpreter/builtins/time-system.d.ts +1 -0
  9. package/dist-lib/numbl-core/interpreter/builtins/types.d.ts +96 -5
  10. package/dist-lib/numbl-core/interpreter/interpreter.d.ts +37 -3
  11. package/dist-lib/numbl-core/interpreter/types.d.ts +1 -1
  12. package/dist-lib/numbl-core/jit/c/abi.d.ts +90 -0
  13. package/dist-lib/numbl-core/jit/c/assemble.d.ts +56 -0
  14. package/dist-lib/numbl-core/jit/c/classify.d.ts +70 -0
  15. package/dist-lib/numbl-core/jit/c/compile.d.ts +37 -0
  16. package/dist-lib/numbl-core/jit/c/context.d.ts +152 -0
  17. package/dist-lib/numbl-core/jit/c/emit/assign.d.ts +20 -0
  18. package/dist-lib/numbl-core/jit/c/emit/complexScalar.d.ts +18 -0
  19. package/dist-lib/numbl-core/jit/c/emit/fused.d.ts +42 -0
  20. package/dist-lib/numbl-core/jit/c/emit/helpers.d.ts +40 -0
  21. package/dist-lib/numbl-core/jit/c/emit/index.d.ts +14 -0
  22. package/dist-lib/numbl-core/jit/c/emit/scalar.d.ts +23 -0
  23. package/dist-lib/numbl-core/jit/c/emit/stmt.d.ts +25 -0
  24. package/dist-lib/numbl-core/jit/c/emit/tensor.d.ts +127 -0
  25. package/dist-lib/numbl-core/jit/c/emit/userCall.d.ts +58 -0
  26. package/dist-lib/numbl-core/jit/c/epilogue.d.ts +26 -0
  27. package/dist-lib/numbl-core/jit/c/feasibility.d.ts +44 -0
  28. package/dist-lib/numbl-core/jit/c/hybrid.d.ts +42 -0
  29. package/dist-lib/numbl-core/jit/c/install.d.ts +15 -0
  30. package/dist-lib/numbl-core/jit/c/parityError.d.ts +26 -0
  31. package/dist-lib/numbl-core/jit/c/prelude.d.ts +37 -0
  32. package/dist-lib/numbl-core/jit/c/registry.d.ts +51 -0
  33. package/dist-lib/numbl-core/jit/c/visit.d.ts +63 -0
  34. package/dist-lib/numbl-core/jit/e1/install.d.ts +13 -0
  35. package/dist-lib/numbl-core/jit/e1/kernelEmit.d.ts +54 -0
  36. package/dist-lib/numbl-core/jit/e1/openmpFlag.d.ts +13 -0
  37. package/dist-lib/numbl-core/jit/e1/scalarFnKernel.d.ts +44 -0
  38. package/dist-lib/numbl-core/jit/fusedChainHelpers.d.ts +65 -0
  39. package/dist-lib/numbl-core/jit/fusedScalarEmit.d.ts +61 -0
  40. package/dist-lib/numbl-core/jit/fusion.d.ts +71 -0
  41. package/dist-lib/numbl-core/jit/fusionOps.d.ts +25 -0
  42. package/dist-lib/numbl-core/{interpreter/jit → jit}/index.d.ts +2 -2
  43. package/dist-lib/numbl-core/jit/jitBailSafety.d.ts +41 -0
  44. package/dist-lib/numbl-core/{interpreter/jit → jit}/jitLoop.d.ts +2 -2
  45. package/dist-lib/numbl-core/{interpreter/jit → jit}/jitLoopAnalysis.d.ts +6 -1
  46. package/dist-lib/numbl-core/jit/jitLower.d.ts +122 -0
  47. package/dist-lib/numbl-core/jit/jitLowerExpr.d.ts +27 -0
  48. package/dist-lib/numbl-core/jit/jitLowerStmt.d.ts +9 -0
  49. package/dist-lib/numbl-core/{interpreter/jit → jit}/jitLowerTypes.d.ts +7 -3
  50. package/dist-lib/numbl-core/jit/jitTopLevel.d.ts +22 -0
  51. package/dist-lib/numbl-core/{interpreter/jit → jit}/jitTypes.d.ts +133 -1
  52. package/dist-lib/numbl-core/{interpreter/jit → jit/js}/jitCodegen.d.ts +2 -2
  53. package/dist-lib/numbl-core/{interpreter/jit → jit/js}/jitCodegenHoist.d.ts +19 -1
  54. package/dist-lib/numbl-core/{interpreter/jit → jit/js}/jitHelpers.d.ts +15 -3
  55. package/dist-lib/numbl-core/{interpreter/jit → jit/js}/jitHelpersIndex.d.ts +7 -0
  56. package/dist-lib/numbl-core/jit/js/jitHelpersTensor.d.ts +34 -0
  57. package/dist-lib/numbl-core/jit/js/jsFusedCodegen.d.ts +17 -0
  58. package/dist-lib/numbl-core/jit/scalarEmit.d.ts +58 -0
  59. package/dist-lib/numbl-core/lexer/types.d.ts +2 -1
  60. package/dist-lib/numbl-core/native/lapack-bridge.d.ts +39 -1
  61. package/dist-lib/numbl-core/ops/bessel.d.ts +18 -0
  62. package/dist-lib/numbl-core/ops/comparison.d.ts +11 -0
  63. package/dist-lib/numbl-core/ops/complexBinaryElemwise.d.ts +10 -0
  64. package/dist-lib/numbl-core/ops/complexUnaryElemwise.d.ts +8 -0
  65. package/dist-lib/numbl-core/ops/dispatch.d.ts +26 -0
  66. package/dist-lib/numbl-core/ops/index.d.ts +8 -0
  67. package/dist-lib/numbl-core/ops/opCodes.d.ts +70 -0
  68. package/dist-lib/numbl-core/ops/realBinaryElemwise.d.ts +8 -0
  69. package/dist-lib/numbl-core/ops/realUnaryElemwise.d.ts +5 -0
  70. package/dist-lib/numbl-core/ops/reduce.d.ts +6 -0
  71. package/dist-lib/numbl-core/parser/types.d.ts +6 -0
  72. package/dist-lib/numbl-core/runtime/alloc.d.ts +23 -0
  73. package/dist-lib/numbl-core/runtime/runtime.d.ts +1 -0
  74. package/dist-lib/numbl-core/version.d.ts +1 -1
  75. package/native/jit_runtime/jit_runtime.c +261 -0
  76. package/native/jit_runtime/jit_runtime.h +204 -0
  77. package/native/numbl_addon.cpp +53 -1
  78. package/native/ops/bessel.c +572 -0
  79. package/native/ops/comparison.c +150 -0
  80. package/native/ops/complex_binary_elemwise.c +192 -0
  81. package/native/ops/complex_unary_elemwise.c +152 -0
  82. package/native/ops/numbl_ops.c +66 -0
  83. package/native/ops/numbl_ops.h +262 -0
  84. package/native/ops/real_binary_elemwise.c +85 -0
  85. package/native/ops/real_unary_elemwise.c +104 -0
  86. package/native/ops/reduce.c +162 -0
  87. package/native/ops_napi.cpp +320 -0
  88. package/package.json +10 -9
  89. package/dist-lib/numbl-core/interpreter/jit/jitHelpersTensor.d.ts +0 -28
  90. package/dist-lib/numbl-core/interpreter/jit/jitLower.d.ts +0 -23
  91. /package/dist-lib/numbl-core/{interpreter/jit → jit/js}/jitHelpersComplex.d.ts +0 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * numbl_jit_runtime — helpers the C-JIT emitter calls from generated code.
3
+ *
4
+ * Kept in a static archive (jit_runtime.a) separate from numbl_ops.a:
5
+ * the `ops/` directory is reserved for op-code-dispatched kernels that
6
+ * achieve parity with the TS ops layer. Anything the JIT emitter calls
7
+ * *directly* from emitted C (bounds-checked index reads, MATLAB-semantics
8
+ * math helpers, tic/toc, reduction shims, ...) lives here instead.
9
+ *
10
+ * When adding a new helper, bump NUMBL_JIT_RT_VERSION below AND
11
+ * NUMBL_JIT_RT_REQUIRED_VERSION in jitCodegenC.ts. The generated C asserts
12
+ * `NUMBL_JIT_RT_VERSION >= N`, so a stale archive fails the per-JIT
13
+ * compile step with a clear "rebuild the addon" message instead of a
14
+ * cryptic linker error.
15
+ */
16
+
17
+ #ifndef NUMBL_JIT_RUNTIME_H
18
+ #define NUMBL_JIT_RUNTIME_H
19
+
20
+ #include <stddef.h>
21
+ #include <stdint.h>
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ /* ── Version ──────────────────────────────────────────────────────────── */
28
+
29
+ /**
30
+ * Version log:
31
+ * 1 — initial: idx1r, mod, sign, reduce_flat, tic/toc/monotonic_time.
32
+ * 2 — set1r_h (scalar linear Index write with soft-bail on OOB).
33
+ * 3 — idx2r / idx3r / set2r_h / set3r_h (multi-index Index read/write).
34
+ * 4 — setRange1r_h / setCol2r_h / copyRange1r (range/col slice r/w).
35
+ * 5 — is_nan / is_inf / is_finite (predicates that survive -ffast-math
36
+ * by inspecting IEEE-754 bit patterns, not FP ops).
37
+ */
38
+ #define NUMBL_JIT_RT_VERSION 5
39
+
40
+ /** Returns NUMBL_JIT_RT_VERSION baked into the compiled archive. */
41
+ int numbl_jit_rt_version(void);
42
+
43
+ /* ── Scalar linear Index read ─────────────────────────────────────────── */
44
+
45
+ /**
46
+ * 1-based MATLAB linear Index read on a real-valued tensor buffer.
47
+ *
48
+ * `i` — 1-based double index (truncation-to-zero via int64 cast). The
49
+ * emitter wraps non-integer indices with `round()` beforehand to
50
+ * match the JS-JIT's `Math.round`-then-truncate sequence.
51
+ * `err_flag` — set to 1.0 on OOB (and returns 0.0) so the C function
52
+ * finishes without a native crash. The caller must zero
53
+ * the flag before each koffi call; the JS wrapper checks
54
+ * it after and throws "Index exceeds array bounds".
55
+ */
56
+ double numbl_idx1r(const double* data, size_t len, double i, double* err_flag);
57
+
58
+ /**
59
+ * 1-based MATLAB linear Index write on a real-valued tensor buffer.
60
+ *
61
+ * On OOB, writes `2.0` to *err_flag (the "growth-needed" code the JS
62
+ * wrapper translates to a JitBailToInterpreter) and returns without
63
+ * writing, mirroring the JS-JIT's `set1r_h` helper. The interpreter
64
+ * then re-runs the call with proper tensor-growth semantics. As with
65
+ * the read path, the caller must zero the flag before each call.
66
+ */
67
+ void numbl_set1r_h(double* data, size_t len, double i, double v, double* err_flag);
68
+
69
+ /* ── Multi-index Index read (2D, 3D) ──────────────────────────────────── */
70
+
71
+ /**
72
+ * 1-based MATLAB 2D Index read on a real-valued tensor buffer.
73
+ *
74
+ * Column-major: returns data[(j-1)*d0 + (i-1)]. `d0` is the row count.
75
+ * The derived column count is `len / d0`; both dimensions are bounds-
76
+ * checked independently. Emitter wraps non-integer indices with
77
+ * `round()` to match the JS-JIT's `Math.round`-then-truncate sequence.
78
+ * On OOB, sets *err_flag = 1.0 and returns 0.0 (hard bounds error).
79
+ */
80
+ double numbl_idx2r(const double* data, size_t len, size_t d0,
81
+ double i, double j, double* err_flag);
82
+
83
+ /**
84
+ * 1-based MATLAB 3D Index read on a real-valued tensor buffer.
85
+ *
86
+ * Column-major: returns data[((k-1)*d1 + (j-1))*d0 + (i-1)]. `d0` is
87
+ * the row count, `d1` the column count. The derived page count is
88
+ * `len / (d0 * d1)`; each dimension is bounds-checked independently.
89
+ */
90
+ double numbl_idx3r(const double* data, size_t len, size_t d0, size_t d1,
91
+ double i, double j, double k, double* err_flag);
92
+
93
+ /* ── Multi-index Index write (2D, 3D), soft-bail on OOB ───────────────── */
94
+
95
+ /**
96
+ * 2D Index write. On OOB (along either dim) writes `2.0` to *err_flag
97
+ * (the "growth-needed" code the JS wrapper translates to a
98
+ * JitBailToInterpreter) and returns without writing.
99
+ */
100
+ void numbl_set2r_h(double* data, size_t len, size_t d0,
101
+ double i, double j, double v, double* err_flag);
102
+
103
+ /** 3D Index write with the same soft-bail convention as set2r_h. */
104
+ void numbl_set3r_h(double* data, size_t len, size_t d0, size_t d1,
105
+ double i, double j, double k, double v,
106
+ double* err_flag);
107
+
108
+ /* ── Range / column slice read and write ──────────────────────────────── */
109
+
110
+ /**
111
+ * Range → range write: `dst(dStart:dEnd) = src(sStart:sEnd)` on real
112
+ * tensors, 1-based MATLAB indices. Sizes must match: on mismatch,
113
+ * writes `3.0` to *err_flag and returns (the JS wrapper translates this
114
+ * into "Unable to perform assignment because the indices on the left
115
+ * side are not compatible with the size of the right side."). Bounds
116
+ * violations on either range write `1.0` and return. Uses memmove so
117
+ * overlapping dst == src ranges are handled correctly.
118
+ */
119
+ void numbl_setRange1r_h(double* dstData, size_t dstLen,
120
+ double dstStart, double dstEnd,
121
+ const double* srcData, size_t srcLen,
122
+ double srcStart, double srcEnd,
123
+ double* err_flag);
124
+
125
+ /**
126
+ * Column-vector write into column `col` of a 2-D tensor `dst` with row
127
+ * count `dstRows`. `srcLen` must equal `dstRows` (length mismatch →
128
+ * *err_flag = 3.0). When `col` exceeds the current column count, the
129
+ * MATLAB interpreter would grow dst — we soft-bail (*err_flag = 2.0) so
130
+ * the caller's stale hoisted aliases don't corrupt the growth path.
131
+ */
132
+ void numbl_setCol2r_h(double* dstData, size_t dstRows, size_t dstLen,
133
+ double col,
134
+ const double* srcData, size_t srcLen,
135
+ double* err_flag);
136
+
137
+ /**
138
+ * Range read: copy `src(start:end)` into caller-provided `dstData`. The
139
+ * caller must ensure `dstData` has capacity >= `end - start + 1`. OOB
140
+ * on `src` writes `1.0` to *err_flag and returns without writing.
141
+ * `start > end` is a valid empty range (no write, no error).
142
+ */
143
+ void numbl_copyRange1r(const double* srcData, size_t srcLen,
144
+ double start, double end,
145
+ double* dstData,
146
+ double* err_flag);
147
+
148
+ /* ── Scalar math helpers with MATLAB semantics ────────────────────────── */
149
+
150
+ /** MATLAB `mod(a, b)`: result has the sign of `b`; `mod(a, 0) == a`. */
151
+ double numbl_mod(double a, double b);
152
+
153
+ /** Three-valued sign: -1, 0, or 1. */
154
+ double numbl_sign(double x);
155
+
156
+ /* ── Reduction wrapper ────────────────────────────────────────────────── */
157
+
158
+ /**
159
+ * Thin wrapper around numbl_real_flat_reduce (from numbl_ops.a) that
160
+ * returns the scalar directly, so generated C doesn't need a local
161
+ * `double out; … ; return out;` dance inline.
162
+ */
163
+ double numbl_reduce_flat(int op, const double* data, int64_t len);
164
+
165
+ /* ── Timers (tic/toc) ─────────────────────────────────────────────────── */
166
+
167
+ /**
168
+ * Monotonic wall-clock seconds. Exported by every JIT .so so the JS
169
+ * wrapper can cross-reference the C clock domain when bridging tic/toc
170
+ * state between JS and C.
171
+ */
172
+ double numbl_monotonic_time(void);
173
+
174
+ /** Capture the current monotonic time into *state, return it. */
175
+ double numbl_tic(double* state);
176
+
177
+ /** Elapsed seconds since *state. */
178
+ double numbl_toc(const double* state);
179
+
180
+ /* ── NaN / Inf / finite predicates ───────────────────────────────────── */
181
+
182
+ /**
183
+ * Bit-pattern-based predicates that return 1 for true, 0 for false.
184
+ *
185
+ * The JIT emits calls to these instead of C99's `isnan` / `isinf` /
186
+ * `isfinite` because the generated C is compiled with `-ffast-math`,
187
+ * which implies `-ffinite-math-only` and constant-folds those macros
188
+ * away. These helpers inspect the IEEE-754 bit pattern via `memcpy`,
189
+ * so the optimizer can't prove they're always-false even if the
190
+ * caller's `-ffast-math` assumes operands are finite — the function
191
+ * call is opaque, and the bit operations have no FP semantics.
192
+ *
193
+ * Assumes IEEE-754 binary64 doubles (true on every platform numbl
194
+ * targets).
195
+ */
196
+ int numbl_is_nan(double x);
197
+ int numbl_is_inf(double x);
198
+ int numbl_is_finite(double x);
199
+
200
+ #ifdef __cplusplus
201
+ }
202
+ #endif
203
+
204
+ #endif /* NUMBL_JIT_RUNTIME_H */
@@ -29,7 +29,25 @@ extern "C" {
29
29
  // ── Addon version ────────────────────────────────────────────────────────────
30
30
  // Bump this integer whenever the addon's API changes (new functions, signature
31
31
  // changes, etc.) so that the JS side can detect stale builds.
32
- static const int ADDON_VERSION = 3;
32
+ static const int ADDON_VERSION = 8;
33
+
34
+ // ── New tensor-ops layer (native/ops/) ───────────────────────────────────────
35
+ Napi::Value TensorOpRealBinary(const Napi::CallbackInfo& info);
36
+ Napi::Value TensorOpRealScalarBinary(const Napi::CallbackInfo& info);
37
+ Napi::Value TensorOpComplexBinary(const Napi::CallbackInfo& info);
38
+ Napi::Value TensorOpComplexScalarBinary(const Napi::CallbackInfo& info);
39
+ Napi::Value TensorOpRealUnary(const Napi::CallbackInfo& info);
40
+ Napi::Value TensorOpComplexUnary(const Napi::CallbackInfo& info);
41
+ Napi::Value TensorOpComplexAbs(const Napi::CallbackInfo& info);
42
+ Napi::Value TensorOpRealComparison(const Napi::CallbackInfo& info);
43
+ Napi::Value TensorOpRealScalarComparison(const Napi::CallbackInfo& info);
44
+ Napi::Value TensorOpComplexComparison(const Napi::CallbackInfo& info);
45
+ Napi::Value TensorOpComplexScalarComparison(const Napi::CallbackInfo& info);
46
+ Napi::Value TensorOpRealFlatReduce(const Napi::CallbackInfo& info);
47
+ Napi::Value TensorOpComplexFlatReduce(const Napi::CallbackInfo& info);
48
+ Napi::Value TensorOpBesselReal(const Napi::CallbackInfo& info);
49
+ Napi::Value TensorOpBesselH(const Napi::CallbackInfo& info);
50
+ Napi::Value TensorOpDumpCodes(const Napi::CallbackInfo& info);
33
51
 
34
52
  static Napi::Value AddonVersion(const Napi::CallbackInfo& info) {
35
53
  return Napi::Number::New(info.Env(), ADDON_VERSION);
@@ -107,6 +125,40 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
107
125
  Napi::Function::New(env, Gmres));
108
126
  exports.Set(Napi::String::New(env, "gmresComplex"),
109
127
  Napi::Function::New(env, GmresComplex));
128
+
129
+ // ── New tensor-ops layer ──────────────────────────────────────────────────
130
+ exports.Set(Napi::String::New(env, "tensorOpRealBinary"),
131
+ Napi::Function::New(env, TensorOpRealBinary));
132
+ exports.Set(Napi::String::New(env, "tensorOpRealScalarBinary"),
133
+ Napi::Function::New(env, TensorOpRealScalarBinary));
134
+ exports.Set(Napi::String::New(env, "tensorOpComplexBinary"),
135
+ Napi::Function::New(env, TensorOpComplexBinary));
136
+ exports.Set(Napi::String::New(env, "tensorOpComplexScalarBinary"),
137
+ Napi::Function::New(env, TensorOpComplexScalarBinary));
138
+ exports.Set(Napi::String::New(env, "tensorOpRealUnary"),
139
+ Napi::Function::New(env, TensorOpRealUnary));
140
+ exports.Set(Napi::String::New(env, "tensorOpComplexUnary"),
141
+ Napi::Function::New(env, TensorOpComplexUnary));
142
+ exports.Set(Napi::String::New(env, "tensorOpComplexAbs"),
143
+ Napi::Function::New(env, TensorOpComplexAbs));
144
+ exports.Set(Napi::String::New(env, "tensorOpRealComparison"),
145
+ Napi::Function::New(env, TensorOpRealComparison));
146
+ exports.Set(Napi::String::New(env, "tensorOpRealScalarComparison"),
147
+ Napi::Function::New(env, TensorOpRealScalarComparison));
148
+ exports.Set(Napi::String::New(env, "tensorOpComplexComparison"),
149
+ Napi::Function::New(env, TensorOpComplexComparison));
150
+ exports.Set(Napi::String::New(env, "tensorOpComplexScalarComparison"),
151
+ Napi::Function::New(env, TensorOpComplexScalarComparison));
152
+ exports.Set(Napi::String::New(env, "tensorOpRealFlatReduce"),
153
+ Napi::Function::New(env, TensorOpRealFlatReduce));
154
+ exports.Set(Napi::String::New(env, "tensorOpComplexFlatReduce"),
155
+ Napi::Function::New(env, TensorOpComplexFlatReduce));
156
+ exports.Set(Napi::String::New(env, "tensorOpBesselReal"),
157
+ Napi::Function::New(env, TensorOpBesselReal));
158
+ exports.Set(Napi::String::New(env, "tensorOpBesselH"),
159
+ Napi::Function::New(env, TensorOpBesselH));
160
+ exports.Set(Napi::String::New(env, "tensorOpDumpCodes"),
161
+ Napi::Function::New(env, TensorOpDumpCodes));
110
162
  return exports;
111
163
  }
112
164