@digitaldefiance/node-accelerate 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Digital Defiance, Jessica Mulein
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,540 @@
1
+ # node-accelerate
2
+
3
+ High-performance Apple Accelerate framework bindings for Node.js. Get **283x faster** matrix operations and **5-8x faster** vector operations on Apple Silicon (M1/M2/M3/M4).
4
+
5
+ [![npm version](https://badge.fury.io/js/node-accelerate.svg)](https://www.npmjs.com/package/node-accelerate)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [GitHub](https://github.com/Digital-Defiance/node-accelerate)
8
+
9
+ ## Why?
10
+
11
+ Node.js doesn't natively use Apple's Accelerate framework, which provides hardware-optimized routines for numerical computing. This addon exposes Accelerate's BLAS (matrix operations) and vDSP (vector/signal processing) to JavaScript, giving you direct access to:
12
+
13
+ - **AMX (Apple Matrix coprocessor)** - Hardware matrix acceleration
14
+ - **NEON SIMD** - Vector processing
15
+ - **Optimized FFT** - Fast Fourier Transform
16
+
17
+ **Note**: This package only works on macOS because it uses Apple's Accelerate framework. If you're on Linux ARM64 (Raspberry Pi, AWS Graviton, etc.), consider using OpenBLAS, Eigen, or BLIS instead.
18
+
19
+ ## Performance
20
+
21
+ Real benchmarks on Apple M4 Max:
22
+
23
+ | Operation | Pure JavaScript | node-accelerate | Speedup |
24
+ |-----------|----------------|-----------------|---------|
25
+ | Matrix Multiply (500×500) | 93 ms | 0.33 ms | **283x** |
26
+ | Vector Dot Product (1M) | 0.66 ms | 0.13 ms | **5x** |
27
+ | Vector Sum (1M) | 0.59 ms | 0.08 ms | **7.6x** |
28
+ | Vector Add (1M) | 0.74 ms | 0.20 ms | **3.7x** |
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install node-accelerate
34
+ ```
35
+
36
+ **Requirements:**
37
+ - macOS (Apple Silicon: M1/M2/M3/M4 or Intel)
38
+ - Node.js >= 18.0.0
39
+ - Xcode Command Line Tools
40
+
41
+ ### First-time Setup
42
+
43
+ If you don't have Xcode Command Line Tools installed:
44
+
45
+ ```bash
46
+ xcode-select --install
47
+ ```
48
+
49
+ ### Platform Check
50
+
51
+ The package will automatically check your platform during installation. If you see errors:
52
+
53
+ **"node-accelerate requires macOS"**
54
+ - This package only works on macOS due to Apple's Accelerate framework
55
+ - Not supported on Linux or Windows
56
+
57
+ **"Xcode Command Line Tools may not be installed"**
58
+ - Run: `xcode-select --install`
59
+ - Follow the prompts to install
60
+
61
+ **"Failed to load native module"**
62
+ - Try rebuilding: `npm rebuild node-accelerate`
63
+ - Ensure Xcode Command Line Tools are installed
64
+
65
+ ### Verifying Installation
66
+
67
+ ```bash
68
+ node -e "const a = require('node-accelerate'); console.log('✓ Works!')"
69
+ ```
70
+
71
+ ## Quick Start
72
+
73
+ ```javascript
74
+ const accelerate = require('node-accelerate');
75
+
76
+ // Matrix multiplication: C = A × B
77
+ const M = 1000, K = 1000, N = 1000;
78
+ const A = new Float64Array(M * K);
79
+ const B = new Float64Array(K * N);
80
+ const C = new Float64Array(M * N);
81
+
82
+ // Fill with random data
83
+ for (let i = 0; i < A.length; i++) A[i] = Math.random();
84
+ for (let i = 0; i < B.length; i++) B[i] = Math.random();
85
+
86
+ // Hardware-accelerated matrix multiplication
87
+ accelerate.matmul(A, B, C, M, K, N);
88
+
89
+ // Vector operations
90
+ const vec1 = new Float64Array(1000000);
91
+ const vec2 = new Float64Array(1000000);
92
+ const result = new Float64Array(1000000);
93
+
94
+ for (let i = 0; i < vec1.length; i++) {
95
+ vec1[i] = Math.random();
96
+ vec2[i] = Math.random();
97
+ }
98
+
99
+ accelerate.vadd(vec1, vec2, result); // result = vec1 + vec2
100
+ accelerate.vmul(vec1, vec2, result); // result = vec1 * vec2
101
+
102
+ const dotProduct = accelerate.dot(vec1, vec2);
103
+ const sum = accelerate.sum(vec1);
104
+ const mean = accelerate.mean(vec1);
105
+
106
+ // FFT
107
+ const signal = new Float64Array(65536);
108
+ for (let i = 0; i < signal.length; i++) {
109
+ signal[i] = Math.sin(2 * Math.PI * i / signal.length);
110
+ }
111
+ const spectrum = accelerate.fft(signal);
112
+ console.log(spectrum.real, spectrum.imag);
113
+ ```
114
+
115
+ ## API Reference
116
+
117
+ ### Matrix Operations (BLAS)
118
+
119
+ #### `matmul(A, B, C, M, K, N)`
120
+
121
+ Matrix multiplication: C = A × B
122
+
123
+ - `A`: Float64Array - First matrix (M × K) in row-major order
124
+ - `B`: Float64Array - Second matrix (K × N) in row-major order
125
+ - `C`: Float64Array - Output matrix (M × N) in row-major order
126
+ - `M`: number - Rows in A and C
127
+ - `K`: number - Columns in A, rows in B
128
+ - `N`: number - Columns in B and C
129
+ - Returns: Float64Array (C)
130
+
131
+ **Example:**
132
+ ```javascript
133
+ const M = 100, K = 100, N = 100;
134
+ const A = new Float64Array(M * K);
135
+ const B = new Float64Array(K * N);
136
+ const C = new Float64Array(M * N);
137
+
138
+ // Fill A and B...
139
+ accelerate.matmul(A, B, C, M, K, N);
140
+ ```
141
+
142
+ #### `matvec(A, x, y, M, N)`
143
+
144
+ Matrix-vector multiplication: y = A × x
145
+
146
+ - `A`: Float64Array - Matrix (M × N) in row-major order
147
+ - `x`: Float64Array - Input vector (N elements)
148
+ - `y`: Float64Array - Output vector (M elements)
149
+ - `M`: number - Rows in A
150
+ - `N`: number - Columns in A
151
+ - Returns: Float64Array (y)
152
+
153
+ **Example:**
154
+ ```javascript
155
+ const M = 100, N = 50;
156
+ const A = new Float64Array(M * N);
157
+ const x = new Float64Array(N);
158
+ const y = new Float64Array(M);
159
+
160
+ accelerate.matvec(A, x, y, M, N);
161
+ ```
162
+
163
+ #### `axpy(alpha, x, y)`
164
+
165
+ AXPY operation: y = alpha*x + y
166
+
167
+ - `alpha`: number - Scalar multiplier
168
+ - `x`: Float64Array - Input vector
169
+ - `y`: Float64Array - Input/output vector
170
+ - Returns: Float64Array (y)
171
+
172
+ **Example:**
173
+ ```javascript
174
+ const x = new Float64Array([1, 2, 3]);
175
+ const y = new Float64Array([4, 5, 6]);
176
+ accelerate.axpy(2.0, x, y); // y = [6, 9, 12]
177
+ ```
178
+
179
+ ### Vector Operations (vDSP)
180
+
181
+ #### `dot(a, b)`
182
+
183
+ Dot product: sum(a[i] * b[i])
184
+
185
+ - `a`: Float64Array - First vector
186
+ - `b`: Float64Array - Second vector (same length as a)
187
+ - Returns: number
188
+
189
+ **Example:**
190
+ ```javascript
191
+ const a = new Float64Array([1, 2, 3, 4]);
192
+ const b = new Float64Array([5, 6, 7, 8]);
193
+ const result = accelerate.dot(a, b); // 70
194
+ ```
195
+
196
+ #### `sum(vec)`
197
+
198
+ Sum of all elements
199
+
200
+ - `vec`: Float64Array - Input vector
201
+ - Returns: number
202
+
203
+ **Example:**
204
+ ```javascript
205
+ const vec = new Float64Array([1, 2, 3, 4, 5]);
206
+ const result = accelerate.sum(vec); // 15
207
+ ```
208
+
209
+ #### `mean(vec)`
210
+
211
+ Mean (average) of all elements
212
+
213
+ - `vec`: Float64Array - Input vector
214
+ - Returns: number
215
+
216
+ **Example:**
217
+ ```javascript
218
+ const vec = new Float64Array([1, 2, 3, 4, 5]);
219
+ const result = accelerate.mean(vec); // 3
220
+ ```
221
+
222
+ #### `vadd(a, b, out)`
223
+
224
+ Element-wise addition: out[i] = a[i] + b[i]
225
+
226
+ - `a`: Float64Array - First vector
227
+ - `b`: Float64Array - Second vector
228
+ - `out`: Float64Array - Output vector
229
+ - Returns: Float64Array (out)
230
+
231
+ **Example:**
232
+ ```javascript
233
+ const a = new Float64Array([1, 2, 3]);
234
+ const b = new Float64Array([4, 5, 6]);
235
+ const out = new Float64Array(3);
236
+ accelerate.vadd(a, b, out); // out = [5, 7, 9]
237
+ ```
238
+
239
+ #### `vsub(a, b, out)`
240
+
241
+ Element-wise subtraction: out[i] = a[i] - b[i]
242
+
243
+ - `a`: Float64Array - First vector
244
+ - `b`: Float64Array - Second vector
245
+ - `out`: Float64Array - Output vector
246
+ - Returns: Float64Array (out)
247
+
248
+ #### `vmul(a, b, out)`
249
+
250
+ Element-wise multiplication: out[i] = a[i] * b[i]
251
+
252
+ - `a`: Float64Array - First vector
253
+ - `b`: Float64Array - Second vector
254
+ - `out`: Float64Array - Output vector
255
+ - Returns: Float64Array (out)
256
+
257
+ #### `vdiv(a, b, out)`
258
+
259
+ Element-wise division: out[i] = a[i] / b[i]
260
+
261
+ - `a`: Float64Array - First vector
262
+ - `b`: Float64Array - Second vector
263
+ - `out`: Float64Array - Output vector
264
+ - Returns: Float64Array (out)
265
+
266
+ #### `vabs(a, b)`
267
+
268
+ Element-wise absolute value: b[i] = |a[i]|
269
+
270
+ - `a`: Float64Array - Input vector
271
+ - `b`: Float64Array - Output vector
272
+ - Returns: Float64Array (b)
273
+
274
+ **Example:**
275
+ ```javascript
276
+ const a = new Float64Array([-1, -2, 3, -4]);
277
+ const b = new Float64Array(4);
278
+ accelerate.vabs(a, b); // b = [1, 2, 3, 4]
279
+ ```
280
+
281
+ #### `vsquare(a, b)`
282
+
283
+ Element-wise square: b[i] = a[i]^2
284
+
285
+ - `a`: Float64Array - Input vector
286
+ - `b`: Float64Array - Output vector
287
+ - Returns: Float64Array (b)
288
+
289
+ **Example:**
290
+ ```javascript
291
+ const a = new Float64Array([2, 3, 4]);
292
+ const b = new Float64Array(3);
293
+ accelerate.vsquare(a, b); // b = [4, 9, 16]
294
+ ```
295
+
296
+ #### `vsqrt(a, b)`
297
+
298
+ Element-wise square root: b[i] = sqrt(a[i])
299
+
300
+ - `a`: Float64Array - Input vector
301
+ - `b`: Float64Array - Output vector
302
+ - Returns: Float64Array (b)
303
+
304
+ **Example:**
305
+ ```javascript
306
+ const a = new Float64Array([4, 9, 16]);
307
+ const b = new Float64Array(3);
308
+ accelerate.vsqrt(a, b); // b = [2, 3, 4]
309
+ ```
310
+
311
+ #### `normalize(a, b)`
312
+
313
+ Normalize vector to unit length: b = a / ||a||
314
+
315
+ - `a`: Float64Array - Input vector
316
+ - `b`: Float64Array - Output vector (unit vector)
317
+ - Returns: Float64Array (b)
318
+
319
+ **Example:**
320
+ ```javascript
321
+ const a = new Float64Array([3, 4, 0]);
322
+ const b = new Float64Array(3);
323
+ accelerate.normalize(a, b); // b = [0.6, 0.8, 0]
324
+ ```
325
+
326
+ ### Reductions
327
+
328
+ #### `rms(vec)`
329
+
330
+ Root Mean Square: sqrt(sum(vec[i]^2) / n)
331
+
332
+ - `vec`: Float64Array - Input vector
333
+ - Returns: number
334
+
335
+ **Example:**
336
+ ```javascript
337
+ const vec = new Float64Array([1, 2, 3, 4, 5]);
338
+ const result = accelerate.rms(vec); // 3.317
339
+ ```
340
+
341
+ ### Distance Metrics
342
+
343
+ #### `euclidean(a, b)`
344
+
345
+ Euclidean distance: sqrt(sum((a[i] - b[i])^2))
346
+
347
+ - `a`: Float64Array - First vector
348
+ - `b`: Float64Array - Second vector
349
+ - Returns: number
350
+
351
+ **Example:**
352
+ ```javascript
353
+ const a = new Float64Array([0, 0, 0]);
354
+ const b = new Float64Array([3, 4, 0]);
355
+ const distance = accelerate.euclidean(a, b); // 5
356
+ ```
357
+
358
+ ### Signal Processing
359
+
360
+ #### `fft(signal)`
361
+
362
+ Fast Fourier Transform
363
+
364
+ - `signal`: Float64Array - Input signal (length must be power of 2)
365
+ - Returns: Object with `real` and `imag` Float64Arrays
366
+
367
+ **Example:**
368
+ ```javascript
369
+ const signal = new Float64Array(1024);
370
+ for (let i = 0; i < signal.length; i++) {
371
+ signal[i] = Math.sin(2 * Math.PI * i / signal.length);
372
+ }
373
+ const spectrum = accelerate.fft(signal);
374
+ console.log(spectrum.real.length); // 512
375
+ console.log(spectrum.imag.length); // 512
376
+ ```
377
+
378
+ ## TypeScript Support
379
+
380
+ Full TypeScript definitions included:
381
+
382
+ ```typescript
383
+ import * as accelerate from 'node-accelerate';
384
+
385
+ const A = new Float64Array(100 * 100);
386
+ const B = new Float64Array(100 * 100);
387
+ const C = new Float64Array(100 * 100);
388
+
389
+ accelerate.matmul(A, B, C, 100, 100, 100);
390
+ ```
391
+
392
+ ## Use Cases
393
+
394
+ ### Machine Learning Inference
395
+
396
+ ```javascript
397
+ // Matrix multiplication for neural network layers
398
+ function denseLayer(input, weights, bias) {
399
+ const output = new Float64Array(weights.length / input.length);
400
+ accelerate.matmul(
401
+ input, weights, output,
402
+ 1, input.length, output.length
403
+ );
404
+ // Add bias...
405
+ return output;
406
+ }
407
+ ```
408
+
409
+ ### Signal Processing
410
+
411
+ ```javascript
412
+ // Analyze audio spectrum
413
+ function analyzeAudio(audioBuffer) {
414
+ const spectrum = accelerate.fft(audioBuffer);
415
+ const magnitudes = new Float64Array(spectrum.real.length);
416
+
417
+ for (let i = 0; i < magnitudes.length; i++) {
418
+ magnitudes[i] = Math.sqrt(
419
+ spectrum.real[i] ** 2 + spectrum.imag[i] ** 2
420
+ );
421
+ }
422
+
423
+ return magnitudes;
424
+ }
425
+ ```
426
+
427
+ ### Scientific Computing
428
+
429
+ ```javascript
430
+ // Numerical integration using vector operations
431
+ function integrate(f, a, b, n) {
432
+ const h = (b - a) / n;
433
+ const x = new Float64Array(n);
434
+ const y = new Float64Array(n);
435
+
436
+ for (let i = 0; i < n; i++) {
437
+ x[i] = a + i * h;
438
+ y[i] = f(x[i]);
439
+ }
440
+
441
+ return h * accelerate.sum(y);
442
+ }
443
+ ```
444
+
445
+ ## Benchmarking
446
+
447
+ Run the included benchmarks:
448
+
449
+ ```bash
450
+ npm run benchmark
451
+ ```
452
+
453
+ Run tests:
454
+
455
+ ```bash
456
+ npm test
457
+ ```
458
+
459
+ ## Performance Tips
460
+
461
+ 1. **Reuse buffers** - Allocate Float64Arrays once and reuse them
462
+ 2. **Batch operations** - Process large arrays instead of many small ones
463
+ 3. **Use appropriate sizes** - Accelerate shines with larger data (1000+ elements)
464
+ 4. **Profile your code** - Not all operations benefit equally
465
+
466
+ ## Limitations
467
+
468
+ - **macOS only** - Requires Apple's Accelerate framework
469
+ - **Float64Array only** - Currently supports double precision only
470
+ - **Row-major order** - Matrices must be in row-major format
471
+ - **FFT size** - Must be power of 2
472
+
473
+ ## Contributing
474
+
475
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
476
+
477
+ ## License
478
+
479
+ MIT © Jessica Mulein
480
+
481
+ ## Acknowledgments
482
+
483
+ Built on Apple's Accelerate framework. Inspired by the need for high-performance numerical computing in Node.js on Apple Silicon.
484
+
485
+ ## Troubleshooting
486
+
487
+ ### "Cannot find module 'node-accelerate'"
488
+
489
+ Make sure you installed it:
490
+ ```bash
491
+ npm install node-accelerate
492
+ ```
493
+
494
+ ### "Error: Module did not self-register"
495
+
496
+ Rebuild the addon:
497
+ ```bash
498
+ npm rebuild node-accelerate
499
+ ```
500
+
501
+ ### "node-accelerate requires macOS"
502
+
503
+ This package only works on macOS because it uses Apple's Accelerate framework. It cannot run on Linux or Windows.
504
+
505
+ ### Build fails with "gyp: No Xcode or CLT version detected"
506
+
507
+ Install Xcode Command Line Tools:
508
+ ```bash
509
+ xcode-select --install
510
+ ```
511
+
512
+ ### "Unsupported architecture"
513
+
514
+ node-accelerate supports:
515
+ - ARM64 (Apple Silicon: M1/M2/M3/M4)
516
+ - x64 (Intel Macs)
517
+
518
+ If you're on an older Mac with a different architecture, this package won't work.
519
+
520
+ ### Performance seems slow
521
+
522
+ 1. Make sure you're using large arrays (1000+ elements)
523
+ 2. Reuse buffers instead of allocating new ones
524
+ 3. Run `npm run compare` to see actual speedups on your machine
525
+ 4. Check that you're not running in a VM or emulator
526
+
527
+ ## Related Projects
528
+
529
+ - [Apple Accelerate Documentation](https://developer.apple.com/documentation/accelerate)
530
+ - [BLAS Reference](http://www.netlib.org/blas/)
531
+ - [vDSP Reference](https://developer.apple.com/documentation/accelerate/vdsp)
532
+
533
+ ## Support
534
+
535
+ - [GitHub Issues](https://github.com/Digital-Defiance/node-accelerate/issues)
536
+ - [npm Package](https://www.npmjs.com/package/@digitaldefiance/node-accelerate)
537
+
538
+ ---
539
+
540
+ **Made with ❤️ for Apple Silicon**