Add a second GPU card to the monitor page

The 3080 was invisible because the stats parser only ever described GPU 0.
This commit is contained in:
Gmer4Lfe
2026-08-01 20:37:58 -04:00
parent 77b24e9823
commit cdce877601
4 changed files with 96 additions and 31 deletions
+39 -20
View File
@@ -95,35 +95,54 @@ function vv_docker_stopped(): array {
return $containers;
}
function vv_gpu_stats(): array {
$out = shell_exec('nvidia-smi --query-gpu=name,memory.used,memory.total,utilization.gpu,temperature.gpu,power.draw,utilization.encoder,utilization.decoder --format=csv,noheader,nounits 2>/dev/null');
if (!$out) return ['available' => false];
// Every installed GPU, one entry per card. Parsed line by line — nvidia-smi emits one row
// per GPU, so splitting the whole output on commas (as this once did) runs the rows together
// and only ever describes GPU 0.
function vv_gpu_stats_all(): array {
$out = shell_exec('nvidia-smi --query-gpu=index,uuid,name,memory.used,memory.total,utilization.gpu,temperature.gpu,power.draw,utilization.encoder,utilization.decoder --format=csv,noheader,nounits 2>/dev/null');
if (!$out) return [];
$parts = array_map('trim', explode(',', $out));
$power = is_numeric($parts[5] ?? '') ? round((float)$parts[5], 1) : null;
return [
'available' => true,
'name' => $parts[0] ?? '',
'memory_used' => (int)($parts[1] ?? 0),
'memory_total' => (int)($parts[2] ?? 0),
'utilization' => (int)($parts[3] ?? 0),
'temperature' => (int)($parts[4] ?? 0),
'power_w' => $power,
'enc_pct' => (int)($parts[6] ?? 0),
'dec_pct' => (int)($parts[7] ?? 0),
];
$gpus = [];
foreach (explode("\n", trim($out)) as $line) {
if (!$line) continue;
$p = array_map('trim', explode(',', $line));
if (count($p) < 10) continue;
$gpus[] = [
'available' => true,
'index' => (int)$p[0],
'uuid' => $p[1],
'name' => $p[2],
'memory_used' => (int)$p[3],
'memory_total' => (int)$p[4],
'utilization' => (int)$p[5],
'temperature' => (int)$p[6],
'power_w' => is_numeric($p[7]) ? round((float)$p[7], 1) : null,
'enc_pct' => (int)$p[8],
'dec_pct' => (int)$p[9],
];
}
return $gpus;
}
// Kept for the existing single-GPU consumers — same shape as before, always GPU 0.
function vv_gpu_stats(): array {
$gpus = vv_gpu_stats_all();
return $gpus[0] ?? ['available' => false];
}
// gpu_uuid is included so each process can be attributed to the card it is actually running
// on. Without it a two-GPU box shows every process under every card.
function vv_gpu_processes(): array {
$out = shell_exec('nvidia-smi --query-compute-apps=pid,used_gpu_memory,name --format=csv,noheader,nounits 2>/dev/null');
$out = shell_exec('nvidia-smi --query-compute-apps=gpu_uuid,pid,used_gpu_memory,name --format=csv,noheader,nounits 2>/dev/null');
$procs = [];
foreach (explode("\n", trim($out ?? '')) as $line) {
if (!$line) continue;
$parts = array_map('trim', explode(',', $line));
$procs[] = [
'pid' => $parts[0] ?? '',
'memory_mb' => $parts[1] ?? '',
'name' => $parts[2] ?? '',
'gpu_uuid' => $parts[0] ?? '',
'pid' => $parts[1] ?? '',
'memory_mb' => $parts[2] ?? '',
'name' => $parts[3] ?? '',
];
}
return $procs;