/ concept-collection / matmul-bench
Sign in
concept-collection / matmul-bench
Widen results layout and add CSV export
- Page container md -> xl so the 8-column results table has room; prose blocks capped at 900px for readability. - Download CSV button (tidy long format: n, method, precision, gflops, ms, checksum), enabled once results exist.
Jeremy Magland <jmagland@flatironinstitute.org> committed commit e1207942b58a parent 666db68 Browse files
2 changed files+37−6
src/App.tsxmodified+4−4View file
@@ -22,8 +22,8 @@ function App() {
2222 </Toolbar>
2323 </AppBar>
2424
25- <Container maxWidth="md" sx={{ py: 3 }}>
26- <Typography variant="body1" sx={{ mb: 2 }}>
25+ <Container maxWidth="xl" sx={{ py: 3 }}>
26+ <Typography variant="body1" sx={{ mb: 2, maxWidth: 900 }}>
2727 Compares n×n matrix-matrix multiply (GEMM) across implementations
2828 running in the browser — plain JavaScript/TypeScript, a WebGPU
2929 compute shader, hand-optimized C compiled to WebAssembly (including a
@@ -35,7 +35,7 @@ function App() {
3535 <BenchmarkRunner />
3636
3737 <Typography variant="h6" sx={{ mt: 4, mb: 1 }}>Native reference: OpenBLAS dgemm</Typography>
38- <Typography variant="caption" color="text.secondary" component="div" sx={{ mb: 1 }}>
38+ <Typography variant="caption" color="text.secondary" component="div" sx={{ mb: 1, maxWidth: 900 }}>
3939 Measured with <code>native/bench_native.c</code> outside the browser on one
4040 Linux desktop — hardware-dependent, for rough comparison only. Regenerate with{' '}
4141 <code>native/build.sh && native/bench_native</code>.
@@ -69,7 +69,7 @@ function App() {
6969 column is slower than 1 thread below n≈512 on this machine.
7070 </Typography>
7171
72- <Typography variant="body2" color="text.secondary" sx={{ mt: 3 }}>
72+ <Typography variant="body2" color="text.secondary" sx={{ mt: 3, maxWidth: 900 }}>
7373 The threaded methods (custom C and libFLAME/BLIS) use WASM pthreads
7474 (Web Workers + SharedArrayBuffer) and need cross-origin isolation,
7575 provided here by a service worker; pick the thread count above. The
src/components/BenchmarkRunner.tsxmodified+33−2View file
@@ -118,9 +118,34 @@ export function BenchmarkRunner() {
118118 })
119119 }
120120
121+ const hasResults = Object.values(results).some(
122+ (byN) => byN && Object.values(byN).some((c) => c && typeof c === 'object'),
123+ )
124+
125+ // Tidy (long) CSV of every measured cell. Method labels carry the thread
126+ // count (from displayMethods), so no separate threads column is needed.
127+ const downloadCsv = () => {
128+ const esc = (s: string) => (/[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s)
129+ const lines = ['n,method,precision,gflops,ms,checksum']
130+ for (const n of ALL_SIZES) {
131+ for (const m of displayMethods) {
132+ const r = results[m.id]?.[n]
133+ if (r && typeof r === 'object') {
134+ lines.push([n, esc(m.label), m.precision, r.gflops.toFixed(4), r.ms.toFixed(3), r.sample].join(','))
135+ }
136+ }
137+ }
138+ const blob = new Blob([lines.join('\n')], { type: 'text/csv' })
139+ const a = document.createElement('a')
140+ a.href = URL.createObjectURL(blob)
141+ a.download = 'matmul-bench-results.csv'
142+ a.click()
143+ URL.revokeObjectURL(a.href)
144+ }
145+
121146 return (
122147 <Stack spacing={2}>
123- <Typography variant="body2" color="text.secondary">
148+ <Typography variant="body2" color="text.secondary" sx={{ maxWidth: 900 }}>
124149 Multiplies two random n×n matrices with each method and reports GFLOP/s
125150 (2n³ ÷ time). All methods use identical inputs per size — see the
126151 cross-check below. <strong>WebGPU runs in single precision (f32)</strong>;
@@ -181,10 +206,16 @@ export function BenchmarkRunner() {
181206 cell={(methodId, n) => results[methodId]?.[n]}
182207 />
183208
209+ <Box>
210+ <Button size="small" variant="outlined" onClick={downloadCsv} disabled={!hasResults}>
211+ Download CSV
212+ </Button>
213+ </Box>
214+
184215 <Box>
185216 <Typography variant="subtitle2">Cross-check (C[0] for identical inputs)</Typography>
186217 <Typography variant="caption" color="text.secondary" component="div" sx={{ mb: 1 }}>
187- The f64 methods (JS, both WASM kernels, both BLIS builds) should agree
218+ The f64 methods (JS, the WASM kernels, both BLIS builds) should agree
188219 to ~1e-9; WebGPU (f32) will be close but not identical.
189220 </Typography>
190221 <Stack spacing={0.5}>
moveopenescclose