e01ddf1MATLAB-syntax scripts on WebGPU: fused kernels, tic/toc timing, CPU comparisonJeremy Magland 1
2<html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><rect x=%225%22 y=%225%22 width=%2290%22 height=%2290%22 rx=%2216%22 fill=%22%230969da%22/><text x=%2250%22 y=%2268%22 font-size=%2252%22 text-anchor=%22middle%22 fill=%22white%22 font-family=%22monospace%22 font-weight=%22bold%22>⚡</text></svg>" />
7 <title>math-webgpu-sandbox — MATLAB-syntax scripts on WebGPU</title>
8 <style>
9 :root {
10 --bg: #ffffff;
11 --ink: #1f2328;
12 --ink-2: #57606a;
13 --line: #d0d7de;
14 --accent: #0969da;
15 --pane-bg: #f4f6f8;
16 --tok-com: #6e7781;
17 --tok-str: #0a3069;
18 --tok-num: #0550ae;
19 --tok-kw: #cf222e;
20 --tok-ext: #8250df;
21 --warn-bg: #fff8e5;
22 --warn-line: #e3c37a;
23 --warn-edge: #bf8700;
24 --err: #b35900;
25 color-scheme: light dark;
26 }
27 @media (prefers-color-scheme: dark) {
28 :root {
29 --bg: #14171a;
30 --ink: #e6e9ec;
31 --ink-2: #9aa4af;
32 --line: #333b44;
33 --accent: #58a6ff;
34 --pane-bg: #191d22;
35 --tok-com: #8b949e;
36 --tok-str: #a5d6ff;
37 --tok-num: #79c0ff;
38 --tok-kw: #ff7b72;
39 --tok-ext: #d2a8ff;
40 --warn-bg: #2b2410;
41 --warn-line: #6b5518;
42 --warn-edge: #e3b341;
43 --err: #f0883e;
44 }
45 }
46 body {
47 margin: 0;
48 background: var(--bg);
49 color: var(--ink);
50 font: 15px/1.5 system-ui, -apple-system, sans-serif;
51 }
52 main { max-width: 1200px; margin: 0 auto; padding: 20px 16px 48px; }
53 h1 { font-size: 20px; margin: 0 0 2px; }
54 .sub { color: var(--ink-2); margin: 0 0 10px; font-size: 13px; }
55 .sub a { color: var(--accent); }
56 .warn {
57 margin: 0 0 12px; padding: 10px 14px;
58 border: 1px solid var(--warn-line); border-left: 5px solid var(--warn-edge);
59 border-radius: 6px; background: var(--warn-bg);
60 font-size: 13.5px; line-height: 1.5;
61 }
62 .controls {
63 display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center;
64 padding: 6px 0;
65 }
66 .controls label { color: var(--ink-2); font-size: 13px; white-space: nowrap; }
67 select, button {
68 font: inherit; font-size: 13px;
69 color: var(--ink); background: var(--bg);
70 border: 1px solid var(--line); border-radius: 6px;
71 padding: 4px 10px;
72 }
73 button { cursor: pointer; }
74 button:hover:not(:disabled) { border-color: var(--accent); }
75 button:disabled { opacity: 0.5; cursor: default; }
76 button.primary { border-color: var(--accent); color: var(--accent); font-weight: 600; }
77 #device { font-size: 12.5px; color: var(--ink-2); margin-left: auto; }
78 .split { display: flex; gap: 14px; margin-top: 10px; align-items: stretch; }
79 .box {
80 border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
81 display: flex; flex-direction: column; min-width: 0;
82 }
83 #editorbox { flex: 1 1 56%; }
84 #outbox { flex: 1 1 44%; }
85 .box-head {
86 display: flex; gap: 10px; align-items: center; justify-content: space-between;
87 padding: 6px 10px; font-size: 12px; color: var(--ink-2);
88 background: var(--pane-bg); border-bottom: 1px solid var(--line);
89 }
90 .editor-code { position: relative; flex: 1; min-height: 30em; }
91 .editor-code > pre,
92 .editor-code > textarea {
93 margin: 0; padding: 10px 12px; border: 0;
94 box-sizing: border-box; width: 100%; height: 100%;
95 font: 12.5px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
96 tab-size: 2;
97 white-space: pre; overflow-wrap: normal;
98 }
99 #highlight {
100 position: absolute; inset: 0; overflow: hidden;
101 pointer-events: none; background: var(--bg); color: var(--ink);
102 }
103 #source {
104 position: relative; z-index: 1; display: block;
105 resize: none; overflow: auto;
106 background: transparent; color: transparent; caret-color: var(--ink);
107 }
108 #source:focus { outline: none; }
109 #source::selection { background: color-mix(in srgb, var(--accent) 28%, transparent); }
110 .console {
111 flex: 1; margin: 0; padding: 10px 12px; overflow: auto;
112 font: 12.5px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
113 white-space: pre-wrap; background: var(--pane-bg);
114 min-height: 8em;
115 }
116 .console .err { color: var(--err); }
117 .console .meta { color: var(--ink-2); }
118 details { margin-top: 12px; font-size: 13px; }
119 details pre {
120 margin: 6px 0 0; padding: 8px 10px; overflow: auto;
121 background: var(--pane-bg); border: 1px solid var(--line); border-radius: 6px;
122 font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
123 }
4ded6ffShow the generated WGSL kernels in the compiled-plan paneJeremy Magland 124 #kernels details { margin: 6px 0 0 14px; }
125 #kernels summary {
126 cursor: pointer; color: var(--ink-2);
127 font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
128 }
129 #kernels summary b { color: var(--accent); font-weight: 600; }
130 #kernels pre { max-height: 24em; }
e01ddf1MATLAB-syntax scripts on WebGPU: fused kernels, tic/toc timing, CPU comparisonJeremy Magland 131 #blurb { margin-top: 14px; font-size: 13px; color: var(--ink-2); max-width: 72em; }
132 #blurb code { font-size: 12px; }
133 .tok-com { color: var(--tok-com); }
134 .tok-str { color: var(--tok-str); }
135 .tok-num { color: var(--tok-num); }
136 .tok-kw { color: var(--tok-kw); font-weight: 600; }
137 .tok-ext { color: var(--tok-ext); }
138 @media (max-width: 900px) {
139 .split { flex-direction: column; }
140 .editor-code { min-height: 22em; }
141 }
142 </style>
143 </head>
144 <body>
145 <main>
146 <h1>math-webgpu-sandbox</h1>
147 <p class="sub">
148 MATLAB-syntax scripts compiled to fused WebGPU compute kernels — time them with
149 <code>tic</code>/<code>toc</code>, then paste the same script into MATLAB and compare.
150 <a href="https://github.com/concept-collection/math-webgpu-sandbox">source</a>
151 </p>
152 <div id="gpuwarn" class="warn" hidden></div>
153 <div class="controls">
154 <label>example
155 <select id="example"></select>
156 </label>
157 <button id="run" class="primary">Run on GPU</button>
158 <button id="copy" title="Copy the script for pasting into MATLAB">Copy script</button>
159 <span id="device"></span>
160 </div>
161 <div class="split">
162 <div class="box" id="editorbox">
163 <div class="box-head"><span>script.m — valid MATLAB</span><span id="editstate"></span></div>
164 <div class="editor-code">
165 <pre id="highlight" aria-hidden="true"></pre>
166 <textarea id="source" spellcheck="false" autocomplete="off"></textarea>
167 </div>
168 </div>
169 <div class="box" id="outbox">
170 <div class="box-head"><span>output</span><span id="runstate"></span></div>
171 <pre id="console" class="console"></pre>
172 </div>
173 </div>
20d2604Open the plan-and-kernels pane by defaultJeremy Magland 174 <details id="plandetails" open hidden>
4ded6ffShow the generated WGSL kernels in the compiled-plan paneJeremy Magland 175 <summary>compiled GPU plan & kernels</summary>
e01ddf1MATLAB-syntax scripts on WebGPU: fused kernels, tic/toc timing, CPU comparisonJeremy Magland 176 <pre id="plan"></pre>
4ded6ffShow the generated WGSL kernels in the compiled-plan paneJeremy Magland 177 <div id="kernels"></div>
e01ddf1MATLAB-syntax scripts on WebGPU: fused kernels, tic/toc timing, CPU comparisonJeremy Magland 178 </details>
179 <p id="blurb">
9c655b8Remove CPU comparison run and timing table; tighten footnoteJeremy Magland 180 The GPU computes in f32 (WebGPU has no f64) — for the closest MATLAB comparison,
181 use <code>single</code> arrays there. <code>rand</code> is deterministic here:
182 statistics match MATLAB's, individual draws don't. Unsupported constructs fail
183 with a compile error rather than a wrong answer.
e01ddf1MATLAB-syntax scripts on WebGPU: fused kernels, tic/toc timing, CPU comparisonJeremy Magland 184 </p>
185 </main>
186 <script type="module" src="/src/main.ts"></script>
187 </body>
188</html>