Detect Intel integrated graphics, which nvidia-smi cannot see
HOST2 has UHD Graphics 730 and reported no GPU at all. An iGPU has no VRAM, no sensor of its own and no encode/decode split, so it is drawn from the per-engine busy figures Intel actually publishes and the fields it lacks are null rather than a confident zero.
This commit is contained in:
@@ -1789,11 +1789,23 @@ function vvPollMonitor(live) {
|
||||
p.gpu_uuid ? p.gpu_uuid === gpu.uuid : (gpu.index ?? 0) === 0
|
||||
);
|
||||
|
||||
const isIntel = gpu.vendor === 'intel';
|
||||
const vramPct = gpu.memory_total > 0 ? Math.round(gpu.memory_used / gpu.memory_total * 100) : 0;
|
||||
const utilPct = gpu.utilization ?? 0;
|
||||
const temp = gpu.temperature ?? 0;
|
||||
const tempColor = temp >= 85 ? '#f44336' : temp >= 70 ? '#ff9800' : '#4caf50';
|
||||
const powerStr = gpu.power_w != null ? gpu.power_w + ' W' : '—';
|
||||
// Package power when the GPU rail reads nothing, which is what Alder Lake reports. Labelled
|
||||
// "Pkg" in that case rather than passed off as the GPU's own draw.
|
||||
const powerStr = gpu.power_w != null ? gpu.power_w + ' W'
|
||||
: (isIntel && gpu.package_w != null) ? gpu.package_w + ' W' : '—';
|
||||
|
||||
// Video first — it is the engine a hardware transcode uses, and this is a media server.
|
||||
const engineOrder = ['Video', 'VideoEnhance', 'Render/3D', 'Blitter'];
|
||||
const engines = gpu.engines ?? {};
|
||||
const engineMeters = engineOrder
|
||||
.filter(n => engines[n] != null)
|
||||
.map(n => vvMeter(n === 'VideoEnhance' ? 'VideoEnh' : n, engines[n], `${engines[n]}%`))
|
||||
.join('');
|
||||
const procCount = gpuProcs.length;
|
||||
const procColor = procCount > 0 ? '#4caf50' : '#555';
|
||||
|
||||
@@ -1822,14 +1834,23 @@ function vvPollMonitor(live) {
|
||||
<div style="margin-left:8px;background:${procColor}22;border:1px solid ${procColor};color:${procColor};
|
||||
padding:1px 8px;border-radius:10px;font-size:11px;white-space:nowrap;">${procCount} proc${procCount !== 1 ? 's' : ''}</div>
|
||||
</div>` +
|
||||
vvMeter('VRAM', vramPct, `${gpu.memory_used} / ${gpu.memory_total} MB`) +
|
||||
vvMeter('GPU', utilPct, `${utilPct}%`) +
|
||||
vvMeter('Encode', gpu.enc_pct ?? 0, `${gpu.enc_pct ?? 0}%`) +
|
||||
vvMeter('Decode', gpu.dec_pct ?? 0, `${gpu.dec_pct ?? 0}%`) +
|
||||
// An integrated GPU has no VRAM pool, no sensor of its own and no encode/decode split,
|
||||
// so it is drawn from what Intel actually publishes — per-engine busy — rather than
|
||||
// from nvidia's fields with zeros standing in for the ones it lacks. Video is listed
|
||||
// first: on a media server it is the engine a hardware transcode uses.
|
||||
(isIntel
|
||||
? (gpu.utilization != null ? vvMeter('GPU', utilPct, `${utilPct}%`) : '')
|
||||
+ engineMeters
|
||||
: vvMeter('VRAM', vramPct, `${gpu.memory_used} / ${gpu.memory_total} MB`)
|
||||
+ vvMeter('GPU', utilPct, `${utilPct}%`)
|
||||
+ vvMeter('Encode', gpu.enc_pct ?? 0, `${gpu.enc_pct ?? 0}%`)
|
||||
+ vvMeter('Decode', gpu.dec_pct ?? 0, `${gpu.dec_pct ?? 0}%`)
|
||||
) +
|
||||
`<div style="display:flex;justify-content:space-between;font-size:11px;margin-top:6px;margin-bottom:8px;">
|
||||
<span style="color:#666;">Temp</span>
|
||||
<span style="color:${tempColor};font-weight:bold;">${temp}°C</span>
|
||||
<span style="color:#666;margin-left:12px;">Power</span>
|
||||
${gpu.temperature != null
|
||||
? `<span style="color:#666;">Temp</span><span style="color:${tempColor};font-weight:bold;">${temp}°C</span>`
|
||||
: `<span style="color:#666;">Temp</span><span style="color:#555;">in CPU pkg</span>`}
|
||||
<span style="color:#666;margin-left:12px;">${isIntel && gpu.power_w == null ? 'Pkg' : 'Power'}</span>
|
||||
<span style="color:#aaa;font-weight:bold;">${powerStr}</span>
|
||||
</div>` + gpuProcHtml;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user