wgblas 0.1.2 → 1.0.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 (55) hide show
  1. package/README.md +3 -0
  2. package/dist/wgblas.browser.js +1078 -37
  3. package/index.d.mts +6 -0
  4. package/index.mjs +6 -0
  5. package/package.json +32 -1
  6. package/src/classes/GpuMatrix.d.mts +85 -0
  7. package/src/classes/GpuMatrix.mjs +91 -0
  8. package/src/classes/GpuVector.d.mts +11 -7
  9. package/src/classes/GpuVector.mjs +31 -5
  10. package/src/dasum/dasum.d.mts +48 -0
  11. package/src/dasum/dasum.mjs +121 -0
  12. package/src/init.mjs +3 -1
  13. package/src/isamax/isamax.mjs +66 -67
  14. package/src/random/random.d.mts +37 -0
  15. package/src/random/random.mjs +17 -0
  16. package/src/sasum/sasum.mjs +55 -51
  17. package/src/saxpy/saxpy.mjs +48 -35
  18. package/src/scopy/scopy.mjs +43 -32
  19. package/src/sdot/sdot.mjs +60 -55
  20. package/src/sgemv/sgemv.d.mts +118 -0
  21. package/src/sgemv/sgemv.mjs +141 -0
  22. package/src/shaders/browser-shaders.mjs +20 -0
  23. package/src/shaders/dasum.wgsl +98 -0
  24. package/src/shaders/f64add.wgsl +281 -0
  25. package/src/shaders/isamax.wgsl +32 -9
  26. package/src/shaders/reduction/sumF64.wgsl +49 -0
  27. package/src/shaders/sasum.wgsl +18 -4
  28. package/src/shaders/sdot.wgsl +18 -4
  29. package/src/shaders/sgemv_n.wgsl +75 -0
  30. package/src/shaders/sgemv_t.wgsl +65 -0
  31. package/src/shaders/snrm2.wgsl +22 -4
  32. package/src/shaders/ssymv.wgsl +69 -0
  33. package/src/shaders/strmv.wgsl +103 -0
  34. package/src/shaders/strsv_apply_inverse.wgsl +47 -0
  35. package/src/shaders/strsv_invert_block.wgsl +109 -0
  36. package/src/shaders/strsv_update.wgsl +75 -0
  37. package/src/snrm2/snrm2.mjs +56 -52
  38. package/src/srot/srot.mjs +57 -41
  39. package/src/srotm/srotm.mjs +54 -38
  40. package/src/sscal/sscal.mjs +43 -32
  41. package/src/sswap/sswap.mjs +49 -34
  42. package/src/ssymv/ssymv.d.mts +109 -0
  43. package/src/ssymv/ssymv.mjs +130 -0
  44. package/src/strmv/strmv.d.mts +109 -0
  45. package/src/strmv/strmv.mjs +132 -0
  46. package/src/strsv/strsv.d.mts +98 -0
  47. package/src/strsv/strsv.mjs +212 -0
  48. package/src/util/benchmark.mjs +1 -1
  49. package/src/util/bindgroup.mjs +14 -10
  50. package/src/util/buffer.mjs +7 -2
  51. package/src/util/compute.mjs +41 -15
  52. package/src/util/f64pack.mjs +152 -0
  53. package/src/util/pipeline.mjs +32 -17
  54. package/src/util/result.mjs +8 -4
  55. package/src/util/workgroup.mjs +10 -10
@@ -0,0 +1,109 @@
1
+ import { GpuVector } from "../classes/GpuVector.mjs";
2
+ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
3
+
4
+ /**
5
+ * Performs the symmetric matrix-vector operation y = alpha * A * x + beta * y
6
+ *
7
+ * A is an n×n symmetric matrix stored in row-major order. Only the triangle
8
+ * specified by `uplo` is referenced; the other triangle is inferred by symmetry.
9
+ *
10
+ * {@includeCode ../../examples/ssymv/ssymv.js}
11
+ *
12
+ * **Browser (standalone HTML):**
13
+ * {@includeCode ../../examples/ssymv/web/ssymv.html}
14
+ *
15
+ * @param device - GPUDevice from `init()`
16
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
17
+ * @param n - order of the matrix A (number of rows and columns)
18
+ * @param alpha - scalar multiplier for A*x
19
+ * @param A - Float32Array or GpuMatrix, row-major, at least (n-1)*lda+n elements
20
+ * @param lda - leading dimension of A (>= n)
21
+ * @param x - Float32Array input vector, length at least (n-1)*incx+1
22
+ * @param incx - stride for x (must be a positive integer)
23
+ * @param beta - scalar multiplier for y
24
+ * @param y - Float32Array input/output vector, length at least (n-1)*incy+1
25
+ * @param incy - stride for y (must be a positive integer)
26
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/ssymv/ssymv.mjs#L15">Source code: ssymv.mjs (L15)</a>
27
+ * @category BLAS Level 2
28
+ */
29
+ export declare function ssymv(
30
+ device: GPUDevice,
31
+ uplo: 'lower' | 'upper',
32
+ n: number,
33
+ alpha: number,
34
+ A: Float32Array | GpuMatrix,
35
+ lda: number,
36
+ x: Float32Array,
37
+ incx: number,
38
+ beta: number,
39
+ y: Float32Array,
40
+ incy: number,
41
+ ): Promise<{ y: Float32Array; gpuTimeMs?: number }>;
42
+
43
+ /**
44
+ * Performs the symmetric matrix-vector operation y = alpha * A * x + beta * y
45
+ *
46
+ * A is kept GPU-resident; x and y are CPU Float32Arrays.
47
+ *
48
+ * @param device - GPUDevice from `init()`
49
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
50
+ * @param n - order of the matrix A
51
+ * @param alpha - scalar multiplier for A*x
52
+ * @param A - GpuMatrix, row-major, GPU-resident
53
+ * @param lda - leading dimension of A (must equal A.lda)
54
+ * @param x - Float32Array input vector
55
+ * @param incx - stride for x (must be a positive integer)
56
+ * @param beta - scalar multiplier for y
57
+ * @param y - Float32Array input/output vector
58
+ * @param incy - stride for y (must be a positive integer)
59
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/ssymv/ssymv.mjs#L15">Source code: ssymv.mjs (L15)</a>
60
+ * @category BLAS Level 2
61
+ */
62
+ export declare function ssymv(
63
+ device: GPUDevice,
64
+ uplo: 'lower' | 'upper',
65
+ n: number,
66
+ alpha: number,
67
+ A: GpuMatrix,
68
+ lda: number,
69
+ x: Float32Array,
70
+ incx: number,
71
+ beta: number,
72
+ y: Float32Array,
73
+ incy: number,
74
+ ): Promise<{ y: Float32Array; gpuTimeMs?: number }>;
75
+
76
+ /**
77
+ * Performs the symmetric matrix-vector operation y = alpha * A * x + beta * y
78
+ *
79
+ * x and y are kept resident on the GPU. A must be a GpuMatrix.
80
+ *
81
+ * {@includeCode ../../examples/ssymv/gpuvec.ssymv.js}
82
+ *
83
+ * @param device - GPUDevice from `init()`
84
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
85
+ * @param n - order of the matrix A
86
+ * @param alpha - scalar multiplier for A*x
87
+ * @param A - GpuMatrix, row-major, GPU-resident
88
+ * @param lda - leading dimension of A (must equal A.lda)
89
+ * @param x - GpuVector input vector (not mutated)
90
+ * @param incx - stride for x (must be a positive integer)
91
+ * @param beta - scalar multiplier for y
92
+ * @param y - GpuVector input/output vector (mutated in place)
93
+ * @param incy - stride for y (must be a positive integer)
94
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/ssymv/ssymv.mjs#L15">Source code: ssymv.mjs (L15)</a>
95
+ * @category BLAS Level 2
96
+ */
97
+ export declare function ssymv(
98
+ device: GPUDevice,
99
+ uplo: 'lower' | 'upper',
100
+ n: number,
101
+ alpha: number,
102
+ A: GpuMatrix,
103
+ lda: number,
104
+ x: GpuVector,
105
+ incx: number,
106
+ beta: number,
107
+ y: GpuVector,
108
+ incy: number,
109
+ ): Promise<{ gpuTimeMs?: number }>;
@@ -0,0 +1,130 @@
1
+ import {
2
+ uploadBuffer,
3
+ createParamsBuffer,
4
+ stageReadback,
5
+ destroyBuffers,
6
+ } from "../util/buffer.mjs";
7
+ import { createBindGroup } from "../util/bindgroup.mjs";
8
+ import { runComputePass, submit } from "../util/compute.mjs";
9
+ import { extractResult } from "../util/result.mjs";
10
+ import { extractTimestamp } from "../util/benchmark.mjs";
11
+ import { getPipeline } from "../util/pipeline.mjs";
12
+ import { GpuVector } from "../classes/GpuVector.mjs";
13
+ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
14
+
15
+ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, incy) {
16
+ const xIsGpu = x instanceof GpuVector;
17
+ const yIsGpu = y instanceof GpuVector;
18
+ const AIsGpu = A instanceof GpuMatrix;
19
+ const isLower = uplo === "lower";
20
+
21
+ if (!(device instanceof GPUDevice))
22
+ throw new Error("device must be a GPUDevice.");
23
+ if (!isLower && uplo !== "upper")
24
+ throw new Error("uplo must be 'lower' or 'upper'.");
25
+ if (
26
+ !Number.isInteger(n) ||
27
+ !Number.isInteger(incx) ||
28
+ !Number.isInteger(incy) ||
29
+ !Number.isInteger(lda)
30
+ )
31
+ throw new Error("n, incx, incy, and lda must be integers.");
32
+ if (typeof alpha !== "number")
33
+ throw new Error("alpha must be a number.");
34
+ if (Number.isNaN(alpha)) throw new Error("alpha must not be NaN.");
35
+ if (!Number.isFinite(alpha)) throw new Error("alpha must be finite.");
36
+ if (typeof beta !== "number")
37
+ throw new Error("beta must be a number.");
38
+ if (Number.isNaN(beta)) throw new Error("beta must not be NaN.");
39
+ if (!Number.isFinite(beta)) throw new Error("beta must be finite.");
40
+ if (incx <= 0 || incy <= 0)
41
+ throw new Error("incx and incy must be positive.");
42
+ if (lda < n) throw new Error("lda must be >= n.");
43
+ if (!AIsGpu && !(A instanceof Float32Array))
44
+ throw new Error("A must be a Float32Array or GpuMatrix.");
45
+ if (!xIsGpu && !(x instanceof Float32Array))
46
+ throw new Error("x must be a Float32Array or GpuVector.");
47
+ if (!yIsGpu && !(y instanceof Float32Array))
48
+ throw new Error("y must be a Float32Array or GpuVector.");
49
+ if (xIsGpu !== yIsGpu)
50
+ throw new Error(
51
+ "x and y must be the same type (both Float32Array or both GpuVector).",
52
+ );
53
+ if (xIsGpu && !AIsGpu)
54
+ throw new Error("A must be a GpuMatrix when x and y are GpuVectors.");
55
+ if (xIsGpu && x._buf === y._buf)
56
+ throw new Error("x and y must not reference the same GPU buffer when both are GpuVectors.");
57
+ if (AIsGpu && lda !== A.lda)
58
+ throw new Error("lda must match A.lda when A is a GpuMatrix.");
59
+ if (AIsGpu && (A.rows < n || A.cols < n))
60
+ throw new Error("A is too small for the given n.");
61
+ if (n < 0) throw new Error("n must be non-negative.");
62
+ if (n === 0) return yIsGpu ? {} : { y };
63
+
64
+ if (!AIsGpu && A.length < (n - 1) * lda + n)
65
+ throw new Error(
66
+ "A does not have enough elements for the given n and lda.",
67
+ );
68
+ if (x.length < (n - 1) * incx + 1)
69
+ throw new Error(
70
+ "x does not have enough elements for the given n and incx.",
71
+ );
72
+ if (y.length < (n - 1) * incy + 1)
73
+ throw new Error(
74
+ "y does not have enough elements for the given n and incy.",
75
+ );
76
+
77
+ const pipeline = await getPipeline(device, "ssymv");
78
+
79
+ let ABuffer = null;
80
+ let xBuffer = null;
81
+ let yBuffer = null;
82
+ let paramsBuffer = null;
83
+
84
+ try {
85
+ ABuffer = AIsGpu ? A._buf : uploadBuffer(A, "ssymv-A", false);
86
+ xBuffer = xIsGpu ? x._buf : uploadBuffer(x, "ssymv-x", false);
87
+ yBuffer = yIsGpu ? y._buf : uploadBuffer(y, "ssymv-y", true);
88
+ paramsBuffer = createParamsBuffer(
89
+ [
90
+ { value: n, type: "u32" },
91
+ { value: alpha, type: "f32" },
92
+ { value: beta, type: "f32" },
93
+ { value: incx, type: "u32" },
94
+ { value: incy, type: "u32" },
95
+ { value: lda, type: "u32" },
96
+ { value: isLower ? 0 : 1, type: "u32" },
97
+ ],
98
+ "ssymv-params",
99
+ );
100
+
101
+ const bindGroup = createBindGroup(pipeline.getBindGroupLayout(0), [
102
+ ABuffer,
103
+ xBuffer,
104
+ yBuffer,
105
+ paramsBuffer,
106
+ ]);
107
+
108
+ const wgCount = Math.min(n, device.limits.maxComputeWorkgroupsPerDimension);
109
+ const { commandEncoder, ts } = runComputePass(pipeline, bindGroup, wgCount);
110
+ const readBuffer = yIsGpu ? null : stageReadback(commandEncoder, yBuffer);
111
+
112
+ submit(commandEncoder);
113
+
114
+ const gpuTimeMs = await extractTimestamp(ts);
115
+
116
+ if (yIsGpu) {
117
+ if (gpuTimeMs !== undefined) return { gpuTimeMs };
118
+ return {};
119
+ }
120
+
121
+ const result = await extractResult(readBuffer, Float32Array);
122
+ if (gpuTimeMs !== undefined) return { y: result, gpuTimeMs };
123
+ return { y: result };
124
+ } finally {
125
+ if (!AIsGpu && ABuffer) destroyBuffers(ABuffer);
126
+ if (!xIsGpu && xBuffer) destroyBuffers(xBuffer);
127
+ if (!yIsGpu && yBuffer) destroyBuffers(yBuffer);
128
+ if (paramsBuffer) destroyBuffers(paramsBuffer);
129
+ }
130
+ }
@@ -0,0 +1,109 @@
1
+ import { GpuVector } from "../classes/GpuVector.mjs";
2
+ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
3
+
4
+ /**
5
+ * Performs the triangular matrix-vector operation y = op(A) * x
6
+ *
7
+ * A is an n×n triangular matrix stored in row-major order. Only the triangle
8
+ * specified by `uplo` is referenced; the other triangle is not accessed.
9
+ *
10
+ * {@includeCode ../../examples/strmv/strmv.js}
11
+ *
12
+ * **Browser (standalone HTML):**
13
+ * {@includeCode ../../examples/strmv/web/strmv.html}
14
+ *
15
+ * @param device - GPUDevice from `init()`
16
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
17
+ * @param trans - `'no-transpose'` for A, `'transpose'` for A^T
18
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
19
+ * @param n - order of the matrix A (number of rows and columns)
20
+ * @param A - Float32Array or GpuMatrix, row-major, at least (n-1)*lda+n elements
21
+ * @param lda - leading dimension of A (>= n)
22
+ * @param x - Float32Array input vector, length at least (n-1)*incx+1
23
+ * @param incx - stride for x (must be a positive integer)
24
+ * @param y - Float32Array output vector, length at least (n-1)*incy+1
25
+ * @param incy - stride for y (must be a positive integer)
26
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strmv/strmv.mjs#L15">Source code: strmv.mjs (L15)</a>
27
+ * @category BLAS Level 2
28
+ */
29
+ export declare function strmv(
30
+ device: GPUDevice,
31
+ uplo: 'lower' | 'upper',
32
+ trans: 'no-transpose' | 'transpose',
33
+ diag: 'unit' | 'non-unit',
34
+ n: number,
35
+ A: Float32Array | GpuMatrix,
36
+ lda: number,
37
+ x: Float32Array,
38
+ incx: number,
39
+ y: Float32Array,
40
+ incy: number,
41
+ ): Promise<{ y: Float32Array; gpuTimeMs?: number }>;
42
+
43
+ /**
44
+ * Performs the triangular matrix-vector operation y = op(A) * x
45
+ *
46
+ * A is kept GPU-resident; x and y are CPU Float32Arrays.
47
+ *
48
+ * @param device - GPUDevice from `init()`
49
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
50
+ * @param trans - `'no-transpose'` for A, `'transpose'` for A^T
51
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
52
+ * @param n - order of the matrix A
53
+ * @param A - GpuMatrix, row-major, GPU-resident
54
+ * @param lda - leading dimension of A (must equal A.lda)
55
+ * @param x - Float32Array input vector
56
+ * @param incx - stride for x (must be a positive integer)
57
+ * @param y - Float32Array output vector
58
+ * @param incy - stride for y (must be a positive integer)
59
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strmv/strmv.mjs#L15">Source code: strmv.mjs (L15)</a>
60
+ * @category BLAS Level 2
61
+ */
62
+ export declare function strmv(
63
+ device: GPUDevice,
64
+ uplo: 'lower' | 'upper',
65
+ trans: 'no-transpose' | 'transpose',
66
+ diag: 'unit' | 'non-unit',
67
+ n: number,
68
+ A: GpuMatrix,
69
+ lda: number,
70
+ x: Float32Array,
71
+ incx: number,
72
+ y: Float32Array,
73
+ incy: number,
74
+ ): Promise<{ y: Float32Array; gpuTimeMs?: number }>;
75
+
76
+ /**
77
+ * Performs the triangular matrix-vector operation y = op(A) * x
78
+ *
79
+ * x and y are kept resident on the GPU. A must be a GpuMatrix.
80
+ *
81
+ * {@includeCode ../../examples/strmv/gpuvec.strmv.js}
82
+ *
83
+ * @param device - GPUDevice from `init()`
84
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
85
+ * @param trans - `'no-transpose'` for A, `'transpose'` for A^T
86
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
87
+ * @param n - order of the matrix A
88
+ * @param A - GpuMatrix, row-major, GPU-resident
89
+ * @param lda - leading dimension of A (must equal A.lda)
90
+ * @param x - GpuVector input vector (not mutated)
91
+ * @param incx - stride for x (must be a positive integer)
92
+ * @param y - GpuVector output vector (mutated in place)
93
+ * @param incy - stride for y (must be a positive integer)
94
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strmv/strmv.mjs#L15">Source code: strmv.mjs (L15)</a>
95
+ * @category BLAS Level 2
96
+ */
97
+ export declare function strmv(
98
+ device: GPUDevice,
99
+ uplo: 'lower' | 'upper',
100
+ trans: 'no-transpose' | 'transpose',
101
+ diag: 'unit' | 'non-unit',
102
+ n: number,
103
+ A: GpuMatrix,
104
+ lda: number,
105
+ x: GpuVector,
106
+ incx: number,
107
+ y: GpuVector,
108
+ incy: number,
109
+ ): Promise<{ gpuTimeMs?: number }>;
@@ -0,0 +1,132 @@
1
+ import {
2
+ uploadBuffer,
3
+ createParamsBuffer,
4
+ stageReadback,
5
+ destroyBuffers,
6
+ } from "../util/buffer.mjs";
7
+ import { createBindGroup } from "../util/bindgroup.mjs";
8
+ import { runComputePass, submit } from "../util/compute.mjs";
9
+ import { extractResult } from "../util/result.mjs";
10
+ import { extractTimestamp } from "../util/benchmark.mjs";
11
+ import { getPipeline } from "../util/pipeline.mjs";
12
+ import { GpuVector } from "../classes/GpuVector.mjs";
13
+ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
14
+
15
+ export async function strmv(device, uplo, trans, diag, n, A, lda, x, incx, y, incy) {
16
+ const xIsGpu = x instanceof GpuVector;
17
+ const yIsGpu = y instanceof GpuVector;
18
+ const AIsGpu = A instanceof GpuMatrix;
19
+ const isLower = uplo === "lower";
20
+ const isNoTrans = trans === "no-transpose";
21
+ const isUnit = diag === "unit";
22
+
23
+ if (!(device instanceof GPUDevice))
24
+ throw new Error("device must be a GPUDevice.");
25
+ if (!isLower && uplo !== "upper")
26
+ throw new Error("uplo must be 'lower' or 'upper'.");
27
+ if (!isNoTrans && trans !== "transpose")
28
+ throw new Error("trans must be 'no-transpose' or 'transpose'.");
29
+ if (!isUnit && diag !== "non-unit")
30
+ throw new Error("diag must be 'unit' or 'non-unit'.");
31
+ if (
32
+ !Number.isInteger(n) ||
33
+ !Number.isInteger(incx) ||
34
+ !Number.isInteger(incy) ||
35
+ !Number.isInteger(lda)
36
+ )
37
+ throw new Error("n, incx, incy, and lda must be integers.");
38
+ if (incx <= 0 || incy <= 0)
39
+ throw new Error("incx and incy must be positive.");
40
+ if (lda < n) throw new Error("lda must be >= n.");
41
+ if (!AIsGpu && !(A instanceof Float32Array))
42
+ throw new Error("A must be a Float32Array or GpuMatrix.");
43
+ if (!xIsGpu && !(x instanceof Float32Array))
44
+ throw new Error("x must be a Float32Array or GpuVector.");
45
+ if (!yIsGpu && !(y instanceof Float32Array))
46
+ throw new Error("y must be a Float32Array or GpuVector.");
47
+ if (xIsGpu !== yIsGpu)
48
+ throw new Error(
49
+ "x and y must be the same type (both Float32Array or both GpuVector).",
50
+ );
51
+ if (xIsGpu && x._buf === y._buf)
52
+ throw new Error(
53
+ "x and y must not reference the same GPU buffer when both are GpuVectors.",
54
+ );
55
+ if (xIsGpu && !AIsGpu)
56
+ throw new Error("A must be a GpuMatrix when x and y are GpuVectors.");
57
+ if (AIsGpu && yIsGpu && A._buf === y._buf)
58
+ throw new Error("A and y must not reference the same GPU buffer.");
59
+ if (AIsGpu && lda !== A.lda)
60
+ throw new Error("lda must match A.lda when A is a GpuMatrix.");
61
+ if (AIsGpu && (A.rows < n || A.cols < n))
62
+ throw new Error("A is too small for the given n.");
63
+ if (n < 0) throw new Error("n must be non-negative.");
64
+ if (n === 0) return yIsGpu ? {} : { y };
65
+
66
+ if (!AIsGpu && A.length < (n - 1) * lda + n)
67
+ throw new Error(
68
+ "A does not have enough elements for the given n and lda.",
69
+ );
70
+ if (x.length < (n - 1) * incx + 1)
71
+ throw new Error(
72
+ "x does not have enough elements for the given n and incx.",
73
+ );
74
+ if (y.length < (n - 1) * incy + 1)
75
+ throw new Error(
76
+ "y does not have enough elements for the given n and incy.",
77
+ );
78
+
79
+ const pipeline = await getPipeline(device, "strmv");
80
+
81
+ let ABuffer = null;
82
+ let xBuffer = null;
83
+ let yBuffer = null;
84
+ let paramsBuffer = null;
85
+
86
+ try {
87
+ ABuffer = AIsGpu ? A._buf : uploadBuffer(A, "strmv-A", false);
88
+ xBuffer = xIsGpu ? x._buf : uploadBuffer(x, "strmv-x", false);
89
+ yBuffer = yIsGpu ? y._buf : uploadBuffer(y, "strmv-y", true);
90
+ paramsBuffer = createParamsBuffer(
91
+ [
92
+ { value: n, type: "u32" },
93
+ { value: incx, type: "u32" },
94
+ { value: incy, type: "u32" },
95
+ { value: lda, type: "u32" },
96
+ { value: isNoTrans ? 0 : 1, type: "u32" },
97
+ { value: isLower ? 0 : 1, type: "u32" },
98
+ { value: isUnit ? 1 : 0, type: "u32" },
99
+ ],
100
+ "strmv-params",
101
+ );
102
+
103
+ const bindGroup = createBindGroup(pipeline.getBindGroupLayout(0), [
104
+ ABuffer,
105
+ xBuffer,
106
+ yBuffer,
107
+ paramsBuffer,
108
+ ]);
109
+
110
+ const wgCount = Math.min(n, device.limits.maxComputeWorkgroupsPerDimension);
111
+ const { commandEncoder, ts } = runComputePass(pipeline, bindGroup, wgCount);
112
+ const readBuffer = yIsGpu ? null : stageReadback(commandEncoder, yBuffer);
113
+
114
+ submit(commandEncoder);
115
+
116
+ const gpuTimeMs = await extractTimestamp(ts);
117
+
118
+ if (yIsGpu) {
119
+ if (gpuTimeMs !== undefined) return { gpuTimeMs };
120
+ return {};
121
+ }
122
+
123
+ const result = await extractResult(readBuffer, Float32Array);
124
+ if (gpuTimeMs !== undefined) return { y: result, gpuTimeMs };
125
+ return { y: result };
126
+ } finally {
127
+ if (!AIsGpu && ABuffer) destroyBuffers(ABuffer);
128
+ if (!xIsGpu && xBuffer) destroyBuffers(xBuffer);
129
+ if (!yIsGpu && yBuffer) destroyBuffers(yBuffer);
130
+ if (paramsBuffer) destroyBuffers(paramsBuffer);
131
+ }
132
+ }
@@ -0,0 +1,98 @@
1
+ import { GpuVector } from "../classes/GpuVector.mjs";
2
+ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
3
+
4
+ /**
5
+ * Solves the triangular system op(A) * x = b for x, in place (x holds b on
6
+ * input, the solution on output).
7
+ *
8
+ * A is an n×n triangular matrix stored in row-major order. Only the triangle
9
+ * specified by `uplo` is referenced; the other triangle is not accessed.
10
+ *
11
+ * {@includeCode ../../examples/strsv/strsv.js}
12
+ *
13
+ * **Browser (standalone HTML):**
14
+ * {@includeCode ../../examples/strsv/web/strsv.html}
15
+ *
16
+ * @param device - GPUDevice from `init()`
17
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
18
+ * @param trans - `'no-transpose'` to solve A*x=b, `'transpose'` to solve A^T*x=b
19
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
20
+ * @param n - order of the matrix A (number of rows and columns)
21
+ * @param A - Float32Array or GpuMatrix, row-major, at least (n-1)*lda+n elements
22
+ * @param lda - leading dimension of A (>= n)
23
+ * @param x - Float32Array holding b on input, the solution on output; length at least (n-1)*incx+1
24
+ * @param incx - stride for x (must be a positive integer)
25
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strsv/strsv.mjs#L15">Source code: strsv.mjs (L15)</a>
26
+ * @category BLAS Level 2
27
+ */
28
+ export declare function strsv(
29
+ device: GPUDevice,
30
+ uplo: 'lower' | 'upper',
31
+ trans: 'no-transpose' | 'transpose',
32
+ diag: 'unit' | 'non-unit',
33
+ n: number,
34
+ A: Float32Array | GpuMatrix,
35
+ lda: number,
36
+ x: Float32Array,
37
+ incx: number,
38
+ ): Promise<{ x: Float32Array; gpuTimeMs?: number }>;
39
+
40
+ /**
41
+ * Solves the triangular system op(A) * x = b for x, in place.
42
+ *
43
+ * A is kept GPU-resident; x is a CPU Float32Array.
44
+ *
45
+ * @param device - GPUDevice from `init()`
46
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
47
+ * @param trans - `'no-transpose'` to solve A*x=b, `'transpose'` to solve A^T*x=b
48
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
49
+ * @param n - order of the matrix A
50
+ * @param A - GpuMatrix, row-major, GPU-resident
51
+ * @param lda - leading dimension of A (must equal A.lda)
52
+ * @param x - Float32Array holding b on input, the solution on output
53
+ * @param incx - stride for x (must be a positive integer)
54
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strsv/strsv.mjs#L15">Source code: strsv.mjs (L15)</a>
55
+ * @category BLAS Level 2
56
+ */
57
+ export declare function strsv(
58
+ device: GPUDevice,
59
+ uplo: 'lower' | 'upper',
60
+ trans: 'no-transpose' | 'transpose',
61
+ diag: 'unit' | 'non-unit',
62
+ n: number,
63
+ A: GpuMatrix,
64
+ lda: number,
65
+ x: Float32Array,
66
+ incx: number,
67
+ ): Promise<{ x: Float32Array; gpuTimeMs?: number }>;
68
+
69
+ /**
70
+ * Solves the triangular system op(A) * x = b for x, in place.
71
+ *
72
+ * x is kept resident on the GPU (mutated in place). A must be a GpuMatrix.
73
+ *
74
+ * {@includeCode ../../examples/strsv/gpuvec.strsv.js}
75
+ *
76
+ * @param device - GPUDevice from `init()`
77
+ * @param uplo - `'lower'` to use the lower triangle, `'upper'` to use the upper triangle
78
+ * @param trans - `'no-transpose'` to solve A*x=b, `'transpose'` to solve A^T*x=b
79
+ * @param diag - `'unit'` to treat the diagonal as all-ones (A's diagonal is not read), `'non-unit'` to read it
80
+ * @param n - order of the matrix A
81
+ * @param A - GpuMatrix, row-major, GPU-resident
82
+ * @param lda - leading dimension of A (must equal A.lda)
83
+ * @param x - GpuVector holding b on input, the solution on output (mutated in place)
84
+ * @param incx - stride for x (must be a positive integer)
85
+ * @see <a href="https://github.com/manit2004/wgblas/blob/main/src/strsv/strsv.mjs#L15">Source code: strsv.mjs (L15)</a>
86
+ * @category BLAS Level 2
87
+ */
88
+ export declare function strsv(
89
+ device: GPUDevice,
90
+ uplo: 'lower' | 'upper',
91
+ trans: 'no-transpose' | 'transpose',
92
+ diag: 'unit' | 'non-unit',
93
+ n: number,
94
+ A: GpuMatrix,
95
+ lda: number,
96
+ x: GpuVector,
97
+ incx: number,
98
+ ): Promise<{ gpuTimeMs?: number }>;