diff --git a/cmd/client/main.go b/cmd/client/main.go index 214e154..80bf831 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -1157,31 +1157,44 @@ func collectGPUs() []GPUInfo { switch runtime.GOOS { case "windows": gpus := tryNvidiaSMI() - if len(gpus) > 0 { - return gpus - } - return tryWMIGPU() + wmi := tryWMIGPU() + return mergeGPULists(gpus, wmi) case "linux": gpus := tryNvidiaSMI() - if len(gpus) > 0 { - return gpus - } - return tryLinuxGPU() + lspci := tryLinuxGPU() + return mergeGPULists(gpus, lspci) case "darwin": gpus := tryNvidiaSMI() - if len(gpus) > 0 { - return gpus - } - return tryMacGPU() + mac := tryMacGPU() + return mergeGPULists(gpus, mac) } return tryNvidiaSMI() } +func mergeGPULists(nvidia, fallback []GPUInfo) []GPUInfo { + if len(nvidia) == 0 { + return fallback + } + if len(fallback) == 0 { + return nvidia + } + exist := make(map[string]bool) + for _, g := range nvidia { + exist[g.Name] = true + } + for _, g := range fallback { + if !exist[g.Name] { + nvidia = append(nvidia, g) + } + } + return nvidia +} + func tryNvidiaSMI() []GPUInfo { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() out, err := exec.CommandContext(ctx, "nvidia-smi", - "--query-gpu=index,name,memory.total,memory.used,memory.free,temperature.gpu,utilization.gpu,clocks.current.graphics,clocks.current.memory,power.draw,power.limit,fan.speed,pstate,persistence_mode,compute_mode,driver_version,cuda_version", + "--query-gpu=index,name,memory.total,memory.used,memory.free,temperature.gpu,utilization.gpu,clocks.current.graphics,clocks.current.memory,power.draw,power.limit,fan.speed,pstate,driver_version,cuda_version", "--format=csv,noheader,nounits", ).Output() if err != nil { @@ -1189,6 +1202,10 @@ func tryNvidiaSMI() []GPUInfo { } var gpus []GPUInfo for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") { + line = strings.TrimSpace(line) + if line == "" || strings.HasPrefix(line, " ") { + continue + } parts := strings.Split(line, ",") if len(parts) < 9 { continue @@ -1220,16 +1237,10 @@ func tryNvidiaSMI() []GPUInfo { g.PState = cleanStr(parts[12]) } if len(parts) > 13 { - g.Persistence = cleanStr(parts[13]) + g.DriverVersion = cleanStr(parts[13]) } if len(parts) > 14 { - g.ComputeMode = cleanStr(parts[14]) - } - if len(parts) > 15 { - g.DriverVersion = cleanStr(parts[15]) - } - if len(parts) > 16 { - g.CudaVersion = cleanStr(parts[16]) + g.CudaVersion = cleanStr(parts[14]) } gpus = append(gpus, g) } diff --git a/cmd/server/templates/index.html b/cmd/server/templates/index.html index 239db83..4c19abb 100644 --- a/cmd/server/templates/index.html +++ b/cmd/server/templates/index.html @@ -60,7 +60,7 @@ .pdot { position:absolute; top:50%; left:50%; width:8px; height:8px; margin:-4px; background:var(--accent); border-radius:50% } @keyframes pulse { 0%{transform:scale(.35);opacity:1} 100%{transform:scale(2.4);opacity:0} } - .device-grid { padding:12px 20px 32px; display:grid; grid-template-columns:repeat(auto-fill,minmax(360px,1fr)); gap:12px } + .device-grid { padding:12px 20px 32px; display:grid; grid-template-columns:repeat(auto-fill,minmax(600px,1fr)); gap:12px } .device-grid > .device-card { min-width:0 } .device-card { background:var(--card); border:1px solid var(--border); border-radius:10px; transition:opacity .3s,border-color .2s,box-shadow .2s } .device-card:hover { border-color:#28304a; box-shadow:0 4px 24px rgba(0,0,0,.2) }