ramimu's picture
Upload 586 files
1c72248 verified
import { NextResponse } from 'next/server';
import { exec } from 'child_process';
import { promisify } from 'util';
import os from 'os';
const execAsync = promisify(exec);
export async function GET() {
try {
// Get platform
const platform = os.platform();
const isWindows = platform === 'win32';
// Check if nvidia-smi is available
const hasNvidiaSmi = await checkNvidiaSmi(isWindows);
if (!hasNvidiaSmi) {
return NextResponse.json({
hasNvidiaSmi: false,
gpus: [],
error: 'nvidia-smi not found or not accessible',
});
}
// Get GPU stats
const gpuStats = await getGpuStats(isWindows);
return NextResponse.json({
hasNvidiaSmi: true,
gpus: gpuStats,
});
} catch (error) {
console.error('Error fetching NVIDIA GPU stats:', error);
return NextResponse.json(
{
hasNvidiaSmi: false,
gpus: [],
error: `Failed to fetch GPU stats: ${error instanceof Error ? error.message : String(error)}`,
},
{ status: 500 },
);
}
}
async function checkNvidiaSmi(isWindows: boolean): Promise<boolean> {
try {
if (isWindows) {
// Check if nvidia-smi is available on Windows
// It's typically located in C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe
// but we'll just try to run it directly as it may be in PATH
await execAsync('nvidia-smi -L');
} else {
// Linux/macOS check
await execAsync('which nvidia-smi');
}
return true;
} catch (error) {
return false;
}
}
async function getGpuStats(isWindows: boolean) {
// Command is the same for both platforms, but the path might be different
const command =
'nvidia-smi --query-gpu=index,name,driver_version,temperature.gpu,utilization.gpu,utilization.memory,memory.total,memory.free,memory.used,power.draw,power.limit,clocks.current.graphics,clocks.current.memory,fan.speed --format=csv,noheader,nounits';
// Execute command
const { stdout } = await execAsync(command);
// Parse CSV output
const gpus = stdout
.trim()
.split('\n')
.map(line => {
const [
index,
name,
driverVersion,
temperature,
gpuUtil,
memoryUtil,
memoryTotal,
memoryFree,
memoryUsed,
powerDraw,
powerLimit,
clockGraphics,
clockMemory,
fanSpeed,
] = line.split(', ').map(item => item.trim());
return {
index: parseInt(index),
name,
driverVersion,
temperature: parseInt(temperature),
utilization: {
gpu: parseInt(gpuUtil),
memory: parseInt(memoryUtil),
},
memory: {
total: parseInt(memoryTotal),
free: parseInt(memoryFree),
used: parseInt(memoryUsed),
},
power: {
draw: parseFloat(powerDraw),
limit: parseFloat(powerLimit),
},
clocks: {
graphics: parseInt(clockGraphics),
memory: parseInt(clockMemory),
},
fan: {
speed: parseInt(fanSpeed) || 0, // Some GPUs might not report fan speed, default to 0
},
};
});
return gpus;
}