wgblas 2.1.0 → 2.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 (99) hide show
  1. package/README.md +2 -0
  2. package/dist/wgblas.browser.js +1007 -43
  3. package/index.d.mts +26 -53
  4. package/index.mjs +11 -0
  5. package/package.json +132 -63
  6. package/src/classes/Complex32.d.mts +43 -0
  7. package/src/classes/Complex32.mjs +82 -0
  8. package/src/classes/Complex64.d.mts +44 -0
  9. package/src/classes/Complex64.mjs +76 -0
  10. package/src/classes/GpuMatrix.d.mts +41 -41
  11. package/src/classes/GpuMatrix.mjs +112 -10
  12. package/src/classes/GpuVector.d.mts +36 -40
  13. package/src/classes/GpuVector.mjs +39 -2
  14. package/src/cscal/cscal.d.mts +47 -0
  15. package/src/cscal/cscal.mjs +98 -0
  16. package/src/dasum/dasum.mjs +31 -15
  17. package/src/daxpy/daxpy.d.mts +56 -0
  18. package/src/daxpy/daxpy.mjs +150 -0
  19. package/src/dcopy/dcopy.d.mts +52 -0
  20. package/src/dcopy/dcopy.mjs +140 -0
  21. package/src/ddot/ddot.d.mts +62 -0
  22. package/src/ddot/ddot.mjs +184 -0
  23. package/src/dnrm2/dnrm2.d.mts +50 -0
  24. package/src/dnrm2/dnrm2.mjs +189 -0
  25. package/src/drot/drot.d.mts +67 -0
  26. package/src/drot/drot.mjs +170 -0
  27. package/src/drotm/drotm.d.mts +67 -0
  28. package/src/drotm/drotm.mjs +171 -0
  29. package/src/dscal/dscal.d.mts +52 -0
  30. package/src/dscal/dscal.mjs +119 -0
  31. package/src/dswap/dswap.d.mts +57 -0
  32. package/src/dswap/dswap.mjs +155 -0
  33. package/src/idamax/idamax.mjs +49 -19
  34. package/src/init.mjs +6 -3
  35. package/src/isamax/isamax.mjs +17 -14
  36. package/src/random/random.d.mts +37 -40
  37. package/src/random/random.mjs +39 -7
  38. package/src/sasum/sasum.mjs +13 -11
  39. package/src/saxpy/saxpy.mjs +9 -8
  40. package/src/scopy/scopy.mjs +8 -6
  41. package/src/sdot/sdot.mjs +13 -11
  42. package/src/sgemm/sgemm.d.mts +2 -2
  43. package/src/sgemm/sgemm.mjs +91 -35
  44. package/src/sgemmtr/sgemmtr.d.mts +3 -2
  45. package/src/sgemmtr/sgemmtr.mjs +92 -35
  46. package/src/sgemv/sgemv.d.mts +2 -2
  47. package/src/sgemv/sgemv.mjs +41 -25
  48. package/src/sger/sger.d.mts +2 -2
  49. package/src/sger/sger.mjs +38 -16
  50. package/src/shaders/__test_pipeline_a.wgsl +3 -0
  51. package/src/shaders/__test_pipeline_b.wgsl +2 -0
  52. package/src/shaders/cscal.wgsl +33 -0
  53. package/src/shaders/daxpy.wgsl +66 -0
  54. package/src/shaders/dcopy.wgsl +34 -0
  55. package/src/shaders/ddot.wgsl +106 -0
  56. package/src/shaders/dnrm2.wgsl +167 -0
  57. package/src/shaders/drot.wgsl +81 -0
  58. package/src/shaders/drotm.wgsl +99 -0
  59. package/src/shaders/dscal.wgsl +60 -0
  60. package/src/shaders/dswap.wgsl +38 -0
  61. package/src/shaders/f64/utils/add.wgsl +6 -0
  62. package/src/shaders/f64/utils/divide.wgsl +45 -0
  63. package/src/shaders/f64/utils/multiply.wgsl +19 -10
  64. package/src/shaders/f64/utils/sqrt.wgsl +45 -0
  65. package/src/shaders/index.mjs +69 -0
  66. package/src/shaders/reduction/scaledSumF64.wgsl +93 -0
  67. package/src/snrm2/snrm2.mjs +20 -14
  68. package/src/srot/srot.mjs +10 -7
  69. package/src/srotm/srotm.mjs +9 -12
  70. package/src/sscal/sscal.mjs +7 -7
  71. package/src/sswap/sswap.mjs +14 -8
  72. package/src/ssymm/ssymm.d.mts +5 -4
  73. package/src/ssymm/ssymm.mjs +142 -55
  74. package/src/ssymv/ssymv.d.mts +2 -2
  75. package/src/ssymv/ssymv.mjs +42 -23
  76. package/src/ssyr/ssyr.d.mts +2 -2
  77. package/src/ssyr/ssyr.mjs +34 -15
  78. package/src/ssyr2/ssyr2.d.mts +2 -2
  79. package/src/ssyr2/ssyr2.mjs +43 -18
  80. package/src/ssyr2k/ssyr2k.d.mts +3 -2
  81. package/src/ssyr2k/ssyr2k.mjs +132 -55
  82. package/src/ssyrk/ssyrk.d.mts +3 -2
  83. package/src/ssyrk/ssyrk.mjs +84 -33
  84. package/src/strmm/strmm.d.mts +5 -4
  85. package/src/strmm/strmm.mjs +153 -54
  86. package/src/strmv/strmv.d.mts +2 -2
  87. package/src/strmv/strmv.mjs +37 -17
  88. package/src/strsm/strsm.d.mts +6 -4
  89. package/src/strsm/strsm.mjs +418 -172
  90. package/src/strsv/strsv.d.mts +5 -3
  91. package/src/strsv/strsv.mjs +82 -31
  92. package/src/util/benchmark.mjs +5 -3
  93. package/src/util/buffer.mjs +33 -12
  94. package/src/util/complex.mjs +87 -0
  95. package/src/util/compute.mjs +14 -8
  96. package/src/util/device.mjs +18 -3
  97. package/src/util/pipeline.mjs +40 -5
  98. package/src/util/workgroup.mjs +23 -6
  99. package/src/shaders/f64add.wgsl +0 -281
@@ -11,15 +11,27 @@ import { extractTimestamp } from "../util/benchmark.mjs";
11
11
  import { getPipeline } from "../util/pipeline.mjs";
12
12
  import { GpuVector } from "../classes/GpuVector.mjs";
13
13
  import { GpuMatrix } from "../classes/GpuMatrix.mjs";
14
- import { requireSameDevice } from "../util/device.mjs";
14
+ import { requireGpuDevice, requireSameDevice } from "../util/device.mjs";
15
15
 
16
- export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, incy, layout = "row-major") {
16
+ export async function ssymv(
17
+ device,
18
+ uplo,
19
+ n,
20
+ alpha,
21
+ A,
22
+ lda,
23
+ x,
24
+ incx,
25
+ beta,
26
+ y,
27
+ incy,
28
+ layout = "row-major",
29
+ ) {
17
30
  const xIsGpu = x instanceof GpuVector;
18
31
  const yIsGpu = y instanceof GpuVector;
19
32
  const AIsGpu = A instanceof GpuMatrix;
20
33
 
21
- if (!(device instanceof GPUDevice))
22
- throw new Error("device must be a GPUDevice.");
34
+ requireGpuDevice(device);
23
35
  requireSameDevice(device, "ssymv", { A, x, y });
24
36
  if (uplo !== "lower" && uplo !== "upper")
25
37
  throw new Error("uplo must be 'lower' or 'upper'.");
@@ -32,12 +44,10 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
32
44
  !Number.isInteger(lda)
33
45
  )
34
46
  throw new Error("n, incx, incy, and lda must be integers.");
35
- if (typeof alpha !== "number")
36
- throw new Error("alpha must be a number.");
47
+ if (typeof alpha !== "number") throw new Error("alpha must be a number.");
37
48
  if (Number.isNaN(alpha)) throw new Error("alpha must not be NaN.");
38
49
  if (!Number.isFinite(alpha)) throw new Error("alpha must be finite.");
39
- if (typeof beta !== "number")
40
- throw new Error("beta must be a number.");
50
+ if (typeof beta !== "number") throw new Error("beta must be a number.");
41
51
  if (Number.isNaN(beta)) throw new Error("beta must not be NaN.");
42
52
  if (!Number.isFinite(beta)) throw new Error("beta must be finite.");
43
53
  if (incx <= 0 || incy <= 0)
@@ -58,7 +68,9 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
58
68
  if (AIsGpu && !xIsGpu)
59
69
  throw new Error("x and y must be GpuVectors when A is a GpuMatrix.");
60
70
  if (xIsGpu && x._buf === y._buf)
61
- throw new Error("x and y must not reference the same GPU buffer when both are GpuVectors.");
71
+ throw new Error(
72
+ "x and y must not reference the same GPU buffer when both are GpuVectors.",
73
+ );
62
74
  if (AIsGpu && lda !== A.lda)
63
75
  throw new Error("lda must match A.lda when A is a GpuMatrix.");
64
76
  if (AIsGpu && (A.rows < n || A.cols < n))
@@ -67,9 +79,7 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
67
79
  if (n === 0) return yIsGpu ? {} : { y };
68
80
 
69
81
  if (!AIsGpu && A.length < (n - 1) * lda + n)
70
- throw new Error(
71
- "A does not have enough elements for the given n and lda.",
72
- );
82
+ throw new Error("A does not have enough elements for the given n and lda.");
73
83
  if (x.length < (n - 1) * incx + 1)
74
84
  throw new Error(
75
85
  "x does not have enough elements for the given n and incx.",
@@ -81,7 +91,8 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
81
91
 
82
92
  // GpuMatrix's own layout wins over the argument; A is symmetric, so column-major A reinterpreted row-major just flips which triangle is stored — flip uplo to match.
83
93
  const effLayout = AIsGpu ? A.layout : layout;
84
- const isLower = effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
94
+ const isLower =
95
+ effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
85
96
 
86
97
  const pipeline = await getPipeline(device, "ssymv");
87
98
 
@@ -94,14 +105,15 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
94
105
  ABuffer = AIsGpu ? A._buf : uploadBuffer(device, A, "ssymv-A", false);
95
106
  xBuffer = xIsGpu ? x._buf : uploadBuffer(device, x, "ssymv-x", false);
96
107
  yBuffer = yIsGpu ? y._buf : uploadBuffer(device, y, "ssymv-y", true);
97
- paramsBuffer = createParamsBuffer(device,
108
+ paramsBuffer = createParamsBuffer(
109
+ device,
98
110
  [
99
- { value: n, type: "u32" },
100
- { value: alpha, type: "f32" },
101
- { value: beta, type: "f32" },
102
- { value: incx, type: "u32" },
103
- { value: incy, type: "u32" },
104
- { value: lda, type: "u32" },
111
+ { value: n, type: "u32" },
112
+ { value: alpha, type: "f32" },
113
+ { value: beta, type: "f32" },
114
+ { value: incx, type: "u32" },
115
+ { value: incy, type: "u32" },
116
+ { value: lda, type: "u32" },
105
117
  { value: isLower ? 0 : 1, type: "u32" },
106
118
  ],
107
119
  "ssymv-params",
@@ -115,8 +127,15 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
115
127
  ]);
116
128
 
117
129
  const wgCount = Math.min(n, device.limits.maxComputeWorkgroupsPerDimension);
118
- const { commandEncoder, ts } = runComputePass(device, pipeline, bindGroup, wgCount);
119
- const readBuffer = yIsGpu ? null : stageReadback(device, commandEncoder, yBuffer);
130
+ const { commandEncoder, ts } = runComputePass(
131
+ device,
132
+ pipeline,
133
+ bindGroup,
134
+ wgCount,
135
+ );
136
+ const readBuffer = yIsGpu
137
+ ? null
138
+ : stageReadback(device, commandEncoder, yBuffer);
120
139
 
121
140
  submit(device, commandEncoder);
122
141
 
@@ -136,4 +155,4 @@ export async function ssymv(device, uplo, n, alpha, A, lda, x, incx, beta, y, in
136
155
  if (!yIsGpu && yBuffer) destroyBuffers(yBuffer);
137
156
  if (paramsBuffer) destroyBuffers(paramsBuffer);
138
157
  }
139
- }
158
+ }
@@ -2,7 +2,7 @@ import { GpuVector } from "../classes/GpuVector.mjs";
2
2
  import { GpuMatrix } from "../classes/GpuMatrix.mjs";
3
3
 
4
4
  /**
5
- * Performs the symmetric rank-1 update A = alpha * x * x^T + A
5
+ * Performs the symmetric rank-1 update $$A \leftarrow \alpha x x^{T} + A$$
6
6
  *
7
7
  * A is an n×n symmetric matrix stored in row-major order, updated in place.
8
8
  * Only the triangle specified by `uplo` is referenced and updated; the other
@@ -40,7 +40,7 @@ export declare function ssyr(
40
40
  ): Promise<{ A: Float32Array; gpuTimeMs?: number }>;
41
41
 
42
42
  /**
43
- * Performs the symmetric rank-1 update A = alpha * x * x^T + A
43
+ * Performs the symmetric rank-1 update $$A \leftarrow \alpha x x^{T} + A$$
44
44
  *
45
45
  * x and A are both kept resident on the GPU. `A`'s own `layout` (set at
46
46
  * `GpuMatrix.from` time) determines the operation — there is no separate
package/src/ssyr/ssyr.mjs CHANGED
@@ -11,14 +11,23 @@ import { extractTimestamp } from "../util/benchmark.mjs";
11
11
  import { getPipeline } from "../util/pipeline.mjs";
12
12
  import { GpuVector } from "../classes/GpuVector.mjs";
13
13
  import { GpuMatrix } from "../classes/GpuMatrix.mjs";
14
- import { requireSameDevice } from "../util/device.mjs";
14
+ import { requireGpuDevice, requireSameDevice } from "../util/device.mjs";
15
15
 
16
- export async function ssyr(device, uplo, n, alpha, x, incx, A, lda, layout = "row-major") {
16
+ export async function ssyr(
17
+ device,
18
+ uplo,
19
+ n,
20
+ alpha,
21
+ x,
22
+ incx,
23
+ A,
24
+ lda,
25
+ layout = "row-major",
26
+ ) {
17
27
  const xIsGpu = x instanceof GpuVector;
18
28
  const AIsGpu = A instanceof GpuMatrix;
19
29
 
20
- if (!(device instanceof GPUDevice))
21
- throw new Error("device must be a GPUDevice.");
30
+ requireGpuDevice(device);
22
31
  requireSameDevice(device, "ssyr", { A, x });
23
32
  if (uplo !== "lower" && uplo !== "upper")
24
33
  throw new Error("uplo must be 'lower' or 'upper'.");
@@ -26,8 +35,7 @@ export async function ssyr(device, uplo, n, alpha, x, incx, A, lda, layout = "ro
26
35
  throw new Error("layout must be 'row-major' or 'column-major'.");
27
36
  if (!Number.isInteger(n) || !Number.isInteger(incx) || !Number.isInteger(lda))
28
37
  throw new Error("n, incx, and lda must be integers.");
29
- if (typeof alpha !== "number")
30
- throw new Error("alpha must be a number.");
38
+ if (typeof alpha !== "number") throw new Error("alpha must be a number.");
31
39
  if (Number.isNaN(alpha)) throw new Error("alpha must not be NaN.");
32
40
  if (!Number.isFinite(alpha)) throw new Error("alpha must be finite.");
33
41
  if (incx <= 0) throw new Error("incx must be positive.");
@@ -52,11 +60,14 @@ export async function ssyr(device, uplo, n, alpha, x, incx, A, lda, layout = "ro
52
60
  if (!AIsGpu && A.length < (n - 1) * lda + n)
53
61
  throw new Error("A does not have enough elements for the given n and lda.");
54
62
  if (x.length < (n - 1) * incx + 1)
55
- throw new Error("x does not have enough elements for the given n and incx.");
63
+ throw new Error(
64
+ "x does not have enough elements for the given n and incx.",
65
+ );
56
66
 
57
67
  // GpuMatrix's own layout wins over the argument; A is symmetric, so column-major A reinterpreted row-major just flips which triangle is stored — flip uplo to match.
58
68
  const effLayout = AIsGpu ? A.layout : layout;
59
- const isLower = effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
69
+ const isLower =
70
+ effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
60
71
 
61
72
  const pipeline = await getPipeline(device, "ssyr");
62
73
 
@@ -67,12 +78,13 @@ export async function ssyr(device, uplo, n, alpha, x, incx, A, lda, layout = "ro
67
78
  try {
68
79
  xBuffer = xIsGpu ? x._buf : uploadBuffer(device, x, "ssyr-x", false);
69
80
  ABuffer = AIsGpu ? A._buf : uploadBuffer(device, A, "ssyr-A", true);
70
- paramsBuffer = createParamsBuffer(device,
81
+ paramsBuffer = createParamsBuffer(
82
+ device,
71
83
  [
72
- { value: n, type: "u32" },
73
- { value: alpha, type: "f32" },
74
- { value: incx, type: "u32" },
75
- { value: lda, type: "u32" },
84
+ { value: n, type: "u32" },
85
+ { value: alpha, type: "f32" },
86
+ { value: incx, type: "u32" },
87
+ { value: lda, type: "u32" },
76
88
  { value: isLower ? 0 : 1, type: "u32" },
77
89
  ],
78
90
  "ssyr-params",
@@ -87,8 +99,15 @@ export async function ssyr(device, uplo, n, alpha, x, incx, A, lda, layout = "ro
87
99
  // One workgroup per row of A; clamped to device limit — the shader's
88
100
  // grid-stride loop handles remaining rows when n > dispatch count.
89
101
  const wgCount = Math.min(n, device.limits.maxComputeWorkgroupsPerDimension);
90
- const { commandEncoder, ts } = runComputePass(device, pipeline, bindGroup, wgCount);
91
- const readBuffer = AIsGpu ? null : stageReadback(device, commandEncoder, ABuffer);
102
+ const { commandEncoder, ts } = runComputePass(
103
+ device,
104
+ pipeline,
105
+ bindGroup,
106
+ wgCount,
107
+ );
108
+ const readBuffer = AIsGpu
109
+ ? null
110
+ : stageReadback(device, commandEncoder, ABuffer);
92
111
 
93
112
  submit(device, commandEncoder);
94
113
 
@@ -2,7 +2,7 @@ import { GpuVector } from "../classes/GpuVector.mjs";
2
2
  import { GpuMatrix } from "../classes/GpuMatrix.mjs";
3
3
 
4
4
  /**
5
- * Performs the symmetric rank-2 update A = alpha * x * y^T + alpha * y * x^T + A
5
+ * Performs the symmetric rank-2 update $$A \leftarrow \alpha x y^{T} + \alpha y x^{T} + A$$
6
6
  *
7
7
  * A is an n×n symmetric matrix stored in row-major order, updated in place.
8
8
  * Only the triangle specified by `uplo` is referenced and updated; the other
@@ -44,7 +44,7 @@ export declare function ssyr2(
44
44
  ): Promise<{ A: Float32Array; gpuTimeMs?: number }>;
45
45
 
46
46
  /**
47
- * Performs the symmetric rank-2 update A = alpha * x * y^T + alpha * y * x^T + A
47
+ * Performs the symmetric rank-2 update $$A \leftarrow \alpha x y^{T} + \alpha y x^{T} + A$$
48
48
  *
49
49
  * x, y, and A are all kept resident on the GPU. `A`'s own `layout` (set at
50
50
  * `GpuMatrix.from` time) determines the operation — there is no separate
@@ -11,15 +11,26 @@ import { extractTimestamp } from "../util/benchmark.mjs";
11
11
  import { getPipeline } from "../util/pipeline.mjs";
12
12
  import { GpuVector } from "../classes/GpuVector.mjs";
13
13
  import { GpuMatrix } from "../classes/GpuMatrix.mjs";
14
- import { requireSameDevice } from "../util/device.mjs";
14
+ import { requireGpuDevice, requireSameDevice } from "../util/device.mjs";
15
15
 
16
- export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, layout = "row-major") {
16
+ export async function ssyr2(
17
+ device,
18
+ uplo,
19
+ n,
20
+ alpha,
21
+ x,
22
+ incx,
23
+ y,
24
+ incy,
25
+ A,
26
+ lda,
27
+ layout = "row-major",
28
+ ) {
17
29
  const xIsGpu = x instanceof GpuVector;
18
30
  const yIsGpu = y instanceof GpuVector;
19
31
  const AIsGpu = A instanceof GpuMatrix;
20
32
 
21
- if (!(device instanceof GPUDevice))
22
- throw new Error("device must be a GPUDevice.");
33
+ requireGpuDevice(device);
23
34
  requireSameDevice(device, "ssyr2", { A, x, y });
24
35
  if (uplo !== "lower" && uplo !== "upper")
25
36
  throw new Error("uplo must be 'lower' or 'upper'.");
@@ -32,8 +43,7 @@ export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, la
32
43
  !Number.isInteger(lda)
33
44
  )
34
45
  throw new Error("n, incx, incy, and lda must be integers.");
35
- if (typeof alpha !== "number")
36
- throw new Error("alpha must be a number.");
46
+ if (typeof alpha !== "number") throw new Error("alpha must be a number.");
37
47
  if (Number.isNaN(alpha)) throw new Error("alpha must not be NaN.");
38
48
  if (!Number.isFinite(alpha)) throw new Error("alpha must be finite.");
39
49
  if (incx <= 0 || incy <= 0)
@@ -58,7 +68,9 @@ export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, la
58
68
  if (AIsGpu && yIsGpu && A._buf === y._buf)
59
69
  throw new Error("A and y must not reference the same GPU buffer.");
60
70
  if (xIsGpu && x._buf === y._buf)
61
- throw new Error("x and y must not reference the same GPU buffer when both are GpuVectors.");
71
+ throw new Error(
72
+ "x and y must not reference the same GPU buffer when both are GpuVectors.",
73
+ );
62
74
  if (AIsGpu && lda !== A.lda)
63
75
  throw new Error("lda must match A.lda when A is a GpuMatrix.");
64
76
  if (AIsGpu && (A.rows < n || A.cols < n))
@@ -69,13 +81,18 @@ export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, la
69
81
  if (!AIsGpu && A.length < (n - 1) * lda + n)
70
82
  throw new Error("A does not have enough elements for the given n and lda.");
71
83
  if (x.length < (n - 1) * incx + 1)
72
- throw new Error("x does not have enough elements for the given n and incx.");
84
+ throw new Error(
85
+ "x does not have enough elements for the given n and incx.",
86
+ );
73
87
  if (y.length < (n - 1) * incy + 1)
74
- throw new Error("y does not have enough elements for the given n and incy.");
88
+ throw new Error(
89
+ "y does not have enough elements for the given n and incy.",
90
+ );
75
91
 
76
92
  // GpuMatrix's own layout wins over the argument; A is symmetric, so column-major A reinterpreted row-major just flips which triangle is stored (no x/y swap needed — x*y^T+y*x^T is already symmetric under swapping them).
77
93
  const effLayout = AIsGpu ? A.layout : layout;
78
- const isLower = effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
94
+ const isLower =
95
+ effLayout === "column-major" ? uplo === "upper" : uplo === "lower";
79
96
 
80
97
  const pipeline = await getPipeline(device, "ssyr2");
81
98
 
@@ -88,13 +105,14 @@ export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, la
88
105
  xBuffer = xIsGpu ? x._buf : uploadBuffer(device, x, "ssyr2-x", false);
89
106
  yBuffer = yIsGpu ? y._buf : uploadBuffer(device, y, "ssyr2-y", false);
90
107
  ABuffer = AIsGpu ? A._buf : uploadBuffer(device, A, "ssyr2-A", true);
91
- paramsBuffer = createParamsBuffer(device,
108
+ paramsBuffer = createParamsBuffer(
109
+ device,
92
110
  [
93
- { value: n, type: "u32" },
94
- { value: alpha, type: "f32" },
95
- { value: incx, type: "u32" },
96
- { value: incy, type: "u32" },
97
- { value: lda, type: "u32" },
111
+ { value: n, type: "u32" },
112
+ { value: alpha, type: "f32" },
113
+ { value: incx, type: "u32" },
114
+ { value: incy, type: "u32" },
115
+ { value: lda, type: "u32" },
98
116
  { value: isLower ? 0 : 1, type: "u32" },
99
117
  ],
100
118
  "ssyr2-params",
@@ -110,8 +128,15 @@ export async function ssyr2(device, uplo, n, alpha, x, incx, y, incy, A, lda, la
110
128
  // One workgroup per row of A; clamped to device limit — the shader's
111
129
  // grid-stride loop handles remaining rows when n > dispatch count.
112
130
  const wgCount = Math.min(n, device.limits.maxComputeWorkgroupsPerDimension);
113
- const { commandEncoder, ts } = runComputePass(device, pipeline, bindGroup, wgCount);
114
- const readBuffer = AIsGpu ? null : stageReadback(device, commandEncoder, ABuffer);
131
+ const { commandEncoder, ts } = runComputePass(
132
+ device,
133
+ pipeline,
134
+ bindGroup,
135
+ wgCount,
136
+ );
137
+ const readBuffer = AIsGpu
138
+ ? null
139
+ : stageReadback(device, commandEncoder, ABuffer);
115
140
 
116
141
  submit(device, commandEncoder);
117
142
 
@@ -2,7 +2,8 @@ import { GpuMatrix } from "../classes/GpuMatrix.mjs";
2
2
 
3
3
  /**
4
4
  * Performs the symmetric rank-2k update
5
- * C := uplo(alpha * op(A) * op(B)^T + alpha * op(B) * op(A)^T + beta * C) —
5
+ * $$C \leftarrow \mathrm{uplo}(\alpha \mathrm{op}(A) \mathrm{op}(B)^{T} + \alpha \mathrm{op}(B) \mathrm{op}(A)^{T} + \beta C)$$
6
+ *
6
7
  * only the triangle of C named by `uplo` is read or written (`'lower'`:
7
8
  * `col <= row`, `'upper'`: `col >= row`). C is always n×n.
8
9
  *
@@ -57,7 +58,7 @@ export declare function ssyr2k(
57
58
 
58
59
  /**
59
60
  * Performs the symmetric rank-2k update
60
- * C := uplo(alpha * op(A) * op(B)^T + alpha * op(B) * op(A)^T + beta * C)
61
+ * $$C \leftarrow \mathrm{uplo}(\alpha \mathrm{op}(A) \mathrm{op}(B)^{T} + \alpha \mathrm{op}(B) \mathrm{op}(A)^{T} + \beta C)$$
61
62
  *
62
63
  * A, B, and C are all kept GPU-resident. Each matrix's own `layout` (set at
63
64
  * `GpuMatrix.from` time) determines the operation — there is no separate