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 { 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; }