diff --git a/services/hwfit/hardware.py b/services/hwfit/hardware.py index 191f0e61d..db48d1842 100644 --- a/services/hwfit/hardware.py +++ b/services/hwfit/hardware.py @@ -468,39 +468,55 @@ def _detect_windows(): """ # Single PowerShell command that gathers all hardware info at once ps_cmd = ( - "$r = @{}; " - "$os = Get-CimInstance Win32_OperatingSystem; " - "$r.ram_gb = [math]::Round($os.TotalVisibleMemorySize / 1048576, 1); " - "$r.avail_gb = [math]::Round($os.FreePhysicalMemory / 1048576, 1); " - "$cpu = Get-CimInstance Win32_Processor | Select-Object -First 1; " - "$r.cpu_name = $cpu.Name; " - "$r.cpu_cores = (Get-CimInstance Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum; " - "$r.arch = $cpu.AddressWidth; " + """ + $r = @{} + $os = Get-CimInstance Win32_OperatingSystem + $r.ram_gb = [math]::Round($os.TotalVisibleMemorySize / 1048576, 1) + $r.avail_gb = [math]::Round($os.FreePhysicalMemory / 1048576, 1) + $cpu = Get-CimInstance Win32_Processor | Select-Object -First 1 + $r.cpu_name = $cpu.Name + $r.cpu_cores = (Get-CimInstance Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum + $r.arch = $cpu.AddressWidth # GPU detection via nvidia-smi (fastest) or WMI fallback - "try { " - " $nv = nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>$null; " - " if ($LASTEXITCODE -eq 0 -and $nv) { " - " $gpus = @(); " - " foreach ($line in $nv -split \"`n\") { " - " $p = $line -split ','; " - " if ($p.Count -ge 2) { $gpus += [pscustomobject]@{name=$p[1].Trim(); vram_mb=[double]$p[0].Trim()} } " - " }; " - " $r.gpu_name = $gpus[0].name; " - " $r.gpu_vram_gb = [math]::Round(($gpus | Measure-Object -Property vram_mb -Sum).Sum / 1024, 1); " - " $r.gpu_count = $gpus.Count; " - " $r.gpu_backend = 'cuda'; " - " } " - "} catch {}; " - "if (-not $r.gpu_name) { " - " $wmiGpu = Get-CimInstance Win32_VideoController | Where-Object { $_.AdapterRAM -gt 0 } | Select-Object -First 1; " - " if ($wmiGpu) { " - " $r.gpu_name = $wmiGpu.Name; " - " $r.gpu_vram_gb = [math]::Round($wmiGpu.AdapterRAM / 1073741824, 1); " - " $r.gpu_count = 1; " - " $r.gpu_backend = 'cpu_x86'; " # WMI doesn't tell us CUDA/ROCm - " } " - "}; " - "$r | ConvertTo-Json -Compress" + try { + $nv = nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>$null + if ($LASTEXITCODE -eq 0 -and $nv) { + $gpus = @() + foreach ($line in $nv -split "`n") { + $p = $line -split ',' + if ($p.Count -ge 2) { $gpus += [pscustomobject]@{name = $p[1].Trim(); vram_mb = [double]$p[0].Trim() } } + } + $r.gpu_name = $gpus[0].name + $r.gpu_vram_gb = [math]::Round(($gpus | Measure-Object -Property vram_mb -Sum).Sum / 1024, 1) + $r.gpu_count = $gpus.Count + $r.gpu_backend = 'cuda' + } + } + catch {} + if (-not $r.gpu_name) { + $wmiGpu = Get-CimInstance Win32_VideoController | Where-Object { $_.AdapterRAM -gt 0 } | Select-Object -First 1 + $GPUDriverKey = "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\0*" + $GPUDeviceID = $wmiGpu.PNPDeviceID.Split('&')[0..1] -join '&' + $VRAMfromRegistry = Get-ItemProperty -Path $GPUDriverKey | + Where-Object { $_.MatchingDeviceId -like "${GPUDeviceID}*" } | + # Sometimes there happen to be multiple driver classes for the same gpu. + Select-Object -ExpandProperty HardwareInformation.qwMemorySize -ErrorAction SilentlyContinue -First 1 + if ($wmiGpu) { + $r.gpu_name = $wmiGpu.Name + # Edge case: driver is broken, otherwise $wmiGpu.AdapterRAM is redundant + if ($VRAMfromRegistry -ge $wmiGpu.AdapterRAM) { + $r.gpu_vram_gb = [math]::Round($VRAMfromRegistry / 1073741824, 1) + } + else { + $r.gpu_vram_gb = [math]::Round($wmiGpu.AdapterRAM / 1073741824, 1) + } + $r.gpu_count = 1 + # WMI doesn't tell us CUDA/ROCm + $r.gpu_backend = 'cpu_x86'; + } + } + $r | ConvertTo-Json -Compress + """ ) if _remote_host: # Remote: ship a single command string over SSH. The remote shell parses