MinPerGPUVRAM returns the total VRAM of the SMALLEST GPU on the host (in bytes), or 0 when no per-device VRAM is known. Unlike TotalAvailableVRAM (which sums across devices) this reports a single device's ceiling, which is the right figure for decisions about what must fit on one card: the compute b
()
| 139 | // Unified-memory devices (GB10, Apple) report system RAM as their single |
| 140 | // device's VRAM, so they are unaffected. |
| 141 | func MinPerGPUVRAM() (uint64, error) { |
| 142 | // Prefer per-device binary detection (nvidia-smi/rocm-smi report true |
| 143 | // per-card VRAM); ghw's per-card memory can reflect NUMA node RAM on some |
| 144 | // hosts, which is why TotalAvailableVRAM treats it as a sum. |
| 145 | if infos := GetGPUMemoryUsage(); len(infos) > 0 { |
| 146 | if v := minNonZeroVRAM(infos); v > 0 { |
| 147 | return v, nil |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | // Fallback: ghw per-card memory, taking the minimum non-zero card. |
| 152 | if gpus, err := GPUs(); err == nil { |
| 153 | var min uint64 |
| 154 | for _, gpu := range gpus { |
| 155 | if gpu == nil || gpu.Node == nil || gpu.Node.Memory == nil { |
| 156 | continue |
| 157 | } |
| 158 | if b := gpu.Node.Memory.TotalUsableBytes; b > 0 { |
| 159 | if u := uint64(b); min == 0 || u < min { |
| 160 | min = u |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | if min > 0 { |
| 165 | return min, nil |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | return 0, nil |
| 170 | } |
| 171 | |
| 172 | // minNonZeroVRAM returns the smallest non-zero TotalVRAM across the given GPUs, |
| 173 | // or 0 when none report VRAM. |
no test coverage detected