| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const CHANNEL = 'aitools:backend-event'; |
|
|
| export function dispatchBackendEvent(detail) { |
| document.dispatchEvent(new CustomEvent(CHANNEL, { detail })); |
| } |
|
|
| export function trackBackendEvents(onEvent) { |
| const events = []; |
| const handler = (e) => { |
| events.push(e.detail); |
| onEvent?.(e.detail); |
| }; |
| document.addEventListener(CHANNEL, handler); |
| return { |
| stop() { document.removeEventListener(CHANNEL, handler); }, |
| events: () => events.slice(), |
| summary() { |
| let activeBackend = null; |
| let hadFallback = false; |
| let hadSkip = false; |
| const lines = []; |
| for (const e of events) { |
| if (e.kind === 'success') { |
| activeBackend = e.backend || activeBackend; |
| } else if (e.kind === 'fallback') { |
| hadFallback = true; |
| const friendly = friendlyBackend(e.backend); |
| lines.push(e.reason ? `Failed on ${friendly}: ${e.reason}` : `Failed on ${friendly}`); |
| } else if (e.kind === 'skipped') { |
| hadSkip = true; |
| const friendly = friendlyBackend(e.backend); |
| lines.push(e.reason ? `Skipped ${friendly} (${e.reason})` : `Skipped ${friendly}`); |
| } |
| } |
| return { activeBackend, hadFallback, hadSkip, lines }; |
| }, |
| }; |
| } |
|
|
| |
| |
| |
| |
| |
| export function shortenReason(e) { |
| const s = String(e?.message || e || ''); |
| const m = s.match(/Error in building plan|Non-zero status code returned|Failed to load|Could not create|cannot be reshaped|Unexpected input data type|kernel.*not.*found/i); |
| if (m) return m[0]; |
| return s.length > 120 ? s.slice(0, 117) + '…' : s; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function realizedIsGpu(backend) { |
| if (!backend) return false; |
| if (backend === 'web-wasm' || backend === 'native-cpu') return false; |
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function friendlyBackend(b) { |
| if (!b) return 'unknown'; |
|
|
| |
| if (b === 'web-webgpu') return 'WebGPU'; |
| if (b === 'web-wasm') return 'CPU (WASM)'; |
| if (b.startsWith('native-')) { |
| const ep = b.slice('native-'.length); |
| if (ep === 'cpu') return 'CPU (native)'; |
| if (ep === 'cuda') return 'CUDA'; |
| if (ep === 'rocm') return 'ROCm'; |
| if (ep === 'dml') return 'DirectML'; |
| if (ep.startsWith('coreml')) { |
| const variant = ep.includes('/') ? ep.split('/')[1] : null; |
| return variant ? `CoreML (${variant})` : 'CoreML'; |
| } |
| return ep; |
| } |
|
|
| |
| if (b === 'webgpu') return 'WebGPU'; |
| if (b === 'wasm' || b === 'cpu') return 'CPU'; |
| if (b === 'cuda') return 'CUDA'; |
| if (b === 'dml') return 'DirectML'; |
| if (b.startsWith('coreml')) { |
| const variant = b.includes('/') ? b.split('/')[1] : null; |
| return variant ? `CoreML (${variant})` : 'CoreML'; |
| } |
| return b; |
| } |
|
|