Spaces:
Running
Running
GitHub Actions commited on
Commit ·
53e685e
1
Parent(s): d43ec0c
sync from abhijitramesh/webgpu-bench@31c4d9956b
Browse files- data/combined.json +3 -3
- js/run/controller.js +52 -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-
|
| 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-
|
| 38 |
"resultCount": 2,
|
| 39 |
"passCount": 2,
|
| 40 |
"llamaCppCommit": null,
|
|
@@ -58,7 +58,7 @@
|
|
| 58 |
"browsers": [
|
| 59 |
"chromium-147"
|
| 60 |
],
|
| 61 |
-
"generatedAt": "2026-04-
|
| 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
|
|
|
|
| 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 =
|
| 189 |
-
$('device-platform').textContent =
|
| 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 |
}
|