102 lines
3.2 KiB
JavaScript
102 lines
3.2 KiB
JavaScript
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'))
|
|
})
|