@danielsimonjr/mathts-parallel 0.6.10 → 0.7.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 +9 -3
- package/dist/ComputePool.d.ts +15 -14
- package/dist/ComputePool.d.ts.map +1 -1
- package/dist/WorkerPool.d.ts +55 -0
- package/dist/WorkerPool.d.ts.map +1 -0
- package/dist/gemm-rows.d.ts +19 -0
- package/dist/gemm-rows.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1159 -1752
- package/dist/matrix.worker.d.ts +0 -11
- package/dist/matrix.worker.d.ts.map +1 -1
- package/dist/matrix.worker.js +93 -110
- package/dist/strategies/chunk.d.ts +9 -2
- package/dist/strategies/chunk.d.ts.map +1 -1
- package/package.json +18 -7
package/dist/matrix.worker.d.ts
CHANGED
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Matrix Worker for parallel computation
|
|
3
|
-
* Handles matrix operations in a separate thread.
|
|
4
|
-
*
|
|
5
|
-
* Each task computes a contiguous slice of the output and returns it. The
|
|
6
|
-
* parent ({@link ParallelMatrix}) copies returned slices back into the result
|
|
7
|
-
* buffer. Returning the data (rather than relying on in-place mutation of a
|
|
8
|
-
* shared buffer) keeps the worker correct whether or not the caller is using
|
|
9
|
-
* SharedArrayBuffer — a structured-clone copy of a non-shared `resultData`
|
|
10
|
-
* would otherwise be discarded and the caller would observe all zeros.
|
|
11
|
-
*/
|
|
12
1
|
export {};
|
|
13
2
|
//# sourceMappingURL=matrix.worker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrix.worker.d.ts","sourceRoot":"","sources":["../src/matrix.worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"matrix.worker.d.ts","sourceRoot":"","sources":["../src/matrix.worker.ts"],"names":[],"mappings":""}
|
package/dist/matrix.worker.js
CHANGED
|
@@ -1,126 +1,109 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
//#region src/gemm-rows.ts
|
|
2
|
+
function gemmRows(aData, aCols, bData, bCols, rowStart, rowEnd, out, outRowBase) {
|
|
3
|
+
for (let i = rowStart; i < rowEnd; i++) for (let j = 0; j < bCols; j++) {
|
|
4
|
+
let sum = 0;
|
|
5
|
+
for (let k = 0; k < aCols; k++) sum += aData[i * aCols + k] * bData[k * bCols + j];
|
|
6
|
+
out[(i - outRowBase) * bCols + j] = sum;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/matrix.worker.ts
|
|
11
|
+
const isNode = typeof process !== "undefined" && process.versions?.node !== void 0;
|
|
12
|
+
let nodeParentPort = null;
|
|
4
13
|
function sendMessage(message) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
} else {
|
|
10
|
-
postMessage(message);
|
|
11
|
-
}
|
|
14
|
+
if (isNode) {
|
|
15
|
+
if (nodeParentPort) nodeParentPort.postMessage(message);
|
|
16
|
+
} else postMessage(message);
|
|
12
17
|
}
|
|
13
18
|
function handleMessage(event) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
19
|
+
const message = isNode ? event : event.data;
|
|
20
|
+
try {
|
|
21
|
+
const task = message.data;
|
|
22
|
+
let result;
|
|
23
|
+
switch (task.operation) {
|
|
24
|
+
case "multiply":
|
|
25
|
+
result = multiplyTask(task);
|
|
26
|
+
break;
|
|
27
|
+
case "add":
|
|
28
|
+
result = elementwiseTask(task, (a, b) => a + b);
|
|
29
|
+
break;
|
|
30
|
+
case "subtract":
|
|
31
|
+
result = elementwiseTask(task, (a, b) => a - b);
|
|
32
|
+
break;
|
|
33
|
+
case "elementMultiply":
|
|
34
|
+
result = elementwiseTask(task, (a, b) => a * b);
|
|
35
|
+
break;
|
|
36
|
+
case "scale":
|
|
37
|
+
result = scaleTask(task);
|
|
38
|
+
break;
|
|
39
|
+
case "transpose":
|
|
40
|
+
result = transposeTask(task);
|
|
41
|
+
break;
|
|
42
|
+
case "dot":
|
|
43
|
+
result = dotProductTask(task);
|
|
44
|
+
break;
|
|
45
|
+
case "sum":
|
|
46
|
+
result = sumTask(task);
|
|
47
|
+
break;
|
|
48
|
+
default: throw new Error(`Unknown operation: ${task.operation}`);
|
|
49
|
+
}
|
|
50
|
+
sendMessage({
|
|
51
|
+
id: message.id,
|
|
52
|
+
type: "result",
|
|
53
|
+
data: result
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
sendMessage({
|
|
57
|
+
id: message.id,
|
|
58
|
+
type: "error",
|
|
59
|
+
error: error instanceof Error ? error.message : String(error)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
function multiplyTask(task) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let sum = 0;
|
|
66
|
-
for (let k = 0; k < aCols; k++) {
|
|
67
|
-
sum += aData[i * aCols + k] * bData[k * bCols + j];
|
|
68
|
-
}
|
|
69
|
-
out[(i - startRow) * bCols + j] = sum;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return out;
|
|
64
|
+
const { aData, aCols, bData, bCols, startRow, endRow } = task;
|
|
65
|
+
const rowCount = endRow - startRow;
|
|
66
|
+
const out = new Float64Array(rowCount * bCols);
|
|
67
|
+
gemmRows(aData, aCols, bData, bCols, startRow, endRow, out, startRow);
|
|
68
|
+
return out;
|
|
73
69
|
}
|
|
74
70
|
function elementwiseTask(task, op) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
return out;
|
|
71
|
+
const { aData, bData, start, end } = task;
|
|
72
|
+
const out = new Float64Array(end - start);
|
|
73
|
+
for (let i = start; i < end; i++) out[i - start] = op(aData[i], bData[i]);
|
|
74
|
+
return out;
|
|
81
75
|
}
|
|
82
76
|
function scaleTask(task) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
return out;
|
|
77
|
+
const { aData, scalar, start, end } = task;
|
|
78
|
+
const out = new Float64Array(end - start);
|
|
79
|
+
for (let i = start; i < end; i++) out[i - start] = aData[i] * scalar;
|
|
80
|
+
return out;
|
|
89
81
|
}
|
|
90
82
|
function transposeTask(task) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
out[j * rowCount + (i - startRow)] = data[i * cols + j];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return out;
|
|
83
|
+
const { data, cols, startRow, endRow } = task;
|
|
84
|
+
const rowCount = endRow - startRow;
|
|
85
|
+
const out = new Float64Array(rowCount * cols);
|
|
86
|
+
for (let i = startRow; i < endRow; i++) for (let j = 0; j < cols; j++) out[j * rowCount + (i - startRow)] = data[i * cols + j];
|
|
87
|
+
return out;
|
|
100
88
|
}
|
|
101
89
|
function dotProductTask(task) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
return sum;
|
|
90
|
+
const { aData, bData, start, end } = task;
|
|
91
|
+
let sum = 0;
|
|
92
|
+
for (let i = start; i < end; i++) sum += aData[i] * bData[i];
|
|
93
|
+
return sum;
|
|
108
94
|
}
|
|
109
95
|
function sumTask(task) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
return sum;
|
|
116
|
-
}
|
|
117
|
-
if (isNode) {
|
|
118
|
-
void import("worker_threads").then(({ parentPort }) => {
|
|
119
|
-
if (parentPort) {
|
|
120
|
-
nodeParentPort = parentPort;
|
|
121
|
-
parentPort.on("message", handleMessage);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
125
|
-
self.onmessage = handleMessage;
|
|
96
|
+
const { aData, start, end } = task;
|
|
97
|
+
let sum = 0;
|
|
98
|
+
for (let i = start; i < end; i++) sum += aData[i];
|
|
99
|
+
return sum;
|
|
126
100
|
}
|
|
101
|
+
if (isNode) import("node:worker_threads").then(({ parentPort }) => {
|
|
102
|
+
if (parentPort) {
|
|
103
|
+
nodeParentPort = parentPort;
|
|
104
|
+
parentPort.on("message", handleMessage);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
else self.onmessage = handleMessage;
|
|
108
|
+
//#endregion
|
|
109
|
+
export {};
|
|
@@ -54,7 +54,10 @@ export interface ChunkOptions {
|
|
|
54
54
|
*/
|
|
55
55
|
export declare function calculateOptimalChunks(totalElements: number, options?: ChunkOptions): number;
|
|
56
56
|
/**
|
|
57
|
-
* Chunk a Float64Array into multiple smaller arrays
|
|
57
|
+
* Chunk a Float64Array into multiple smaller arrays.
|
|
58
|
+
*
|
|
59
|
+
* Split ranges are views (`subarray`). A single planned chunk returns `data`
|
|
60
|
+
* itself.
|
|
58
61
|
*
|
|
59
62
|
* @param data - The array to chunk
|
|
60
63
|
* @param options - Chunking options
|
|
@@ -62,7 +65,11 @@ export declare function calculateOptimalChunks(totalElements: number, options?:
|
|
|
62
65
|
*/
|
|
63
66
|
export declare function chunkFloat64Array(data: Float64Array, options?: ChunkOptions): ChunkResult<Float64Array>;
|
|
64
67
|
/**
|
|
65
|
-
* Chunk a generic array into multiple smaller arrays
|
|
68
|
+
* Chunk a generic array into multiple smaller arrays.
|
|
69
|
+
*
|
|
70
|
+
* Split ranges are copies (`slice`). A single planned chunk returns `data`
|
|
71
|
+
* itself. `planChunks` is called with minimum size 0, which is not the
|
|
72
|
+
* Float64 default.
|
|
66
73
|
*
|
|
67
74
|
* @param data - The array to chunk
|
|
68
75
|
* @param options - Chunking options
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/strategies/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,uBAAuB;IACvB,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,gCAAgC;IAChC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/strategies/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,uBAAuB;IACvB,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,gCAAgC;IAChC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0FD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAgBhG;AAqDD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAClB,OAAO,GAAE,YAAiB,GACzB,WAAW,CAAC,YAAY,CAAC,CAK3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAcvE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAKtD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,GAAE,MAAc,GAAG,OAAO,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAE1D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACzB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAKzC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielsimonjr/mathts-parallel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "WebWorker parallelization for MathTS computations",
|
|
5
5
|
"author": "Daniel Simon Jr.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"README.md"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "
|
|
23
|
-
"dev": "
|
|
22
|
+
"build": "tsdown src/index.ts src/matrix.worker.ts --format esm && tsc -p tsconfig.dts.json",
|
|
23
|
+
"dev": "tsdown src/index.ts src/matrix.worker.ts --format esm --watch --on-success \"tsc -p tsconfig.dts.json\"",
|
|
24
24
|
"test": "bun test --isolate --timeout 30000",
|
|
25
25
|
"test:watch": "vitest",
|
|
26
26
|
"test:coverage": "bun test --isolate --timeout 30000 --coverage",
|
|
@@ -28,15 +28,26 @@
|
|
|
28
28
|
"lint": "oxlint src",
|
|
29
29
|
"lint:fix": "oxlint src --fix",
|
|
30
30
|
"clean": "rm -rf dist",
|
|
31
|
-
"build:prod": "
|
|
31
|
+
"build:prod": "tsdown src/index.ts src/matrix.worker.ts --format esm --minify && tsc -p tsconfig.dts.json"
|
|
32
|
+
},
|
|
33
|
+
"tsdown": {
|
|
34
|
+
"fixedExtension": false,
|
|
35
|
+
"dts": false,
|
|
36
|
+
"outputOptions": {
|
|
37
|
+
"comments": {
|
|
38
|
+
"legal": true,
|
|
39
|
+
"annotation": true,
|
|
40
|
+
"jsdoc": false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
32
43
|
},
|
|
33
44
|
"dependencies": {
|
|
34
|
-
"@danielsimonjr/mathts-workerpool": "^0.2.
|
|
35
|
-
"@danielsimonjr/mathts-core": "^0.
|
|
45
|
+
"@danielsimonjr/mathts-workerpool": "^0.2.7",
|
|
46
|
+
"@danielsimonjr/mathts-core": "^0.20.0"
|
|
36
47
|
},
|
|
37
48
|
"devDependencies": {
|
|
38
49
|
"@types/node": "^26.4.0",
|
|
39
|
-
"
|
|
50
|
+
"tsdown": "^0.23.0",
|
|
40
51
|
"typescript": "^7.0.2",
|
|
41
52
|
"vitest": "^5.0.0"
|
|
42
53
|
},
|