import test from 'brittle' import { bareOsQvacParseVulkaninfo, bareOsQvacParseNvidiaSmi, bareOsQvacMergeNvidiaHints, bareOsQvacRankGpus, bareOsQvacMainGpuCandidates, bareOsQvacProbeGpus } from './lib/bare-os-qvac-gpu-probe.mjs' const SAMPLE_VULKAN = ` GPU0: apiVersion = 1.3.0 driverVersion = 1 vendorID = 0x8086 deviceID = 0x9a49 deviceType = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU deviceName = Intel(R) UHD Graphics (TGL GT1) memoryHeaps: count = 1 memoryHeaps[0]: size = 536870912 (0x20000000) (512.00 MiB) flags: count = 1 MEMORY_HEAP_DEVICE_LOCAL_BIT GPU1: apiVersion = 1.3.0 driverVersion = 1 vendorID = 0x10de deviceID = 0x25a0 deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU deviceName = NVIDIA GeForce RTX 3050 Ti Laptop GPU memoryHeaps: count = 2 memoryHeaps[0]: size = 4294967296 (0x100000000) (4096.00 MiB) flags: count = 1 MEMORY_HEAP_DEVICE_LOCAL_BIT memoryHeaps[1]: size = 12582912 (0xc00000) (12.00 MiB) flags: count = 0 ` test('parse vulkaninfo ranks NVIDIA above Intel by VRAM', async (t) => { const gpus = bareOsQvacRankGpus(bareOsQvacParseVulkaninfo(SAMPLE_VULKAN)) t.is(gpus.length, 2) t.is(gpus[0].index, 1) t.ok(gpus[0].name.includes('NVIDIA')) t.is(gpus[0].memoryBytes, 4294967296) t.is(gpus[1].index, 0) t.ok(gpus[1].memoryBytes < gpus[0].memoryBytes) const cands = bareOsQvacMainGpuCandidates(gpus) t.is(cands[0], 1) t.ok(cands.includes('dedicated')) }) test('nvidia-smi parse + candidates avoid trusting smi index as vulkan', async (t) => { const n = bareOsQvacParseNvidiaSmi('NVIDIA GeForce RTX 3050 Ti Laptop GPU, 4096\n') t.is(n.length, 1) t.is(n[0].memoryBytes, 4096 * 1024 * 1024) const synth = n.map((x, i) => ({ index: i, name: x.name, memoryBytes: x.memoryBytes, deviceType: 'PHYSICAL_DEVICE_TYPE_DISCRETE_GPU', source: 'nvidia-smi' })) const cands = bareOsQvacMainGpuCandidates(synth) t.is(cands[0], 'dedicated') t.is(cands[1], 1) }) test('merge nvidia hints upgrades vulkan heap estimate', async (t) => { const vulkan = bareOsQvacParseVulkaninfo(` GPU0: deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU deviceName = NVIDIA GeForce RTX 3050 Ti Laptop GPU `) t.is(vulkan[0].memoryBytes, 8 * 1024 * 1024 * 1024) // discrete heuristic const merged = bareOsQvacMergeNvidiaHints(vulkan, [ { name: 'NVIDIA GeForce RTX 3050 Ti Laptop GPU', memoryBytes: 4096 * 1024 * 1024 } ]) // hint is smaller than discrete heuristic — keep larger t.is(merged[0].memoryBytes, 8 * 1024 * 1024 * 1024) const mergedUp = bareOsQvacMergeNvidiaHints( [{ ...vulkan[0], memoryBytes: 512 * 1024 * 1024 }], [{ name: 'NVIDIA GeForce RTX 3050 Ti Laptop GPU', memoryBytes: 4096 * 1024 * 1024 }] ) t.is(mergedUp[0].memoryBytes, 4096 * 1024 * 1024) }) test('probe with injected runCommand', async (t) => { const ranked = await bareOsQvacProbeGpus({ runCommand: async (file, args) => { if (file === 'vulkaninfo') return SAMPLE_VULKAN if (file === 'nvidia-smi') return 'NVIDIA GeForce RTX 3050 Ti Laptop GPU, 4096\n' return null } }) t.is(ranked[0].index, 1) t.ok(String(ranked[0].source).includes('vulkaninfo')) })