/ concept-collection / math-webgpu-sandbox
Sign in
concept-collection / math-webgpu-sandbox
math-webgpu-sandbox / src / mgpu / session.ts
69 lines · 2.1 KBCodeBlameHistory
2 * The one entry point: compile a MATLAB script and run it on a GPUDevice.
3 *
4 * Compilation (numbl lowering + WGSL pipeline builds) is timed separately
5 * from execution — the execution numbers are the ones to compare with MATLAB.
6 */
7import { compileScript } from './compile.ts';
8import { planScript, type ScriptPlan } from './plan.ts';
9import { executePlan, type RunResult } from './run.ts';
10import { asCompileError } from './errors.ts';
12export interface ScriptRun {
13 compileSeconds: number;
14 /** Human-readable op sequence, for the "what did this compile to" pane. */
15 planDescription: string[];
16 result: RunResult;
19export interface SandboxGpu {
20 device: GPUDevice;
21 /** Human-readable adapter description, for the "ran on" line. */
22 description: string;
25export async function requestSandboxDevice(): Promise<SandboxGpu> {
26 if (!navigator.gpu) {
27 throw new Error('WebGPU is not available in this browser');
28 }
29 const adapter = await navigator.gpu.requestAdapter();
30 if (!adapter) throw new Error('No WebGPU adapter available');
31 const want = (name: keyof GPUSupportedLimits): Record<string, number> => ({
32 [name]: adapter.limits[name] as number,
33 });
34 const device = await adapter.requestDevice({
35 requiredLimits: {
36 ...want('maxStorageBufferBindingSize'),
37 ...want('maxBufferSize'),
38 ...want('maxStorageBuffersPerShaderStage'),
39 },
40 });
41 const info = adapter.info;
42 const description =
43 [info?.description || info?.architecture, info?.vendor]
44 .filter(Boolean)
45 .join(' — ') || 'unknown adapter';
46 return { device, description };
49export async function runScript(
50 device: GPUDevice,
51 source: string,
52 onOutput?: (text: string) => void,
53): Promise<ScriptRun> {
54 const t0 = performance.now();
55 let plan: ScriptPlan;
56 try {
57 const compiled = compileScript(source);
58 plan = await planScript(device, compiled);
59 } catch (e) {
60 throw asCompileError(e);
61 }
62 const compileSeconds = (performance.now() - t0) / 1000;
63 try {
64 const result = await executePlan(device, plan, onOutput);
65 return { compileSeconds, planDescription: plan.describe(), result };
66 } finally {
67 plan.destroy();
68 }
moveopenescclose