@digitaldefiance/node-accelerate 1.0.6 → 1.0.7
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 +6 -1
- package/examples/machine-learning.js +158 -0
- package/examples/matrix-multiply.js +50 -0
- package/examples/signal-processing.js +70 -0
- package/examples/vector-operations.js +73 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
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
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@digitaldefiance/node-accelerate)
|
|
5
|
+
[](https://www.npmjs.com/package/@digitaldefiance/node-accelerate)
|
|
6
|
+
[](https://github.com/Digital-Defiance/node-accelerate/blob/main/LICENSE)
|
|
7
|
+
[](https://github.com/Digital-Defiance/node-accelerate)
|
|
8
|
+
[](https://github.com/Digital-Defiance/node-accelerate/actions)
|
|
9
|
+
[](https://github.com/Digital-Defiance/node-accelerate)
|
|
10
|
+
[](https://nodejs.org/)
|
|
6
11
|
|
|
7
12
|
----
|
|
8
13
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Machine Learning Operations
|
|
4
|
+
* Demonstrates using Accelerate for ML inference
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Machine Learning Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Simple neural network layer: y = activation(W*x + b)
|
|
14
|
+
function denseLayer(input, weights, bias, output) {
|
|
15
|
+
const inputSize = input.length;
|
|
16
|
+
const outputSize = output.length;
|
|
17
|
+
|
|
18
|
+
// Matrix-vector multiply: output = weights * input
|
|
19
|
+
accelerate.matvec(weights, input, output, outputSize, inputSize);
|
|
20
|
+
|
|
21
|
+
// Add bias: output = output + bias
|
|
22
|
+
accelerate.axpy(1.0, bias, output);
|
|
23
|
+
|
|
24
|
+
// ReLU activation: output = max(0, output)
|
|
25
|
+
const zeros = new Float64Array(outputSize);
|
|
26
|
+
for (let i = 0; i < outputSize; i++) {
|
|
27
|
+
output[i] = Math.max(0, output[i]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Example: 2-layer network
|
|
34
|
+
console.log('Building 2-layer neural network...');
|
|
35
|
+
console.log(' Input: 784 (28×28 image)');
|
|
36
|
+
console.log(' Hidden: 128');
|
|
37
|
+
console.log(' Output: 10 (digits 0-9)');
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
// Layer 1: 784 → 128
|
|
41
|
+
const input = new Float64Array(784);
|
|
42
|
+
for (let i = 0; i < input.length; i++) {
|
|
43
|
+
input[i] = Math.random();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const weights1 = new Float64Array(128 * 784);
|
|
47
|
+
const bias1 = new Float64Array(128);
|
|
48
|
+
const hidden = new Float64Array(128);
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < weights1.length; i++) weights1[i] = Math.random() - 0.5;
|
|
51
|
+
for (let i = 0; i < bias1.length; i++) bias1[i] = Math.random() - 0.5;
|
|
52
|
+
|
|
53
|
+
console.log('Layer 1: Forward pass...');
|
|
54
|
+
let start = process.hrtime.bigint();
|
|
55
|
+
denseLayer(input, weights1, bias1, hidden);
|
|
56
|
+
let end = process.hrtime.bigint();
|
|
57
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
58
|
+
console.log('');
|
|
59
|
+
|
|
60
|
+
// Layer 2: 128 → 10
|
|
61
|
+
const weights2 = new Float64Array(10 * 128);
|
|
62
|
+
const bias2 = new Float64Array(10);
|
|
63
|
+
const output = new Float64Array(10);
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < weights2.length; i++) weights2[i] = Math.random() - 0.5;
|
|
66
|
+
for (let i = 0; i < bias2.length; i++) bias2[i] = Math.random() - 0.5;
|
|
67
|
+
|
|
68
|
+
console.log('Layer 2: Forward pass...');
|
|
69
|
+
start = process.hrtime.bigint();
|
|
70
|
+
denseLayer(hidden, weights2, bias2, output);
|
|
71
|
+
end = process.hrtime.bigint();
|
|
72
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
73
|
+
console.log('');
|
|
74
|
+
|
|
75
|
+
// Softmax (normalize to probabilities)
|
|
76
|
+
console.log('Softmax activation...');
|
|
77
|
+
const expOutput = new Float64Array(10);
|
|
78
|
+
for (let i = 0; i < output.length; i++) {
|
|
79
|
+
expOutput[i] = Math.exp(output[i]);
|
|
80
|
+
}
|
|
81
|
+
const sumExp = accelerate.sum(expOutput);
|
|
82
|
+
for (let i = 0; i < expOutput.length; i++) {
|
|
83
|
+
expOutput[i] /= sumExp;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log('Output probabilities:');
|
|
87
|
+
for (let i = 0; i < 10; i++) {
|
|
88
|
+
console.log(` Digit ${i}: ${(expOutput[i] * 100).toFixed(2)}%`);
|
|
89
|
+
}
|
|
90
|
+
console.log('');
|
|
91
|
+
|
|
92
|
+
// K-means clustering example
|
|
93
|
+
console.log('K-means Clustering Example');
|
|
94
|
+
console.log('-'.repeat(50));
|
|
95
|
+
|
|
96
|
+
const numPoints = 1000;
|
|
97
|
+
const numClusters = 3;
|
|
98
|
+
const dimensions = 2;
|
|
99
|
+
|
|
100
|
+
// Generate random points
|
|
101
|
+
const points = new Float64Array(numPoints * dimensions);
|
|
102
|
+
for (let i = 0; i < points.length; i++) {
|
|
103
|
+
points[i] = Math.random() * 100;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Initialize centroids
|
|
107
|
+
const centroids = new Float64Array(numClusters * dimensions);
|
|
108
|
+
for (let i = 0; i < numClusters; i++) {
|
|
109
|
+
const idx = Math.floor(Math.random() * numPoints);
|
|
110
|
+
centroids[i * dimensions] = points[idx * dimensions];
|
|
111
|
+
centroids[i * dimensions + 1] = points[idx * dimensions + 1];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log('Finding nearest centroids for 1000 points...');
|
|
115
|
+
start = process.hrtime.bigint();
|
|
116
|
+
|
|
117
|
+
const assignments = new Int32Array(numPoints);
|
|
118
|
+
const point = new Float64Array(dimensions);
|
|
119
|
+
const centroid = new Float64Array(dimensions);
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < numPoints; i++) {
|
|
122
|
+
point[0] = points[i * dimensions];
|
|
123
|
+
point[1] = points[i * dimensions + 1];
|
|
124
|
+
|
|
125
|
+
let minDist = Infinity;
|
|
126
|
+
let minCluster = 0;
|
|
127
|
+
|
|
128
|
+
for (let j = 0; j < numClusters; j++) {
|
|
129
|
+
centroid[0] = centroids[j * dimensions];
|
|
130
|
+
centroid[1] = centroids[j * dimensions + 1];
|
|
131
|
+
|
|
132
|
+
const dist = accelerate.euclidean(point, centroid);
|
|
133
|
+
if (dist < minDist) {
|
|
134
|
+
minDist = dist;
|
|
135
|
+
minCluster = j;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
assignments[i] = minCluster;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
end = process.hrtime.bigint();
|
|
143
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
144
|
+
console.log('');
|
|
145
|
+
|
|
146
|
+
// Count assignments
|
|
147
|
+
const counts = [0, 0, 0];
|
|
148
|
+
for (let i = 0; i < numPoints; i++) {
|
|
149
|
+
counts[assignments[i]]++;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log('Cluster assignments:');
|
|
153
|
+
for (let i = 0; i < numClusters; i++) {
|
|
154
|
+
console.log(` Cluster ${i}: ${counts[i]} points`);
|
|
155
|
+
}
|
|
156
|
+
console.log('');
|
|
157
|
+
|
|
158
|
+
console.log('✓ Machine learning operations completed!');
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Matrix Multiplication
|
|
4
|
+
* Demonstrates hardware-accelerated matrix operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Matrix Multiplication Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Create two 1000×1000 matrices
|
|
14
|
+
const M = 1000, K = 1000, N = 1000;
|
|
15
|
+
console.log(`Computing C = A × B where:`);
|
|
16
|
+
console.log(` A is ${M}×${K}`);
|
|
17
|
+
console.log(` B is ${K}×${N}`);
|
|
18
|
+
console.log(` C is ${M}×${N}`);
|
|
19
|
+
console.log('');
|
|
20
|
+
|
|
21
|
+
const A = new Float64Array(M * K);
|
|
22
|
+
const B = new Float64Array(K * N);
|
|
23
|
+
const C = new Float64Array(M * N);
|
|
24
|
+
|
|
25
|
+
// Fill with random data
|
|
26
|
+
console.log('Filling matrices with random data...');
|
|
27
|
+
for (let i = 0; i < A.length; i++) A[i] = Math.random();
|
|
28
|
+
for (let i = 0; i < B.length; i++) B[i] = Math.random();
|
|
29
|
+
|
|
30
|
+
// Perform matrix multiplication
|
|
31
|
+
console.log('Performing matrix multiplication...');
|
|
32
|
+
const start = process.hrtime.bigint();
|
|
33
|
+
accelerate.matmul(A, B, C, M, K, N);
|
|
34
|
+
const end = process.hrtime.bigint();
|
|
35
|
+
|
|
36
|
+
const timeMs = Number(end - start) / 1e6;
|
|
37
|
+
console.log(`✓ Completed in ${timeMs.toFixed(2)}ms`);
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
// Calculate GFLOPS
|
|
41
|
+
const operations = 2 * M * K * N; // 2 ops per multiply-add
|
|
42
|
+
const gflops = operations / (timeMs * 1e6);
|
|
43
|
+
console.log(`Performance: ${gflops.toFixed(2)} GFLOPS`);
|
|
44
|
+
console.log('');
|
|
45
|
+
|
|
46
|
+
// Verify result (check a few elements)
|
|
47
|
+
console.log('Sample results:');
|
|
48
|
+
console.log(` C[0,0] = ${C[0].toFixed(6)}`);
|
|
49
|
+
console.log(` C[0,1] = ${C[1].toFixed(6)}`);
|
|
50
|
+
console.log(` C[1,0] = ${C[N].toFixed(6)}`);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Signal Processing with FFT
|
|
4
|
+
* Demonstrates frequency analysis of audio signals
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Signal Processing Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Create a composite signal: 440 Hz (A4) + 880 Hz (A5)
|
|
14
|
+
const sampleRate = 44100; // CD quality
|
|
15
|
+
const duration = 1; // 1 second
|
|
16
|
+
const fftSize = 16384; // Must be power of 2
|
|
17
|
+
|
|
18
|
+
console.log(`Sample rate: ${sampleRate} Hz`);
|
|
19
|
+
console.log(`FFT size: ${fftSize}`);
|
|
20
|
+
console.log(`Frequency resolution: ${(sampleRate / fftSize).toFixed(2)} Hz`);
|
|
21
|
+
console.log('');
|
|
22
|
+
|
|
23
|
+
// Generate signal
|
|
24
|
+
console.log('Generating signal (440 Hz + 880 Hz)...');
|
|
25
|
+
const signal = new Float64Array(fftSize);
|
|
26
|
+
for (let i = 0; i < fftSize; i++) {
|
|
27
|
+
const t = i / sampleRate;
|
|
28
|
+
signal[i] =
|
|
29
|
+
Math.sin(2 * Math.PI * 440 * t) + // A4
|
|
30
|
+
Math.sin(2 * Math.PI * 880 * t); // A5
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Perform FFT
|
|
34
|
+
console.log('Performing FFT...');
|
|
35
|
+
const start = process.hrtime.bigint();
|
|
36
|
+
const spectrum = accelerate.fft(signal);
|
|
37
|
+
const end = process.hrtime.bigint();
|
|
38
|
+
|
|
39
|
+
const timeMs = Number(end - start) / 1e6;
|
|
40
|
+
console.log(`✓ Completed in ${timeMs.toFixed(3)}ms`);
|
|
41
|
+
console.log('');
|
|
42
|
+
|
|
43
|
+
// Calculate magnitudes
|
|
44
|
+
const magnitudes = new Float64Array(spectrum.real.length);
|
|
45
|
+
for (let i = 0; i < magnitudes.length; i++) {
|
|
46
|
+
magnitudes[i] = Math.sqrt(
|
|
47
|
+
spectrum.real[i] ** 2 + spectrum.imag[i] ** 2
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Find peaks
|
|
52
|
+
console.log('Finding frequency peaks...');
|
|
53
|
+
const peaks = [];
|
|
54
|
+
const threshold = Math.max(...magnitudes) * 0.5;
|
|
55
|
+
|
|
56
|
+
for (let i = 1; i < magnitudes.length - 1; i++) {
|
|
57
|
+
if (magnitudes[i] > threshold &&
|
|
58
|
+
magnitudes[i] > magnitudes[i - 1] &&
|
|
59
|
+
magnitudes[i] > magnitudes[i + 1]) {
|
|
60
|
+
const frequency = i * sampleRate / fftSize;
|
|
61
|
+
peaks.push({ frequency, magnitude: magnitudes[i] });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
peaks.sort((a, b) => b.magnitude - a.magnitude);
|
|
66
|
+
|
|
67
|
+
console.log('Top frequency components:');
|
|
68
|
+
peaks.slice(0, 5).forEach((peak, i) => {
|
|
69
|
+
console.log(` ${i + 1}. ${peak.frequency.toFixed(1)} Hz (magnitude: ${peak.magnitude.toFixed(2)})`);
|
|
70
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Example: Vector Operations
|
|
4
|
+
* Demonstrates hardware-accelerated vector math
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const accelerate = require('../index');
|
|
8
|
+
|
|
9
|
+
console.log('Vector Operations Example');
|
|
10
|
+
console.log('='.repeat(50));
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
// Create large vectors
|
|
14
|
+
const size = 1000000;
|
|
15
|
+
console.log(`Vector size: ${size.toLocaleString()} elements`);
|
|
16
|
+
console.log('');
|
|
17
|
+
|
|
18
|
+
const a = new Float64Array(size);
|
|
19
|
+
const b = new Float64Array(size);
|
|
20
|
+
const result = new Float64Array(size);
|
|
21
|
+
|
|
22
|
+
// Fill with random data
|
|
23
|
+
for (let i = 0; i < size; i++) {
|
|
24
|
+
a[i] = Math.random() * 100;
|
|
25
|
+
b[i] = Math.random() * 100;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Dot product
|
|
29
|
+
console.log('Computing dot product...');
|
|
30
|
+
let start = process.hrtime.bigint();
|
|
31
|
+
const dotProduct = accelerate.dot(a, b);
|
|
32
|
+
let end = process.hrtime.bigint();
|
|
33
|
+
console.log(` Result: ${dotProduct.toFixed(2)}`);
|
|
34
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
35
|
+
console.log('');
|
|
36
|
+
|
|
37
|
+
// Sum
|
|
38
|
+
console.log('Computing sum...');
|
|
39
|
+
start = process.hrtime.bigint();
|
|
40
|
+
const sum = accelerate.sum(a);
|
|
41
|
+
end = process.hrtime.bigint();
|
|
42
|
+
console.log(` Result: ${sum.toFixed(2)}`);
|
|
43
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
44
|
+
console.log('');
|
|
45
|
+
|
|
46
|
+
// Mean
|
|
47
|
+
console.log('Computing mean...');
|
|
48
|
+
start = process.hrtime.bigint();
|
|
49
|
+
const mean = accelerate.mean(a);
|
|
50
|
+
end = process.hrtime.bigint();
|
|
51
|
+
console.log(` Result: ${mean.toFixed(2)}`);
|
|
52
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
53
|
+
console.log('');
|
|
54
|
+
|
|
55
|
+
// Vector addition
|
|
56
|
+
console.log('Computing vector addition...');
|
|
57
|
+
start = process.hrtime.bigint();
|
|
58
|
+
accelerate.vadd(a, b, result);
|
|
59
|
+
end = process.hrtime.bigint();
|
|
60
|
+
console.log(` Sample: ${a[0].toFixed(2)} + ${b[0].toFixed(2)} = ${result[0].toFixed(2)}`);
|
|
61
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
62
|
+
console.log('');
|
|
63
|
+
|
|
64
|
+
// Vector multiplication
|
|
65
|
+
console.log('Computing vector multiplication...');
|
|
66
|
+
start = process.hrtime.bigint();
|
|
67
|
+
accelerate.vmul(a, b, result);
|
|
68
|
+
end = process.hrtime.bigint();
|
|
69
|
+
console.log(` Sample: ${a[0].toFixed(2)} × ${b[0].toFixed(2)} = ${result[0].toFixed(2)}`);
|
|
70
|
+
console.log(` Time: ${(Number(end - start) / 1e6).toFixed(3)}ms`);
|
|
71
|
+
console.log('');
|
|
72
|
+
|
|
73
|
+
console.log('✓ All operations completed successfully!');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/node-accelerate",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "High-performance Apple Accelerate framework bindings for Node.js - 283x faster matrix operations on Apple Silicon",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"index.js",
|
|
66
66
|
"index.d.ts",
|
|
67
67
|
"README.md",
|
|
68
|
+
"examples/",
|
|
68
69
|
"LICENSE",
|
|
69
70
|
"scripts/"
|
|
70
71
|
]
|