666db68matmul-bench: browser GEMM benchmark (JS, WebGPU, custom C WASM, libFLAME/BLIS WASM)Jeremy Magland 1# matmul-bench
3Compares matrix-matrix multiply (GEMM) performance across implementations
4running in the browser, plus a native reference measured outside it.
6**Live:** https://concept-collection.github.io/matmul-bench/
8Methods:
10- **JavaScript/TypeScript** — plain triple loop over `Float64Array` (f64), no
11 special-casing. The "no special effort" baseline.
12- **WebGPU** — a tiled compute shader (f32; WGSL has no double precision).
13- **WASM from custom C** — naive, blocked+SIMD (`f64x2`, `-msimd128`), and a
14 threaded (WASM pthreads) version of the blocked+SIMD kernel, built with
15 emscripten (f64). The threaded one needs cross-origin isolation.
16- **libFLAME/BLIS in WASM** — a real BLAS (`dgemm` via libFLAME + BLIS)
17 compiled to WebAssembly, single-threaded and multi-threaded (WASM pthreads),
18 from [libflame2wasm](https://github.com/magland/libflame2wasm) (f64). The
19 threaded build needs cross-origin isolation (SharedArrayBuffer), supplied on
20 GitHub Pages by a vendored service worker.
21- **Native LAPACK/OpenBLAS** — a fixed reference table from `dgemm` run
22 outside the browser (`native/`).
24## Develop
26```bash
27npm install
28npm run dev # local dev server (sends COOP/COEP for threaded methods)
29wasm/build-wasm.sh # rebuild wasm/dist/matmul.* + public/matmul/matmul_mt.*
30 # (needs emsdk)
31blis/build-blis-wasm.sh # rebuild public/matmul/matmul_blis_{st,mt}.* (needs emsdk
32 # + the prebuilt .a files from a sibling libflame2wasm)
33npm run build # tsc -b && vite build
34```
36The libFLAME/BLIS WASM artifacts under `public/matmul/` are committed (they link
37~30 MB of prebuilt static libraries that live in a separate
38[libflame2wasm](https://github.com/magland/libflame2wasm) checkout), so the
39GitHub Pages build doesn't rebuild them. The threaded custom module
40(`public/matmul/matmul_mt.*`) is built in CI from `wasm/matmul.c`.
42## Native reference
44```bash
45native/build.sh
46OPENBLAS_NUM_THREADS=1 native/bench_native 128 256 512 1024 2048
47OPENBLAS_NUM_THREADS=12 native/bench_native 128 256 512 1024 2048
48```
50Hand-copy the results into `src/data/nativeReference.ts`.