UNPKG

lup-system

Version:

NodeJS library to retrieve system information and utilization.

201 lines (200 loc) 9.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGPUs = getGPUs; const utils_1 = require("./utils"); async function getGPUs() { const gpus = []; switch (process.platform) { case 'linux': { const output = await (0, utils_1.execCommand)('lspci -k | grep -i -A3 "\[vga\]\|\[3d\]"').catch(() => ''); const lines = output.split('\n'); let curr = null; // tslint:disable-next-line:prefer-for-of for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (!line) continue; // skip empty lines if (line.startsWith('00:')) { // new GPU found, push current if exists if (curr) gpus.push(curr); curr = {}; curr.id = line.split(' ')[0]; curr.name = line.split(':')[2].trim(); curr.status = 'ok'; // assume ok, will update later if needed } } break; } case 'win32': { const output = await (0, utils_1.execCommand)('powershell -Command "Get-CimInstance -ClassName Win32_VideoController | Format-List"').catch(() => ''); const lines = output.split('\n'); let curr = null; // tslint:disable-next-line:prefer-for-of for (let i = 0; i < lines.length; i++) { const [key, value] = lines[i].split(' : ').map((s) => s.trim()); if (!key && !value) { // empty line, push current GPU if exists if (curr) gpus.push(curr); curr = null; continue; } if (!value) continue; // skip lines without value if (key === 'Name') { if (!curr) curr = {}; curr.name = value; } else if (key === 'Status') { if (!curr) curr = {}; curr.status = value.toLowerCase() || 'unknown'; } else if (key === 'PNPDeviceID') { if (!curr) curr = {}; curr.id = value; } else if (key === 'VideoProcessor') { if (!curr) curr = {}; curr.processor = value; } else if (key === 'AdapterRAM') { const memory = parseInt(value.trim(), 10); if (Number.isNaN(memory)) continue; // skip invalid memory values if (!curr) curr = {}; curr.memory = memory; // not accurate, but gives an idea of the GPU memory } else if (key === 'DriverDate') { if (!curr) curr = {}; curr.driverDate = value; } else if (key === 'DriverVersion') { if (!curr) curr = {}; curr.driverVersion = value; } } if (curr) gpus.push(curr); break; } } // nvidia-smi for more detailed info { const output = await (0, utils_1.execCommand)('nvidia-smi --query-gpu=name,index,display_attached,display_active,fan.speed,memory.total,utilization.gpu,utilization.memory,temperature.gpu,temperature.memory,power.draw,clocks.current.graphics,clocks.current.sm,clocks.current.memory,clocks.current.memory,clocks.max.graphics,clocks.max.sm,clocks.max.memory --format=csv,nounits,noheader').catch(() => ''); const lines = output.split('\n').filter((line) => line.trim() !== ''); const updatedIndexes = new Set(); // tslint:disable-next-line:prefer-for-of for (let i = 0; i < lines.length; i++) { const [name, index, displayAttached, displayActive, fanSpeed, memoryTotal, utilizationGPU, utilizationMemory, temperatureGPU, temperatureMemory, powerDraw, clocksCurrentGraphics, clocksCurrentSM, clocksCurrentMemory, clocksCurrentVideo, clocksMaxGraphics, clocksMaxSM, clocksMaxMemory,] = lines[i].split(',').map((s) => s.trim()); let currIdx = gpus.length; let currGpu = undefined; for (let g = 0; g < gpus.length; g++) { if (updatedIndexes.has(g)) continue; // already updated this GPU const gpu = gpus[g]; if (gpu.name !== name) continue; updatedIndexes.add(g); currIdx = g; currGpu = gpus[g]; break; } if (!currGpu) { currGpu = { id: name, name }; updatedIndexes.add(gpus.length); gpus.push(currGpu); } if (index.toString().length > 0) currGpu.index = parseInt(index, 10); if (displayAttached) currGpu.displayAttached = ['yes', 'enabled', '1'].includes(displayAttached.toLowerCase()); if (displayActive) currGpu.displayActive = ['yes', 'enabled', '1'].includes(displayActive.toLowerCase()); if (fanSpeed && !Number.isNaN(parseFloat(fanSpeed))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.fanSpeed = parseFloat(fanSpeed) / 100; } if (memoryTotal && !Number.isNaN(parseInt(memoryTotal, 10))) currGpu.memory = parseInt(memoryTotal, 10) * 1024 * 1024; // convert MiB to bytes if (utilizationGPU && !Number.isNaN(parseFloat(utilizationGPU))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.processing = parseFloat(utilizationGPU) / 100; } if (utilizationMemory && !Number.isNaN(parseFloat(utilizationMemory))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.memory = parseFloat(utilizationMemory) / 100; } if (temperatureGPU && !Number.isNaN(parseFloat(temperatureGPU))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.temperature = parseFloat(temperatureGPU); } if (temperatureMemory && !Number.isNaN(parseFloat(temperatureMemory))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.memoryTemperature = parseFloat(temperatureMemory); } if (powerDraw && !Number.isNaN(parseFloat(powerDraw))) { if (!currGpu.utilization) currGpu.utilization = {}; currGpu.utilization.powerDraw = parseFloat(powerDraw); } if (clocksCurrentGraphics && !Number.isNaN(parseInt(clocksCurrentGraphics, 10))) { if (!currGpu.utilization) currGpu.utilization = {}; if (!currGpu.utilization.clockSpeed) currGpu.utilization.clockSpeed = {}; currGpu.utilization.clockSpeed.graphics = parseInt(clocksCurrentGraphics, 10); } if (clocksCurrentMemory && !Number.isNaN(parseInt(clocksCurrentMemory, 10))) { if (!currGpu.utilization) currGpu.utilization = {}; if (!currGpu.utilization.clockSpeed) currGpu.utilization.clockSpeed = {}; currGpu.utilization.clockSpeed.memory = parseInt(clocksCurrentMemory, 10); } if (clocksCurrentSM && !Number.isNaN(parseInt(clocksCurrentSM, 10))) { if (!currGpu.utilization) currGpu.utilization = {}; if (!currGpu.utilization.clockSpeed) currGpu.utilization.clockSpeed = {}; currGpu.utilization.clockSpeed.sm = parseInt(clocksCurrentSM, 10); } if (clocksCurrentVideo && !Number.isNaN(parseInt(clocksCurrentVideo, 10))) { if (!currGpu.utilization) currGpu.utilization = {}; if (!currGpu.utilization.clockSpeed) currGpu.utilization.clockSpeed = {}; currGpu.utilization.clockSpeed.video = parseInt(clocksCurrentVideo, 10); } if (clocksMaxGraphics && !Number.isNaN(parseInt(clocksMaxGraphics, 10))) { if (!currGpu.clockMaxSpeed) currGpu.clockMaxSpeed = {}; currGpu.clockMaxSpeed.graphics = parseInt(clocksMaxGraphics, 10); } if (clocksMaxMemory && !Number.isNaN(parseInt(clocksMaxMemory, 10))) { if (!currGpu.clockMaxSpeed) currGpu.clockMaxSpeed = {}; currGpu.clockMaxSpeed.memory = parseInt(clocksMaxMemory, 10); } if (clocksMaxSM && !Number.isNaN(parseInt(clocksMaxSM, 10))) { if (!currGpu.clockMaxSpeed) currGpu.clockMaxSpeed = {}; currGpu.clockMaxSpeed.sm = parseInt(clocksMaxSM, 10); } gpus[currIdx] = currGpu; } } return gpus; }