GPUDevice from init()
'no-transpose' for A, 'transpose' for A^T
'no-transpose' for B, 'transpose' for B^T
rows of op(A) and C
columns of op(B) and C
columns of op(A), rows of op(B)
scalar multiplier for op(A)*op(B)
Float32Array, row-major or column-major (see layout)
leading dimension of A as stored
Float32Array, row-major or column-major (see layout)
leading dimension of B as stored
scalar multiplier for C
Float32Array input/output matrix, row-major or column-major
leading dimension of C as stored
Optionallayout: "column-major" | "row-major"storage layout shared by A/B/C when they're Float32Array
(default: 'row-major'); column-major A/B flips the respective trans
flag internally, column-major C computes C^T = op(B)^T*op(A)^T instead
(same underlying bytes) — op(A)*op(B) stays what you asked for either way
updated C as a Float32Array
Performs the matrix-matrix operation C = alpha * op(A) * op(B) + beta * C
A, B, and C are all kept GPU-resident. Each matrix's own layout (set at
GpuMatrix.from time) determines the operation — there is no separate
layout argument here. A and B must be GpuMatrix whenever C is, and vice
versa — mixing a GpuMatrix with a plain Float32Array is not supported.
import { init, cleanup } from "wgblas";
import { sgemm } from "wgblas/sgemm";
import { GpuMatrix } from "wgblas/classes/GpuMatrix";
import { randomFloat32Array } from "wgblas/random";
const device = await init();
const n = 4;
const A = randomFloat32Array(n * n, -10, 10);
const B = randomFloat32Array(n * n, -10, 10);
const C = new Float32Array(n * n);
const AGpu = GpuMatrix.from(A, n, n, n, "row-major");
const BGpu = GpuMatrix.from(B, n, n, n, "row-major");
const CGpu = GpuMatrix.from(C, n, n, n, "row-major");
console.log("A:", A);
console.log("B:", B);
// results stay on the GPU between steps
await sgemm(device, "no-transpose", "no-transpose", n, n, n, 1.0, AGpu, AGpu.lda, BGpu, BGpu.lda, 0.0, CGpu, CGpu.lda); // C = A*B
await sgemm(device, "no-transpose", "no-transpose", n, n, n, 1.0, AGpu, AGpu.lda, CGpu, CGpu.lda, 0.0, BGpu, BGpu.lda); // B = A*C = A²*B
// single readback
const result = await BGpu.read();
console.log("A²B:", result);
AGpu.destroy();
BGpu.destroy();
CGpu.destroy();
if (typeof process !== "undefined") cleanup();
GPUDevice from init()
'no-transpose' for A, 'transpose' for A^T
'no-transpose' for B, 'transpose' for B^T
rows of op(A) and C
columns of op(B) and C
columns of op(A), rows of op(B)
scalar multiplier for op(A)*op(B)
GpuMatrix
leading dimension of A (must equal A.lda)
GpuMatrix
leading dimension of B (must equal B.lda)
scalar multiplier for C
GpuMatrix (mutated in place)
leading dimension of C (must equal C.lda)
no C — it stays GPU-resident; call C.read() yourself for a CPU readback (see the example)
Performs the matrix-matrix operation C = alpha * op(A) * op(B) + beta * C
transA/transB='no-transpose': op(A) = A (m×k), op(B) = B (k×n)transA/transB='transpose': op(A) = A^T, op(B) = B^TA, B, C are row-major or column-major (see
layout) — backed by one of two shared-memory-tiled, register-blocked kernels chosen by shape:sgemm_small.wgsl(BM=BN=32) below a 6x6 workgroup grid,sgemm_large.wgsl(BM=BN=64) above it.Browser (standalone HTML):