lup-system
Version:
NodeJS library to retrieve system information and utilization.
201 lines (200 loc) • 9.69 kB
JavaScript
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;
}
;