GitHub Actions commited on
Commit
53e685e
·
1 Parent(s): d43ec0c

sync from abhijitramesh/webgpu-bench@31c4d9956b

Browse files
Files changed (3) hide show
  1. data/combined.json +3 -3
  2. js/run/controller.js +52 -3
  3. js/run/device.js +26 -0
data/combined.json CHANGED
@@ -7,7 +7,7 @@
7
  "platform": "darwin",
8
  "arch": "arm",
9
  "totalMemoryGB": 4,
10
- "submittedAt": "2026-04-25T19:50:18.331Z",
11
  "resultCount": 6,
12
  "passCount": 6,
13
  "llamaCppCommit": null,
@@ -34,7 +34,7 @@
34
  "platform": "darwin",
35
  "arch": "arm",
36
  "totalMemoryGB": 8,
37
- "submittedAt": "2026-04-25T19:50:18.331Z",
38
  "resultCount": 2,
39
  "passCount": 2,
40
  "llamaCppCommit": null,
@@ -58,7 +58,7 @@
58
  "browsers": [
59
  "chromium-147"
60
  ],
61
- "generatedAt": "2026-04-25T19:50:18.382Z"
62
  },
63
  "results": [
64
  {
 
7
  "platform": "darwin",
8
  "arch": "arm",
9
  "totalMemoryGB": 4,
10
+ "submittedAt": "2026-04-25T20:54:49.553Z",
11
  "resultCount": 6,
12
  "passCount": 6,
13
  "llamaCppCommit": null,
 
34
  "platform": "darwin",
35
  "arch": "arm",
36
  "totalMemoryGB": 8,
37
+ "submittedAt": "2026-04-25T20:54:49.552Z",
38
  "resultCount": 2,
39
  "passCount": 2,
40
  "llamaCppCommit": null,
 
58
  "browsers": [
59
  "chromium-147"
60
  ],
61
+ "generatedAt": "2026-04-25T20:54:49.603Z"
62
  },
63
  "results": [
64
  {
js/run/controller.js CHANGED
@@ -164,6 +164,54 @@ function groupByFamily(variants) {
164
 
165
  function $(id) { return document.getElementById(id); }
166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  function renderHeader() {
168
  const d = state.device;
169
  const b = state.budget;
@@ -180,13 +228,14 @@ function renderHeader() {
180
  badge.className = `badge run-mode-badge run-mode-${state.surface}`;
181
  }
182
 
183
- const uaShort = d.userAgent.match(/(Firefox|Chrome|CriOS|Edg|Safari)\/[\d.]+/)?.[0] || 'browser';
 
184
  const gpuStr = d.gpu
185
  ? [d.gpu.vendor, d.gpu.architecture, d.gpu.device].filter(Boolean).join(' ').trim()
186
  : '';
187
 
188
- $('device-browser').textContent = uaShort;
189
- $('device-platform').textContent = d.platform || 'unknown';
190
  $('device-gpu').textContent = gpuStr || (d.webgpu ? 'WebGPU (no info)' : 'no WebGPU');
191
 
192
  const memStr = b.memGB !== null ? `${b.memGB} GB` : '—';
 
164
 
165
  function $(id) { return document.getElementById(id); }
166
 
167
+ /* Pretty browser name + version. Prefers UA Client Hints (clean
168
+ { brand, version } pairs) over UA-string regex parsing. The brand list
169
+ is ordered Chromium-favoured, so pick the most-specific brand the user
170
+ actually has (Edg → Chrome → Chromium). */
171
+ function formatBrowser(d) {
172
+ const preferred = ['Microsoft Edge', 'Edg', 'Opera', 'Brave', 'Arc', 'Vivaldi',
173
+ 'Google Chrome', 'Chromium'];
174
+ const brands = d.uaBrands || [];
175
+ for (const name of preferred) {
176
+ const hit = brands.find(b => b.brand === name);
177
+ if (hit) return `${hit.brand} ${hit.version}`;
178
+ }
179
+ if (brands.length > 0) return `${brands[0].brand} ${brands[0].version}`;
180
+
181
+ // Non-Chromium fallback: regex on userAgent. Capture brand + version
182
+ // separately so the slash isn't visible.
183
+ const m = (d.userAgent || '').match(/(Firefox|FxiOS|Edg|CriOS|Chrome|Version)\/([\d.]+)/);
184
+ if (!m) return 'browser';
185
+ const brand = m[1] === 'Version' ? 'Safari' : (m[1] === 'CriOS' ? 'Chrome iOS' : (m[1] === 'FxiOS' ? 'Firefox iOS' : m[1]));
186
+ return `${brand} ${m[2]}`;
187
+ }
188
+
189
+ /* Pretty OS + architecture. `navigator.platform` is unreliable on Apple
190
+ Silicon (it returns "MacIntel" for back-compat); prefer UA-CH and fall
191
+ back to the WebGPU vendor as a strong arm64 signal on Macs. */
192
+ function formatPlatform(d) {
193
+ const ua = d.userAgent || '';
194
+ const platHint = (d.uaPlatform || d.platform || '').toLowerCase();
195
+ let os;
196
+ if (platHint.includes('mac') || /Mac/.test(ua)) os = 'macOS';
197
+ else if (platHint.includes('win') || /Win/.test(ua)) os = 'Windows';
198
+ else if (/iPhone|iPad|iPod/.test(ua) || platHint.includes('ios')) os = 'iOS';
199
+ else if (/Android/.test(ua) || platHint.includes('android')) os = 'Android';
200
+ else if (platHint.includes('linux') || /Linux/.test(ua)) os = 'Linux';
201
+ else os = d.uaPlatform || d.platform || 'unknown';
202
+
203
+ let arch = '';
204
+ if (d.uaArch === 'arm') arch = 'arm64';
205
+ else if (d.uaArch === 'x86') arch = 'x86_64';
206
+ else if (d.uaArch) arch = d.uaArch;
207
+ else if (os === 'macOS' && d.gpu?.vendor === 'apple') arch = 'arm64';
208
+ else if (os === 'iOS') arch = 'arm64';
209
+ else if (/arm|aarch/i.test(ua)) arch = 'arm64';
210
+ else if (/x86_64|Win64;|x64/i.test(ua)) arch = 'x86_64';
211
+
212
+ return arch ? `${os} · ${arch}` : os;
213
+ }
214
+
215
  function renderHeader() {
216
  const d = state.device;
217
  const b = state.budget;
 
228
  badge.className = `badge run-mode-badge run-mode-${state.surface}`;
229
  }
230
 
231
+ const browserStr = formatBrowser(d);
232
+ const platformStr = formatPlatform(d);
233
  const gpuStr = d.gpu
234
  ? [d.gpu.vendor, d.gpu.architecture, d.gpu.device].filter(Boolean).join(' ').trim()
235
  : '';
236
 
237
+ $('device-browser').textContent = browserStr;
238
+ $('device-platform').textContent = platformStr;
239
  $('device-gpu').textContent = gpuStr || (d.webgpu ? 'WebGPU (no info)' : 'no WebGPU');
240
 
241
  const memStr = b.memGB !== null ? `${b.memGB} GB` : '—';
js/run/device.js CHANGED
@@ -146,11 +146,37 @@ export async function describeDevice() {
146
  gpu = null;
147
  }
148
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  return {
150
  ...budget,
151
  webgpu: !!navigator.gpu,
152
  gpu,
153
  userAgent: navigator.userAgent,
154
  platform: navigator.platform ?? null,
 
 
 
 
155
  };
156
  }
 
146
  gpu = null;
147
  }
148
  }
149
+
150
+ // UA Client Hints: high-entropy values give us the real architecture
151
+ // and OS, neither of which `navigator.platform` reports correctly on
152
+ // Apple Silicon Macs (it returns "MacIntel" forever for back-compat).
153
+ let uaArch = null;
154
+ let uaPlatform = null;
155
+ let uaPlatformVersion = null;
156
+ try {
157
+ const uad = navigator.userAgentData;
158
+ if (uad?.getHighEntropyValues) {
159
+ const hev = await uad.getHighEntropyValues(['architecture', 'platform', 'platformVersion']);
160
+ uaArch = hev.architecture || null;
161
+ uaPlatform = hev.platform || null;
162
+ uaPlatformVersion = hev.platformVersion || null;
163
+ }
164
+ } catch { /* not Chromium or denied */ }
165
+
166
+ // UA-CH brands give us a clean { brand, version } pair without parsing
167
+ // the userAgent string. Filter out the "Not(A:Brand)" decoy entries.
168
+ const brands = (navigator.userAgentData?.brands || [])
169
+ .filter(b => b && !/not[^\w]*a[^\w]*brand/i.test(b.brand));
170
+
171
  return {
172
  ...budget,
173
  webgpu: !!navigator.gpu,
174
  gpu,
175
  userAgent: navigator.userAgent,
176
  platform: navigator.platform ?? null,
177
+ uaArch,
178
+ uaPlatform,
179
+ uaPlatformVersion,
180
+ uaBrands: brands,
181
  };
182
  }