import type { GpuStatus } from '../types'
type Props = {
gpu: GpuStatus | null
compact?: boolean
}
function memPct(used: number, total: number) {
if (!total) return 0
return Math.round((used / total) * 100)
}
export function GpuPanel({ gpu, compact }: Props) {
if (!gpu) {
return (
)
}
const online = gpu.ok
const gpus = gpu.gpus || []
const avgUtil = gpus.length ? gpus.reduce((s, g) => s + g.util_gpu, 0) / gpus.length : 0
const avgVram = gpus.length ? gpus.reduce((s, g) => s + memPct(g.memory_used_mib, g.memory_total_mib), 0) / gpus.length : 0
if (compact) {
return (
{gpu.active_model && (
{gpu.active_model}
)}
{gpu.gpu_count ?? gpus.length}× V100
{Math.round(avgUtil)}% util
{Math.round(avgVram)}% VRAM
{online ? (gpu.inference_active ? 'ON' : 'STBY') : 'OFF'}
)
}
return (
Inference cluster
⚡
GPU Lab
{online ? (gpu.inference_active ? 'INFERENCE ON' : 'STANDBY') : 'OFFLINE'}
atc-gpu-dev · {gpu.host} · {gpu.gpu_count ?? gpus.length}× V100
Open GPU Manager ↗
{gpu.active_model && (
Active model
{gpu.active_model}
{gpu.vllm_url && (
{gpu.vllm_url}
)}
)}
{!online && (
{gpu.error || 'GPU manager unreachable'}
)}
{gpus.map((g) => {
const pct = memPct(g.memory_used_mib, g.memory_total_mib)
return (
GPU {g.index}
{g.temperature_c}°C · {g.power_w}W
{g.name}
Util {Math.round(g.util_gpu)}%
VRAM {pct}%
)
})}
)
}