redesign gpu monitor

Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2025-08-07 13:52:57 -04:00
parent 3e3adcee74
commit 4b74fd26b5
17 changed files with 171 additions and 168 deletions
+1 -1
View File
@@ -114,7 +114,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt
/* custom component */
.folder-selector textarea { height: 2em !important; padding: 6px !important; }
.nvml { position: fixed; bottom: 10px; right: 10px; background: var(--background-fill-primary); border: 1px solid var(--button-primary-border-color); padding: 6px; color: var(--button-primary-text-color);
.gpu { position: fixed; bottom: 10px; right: 10px; background: var(--background-fill-primary); border: 1px solid var(--button-primary-border-color); padding: 6px; color: var(--button-primary-text-color);
font-size: 0.7em; z-index: 50; font-family: monospace; display: none; }
/* image browser */
-1
View File
@@ -149,7 +149,6 @@ async function initContextMenu() {
appendContextMenuOption(id, 'Generate forever', () => generateForever(`#${tab}_generate`));
appendContextMenuOption(id, 'Apply selected style', quickApplyStyle);
appendContextMenuOption(id, 'Quick save style', quickSaveStyle);
appendContextMenuOption(id, 'nVidia overlay', startNVML);
id = `#${tab}_reprocess`;
appendContextMenuOption(id, 'Decode full quality', () => reprocessClick(`${tab}`, 'reprocess_decode'), true);
appendContextMenuOption(id, 'Refine & HiRes pass', () => reprocessClick(`${tab}`, 'reprocess_refine'), true);
+75
View File
@@ -0,0 +1,75 @@
let gpuInterval = null; // eslint-disable-line prefer-const
const chartData = { mem: [], load: [] };
async function updateGPUChart(mem, load) {
const maxLen = 120;
const colorRangeMap = $.range_map({ // eslint-disable-line no-undef
'0:5': '#fffafa',
'6:10': '#fff7ed',
'11:20': '#fed7aa',
'21:30': '#fdba74',
'31:40': '#fb923c',
'41:50': '#f97316',
'51:60': '#ea580c',
'61:70': '#c2410c',
'71:80': '#9a3412',
'81:90': '#7c2d12',
'91:100': '#6c2e12',
});
const sparklineConfigLOAD = { type: 'bar', height: '128px', barWidth: '3px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, barColor: '#89007D' };
const sparklineConfigMEM = { type: 'bar', height: '128px', barWidth: '3px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, colorMap: colorRangeMap, composite: true };
if (chartData.load.length > maxLen) chartData.load.shift();
chartData.load.push(load);
if (chartData.mem.length > maxLen) chartData.mem.shift();
chartData.mem.push(mem);
$('#gpuChart').sparkline(chartData.load, sparklineConfigLOAD); // eslint-disable-line no-undef
$('#gpuChart').sparkline(chartData.mem, sparklineConfigMEM); // eslint-disable-line no-undef
}
async function updateGPU() {
const gpuEl = document.getElementById('gpu');
const gpuTable = document.getElementById('gpu-table');
try {
const res = await fetch(`${window.api}/gpu`);
if (!res.ok) {
clearInterval(gpuInterval);
gpuEl.style.display = 'none';
return;
}
const data = await res.json();
if (!data) {
clearInterval(gpuInterval);
gpuEl.style.display = 'none';
return;
}
const gpuTbody = gpuTable.querySelector('tbody');
for (const gpu of data) {
console.log(gpu);
let rows = `<tr><td>GPU</td><td>${gpu.name}</td></tr>`;
for (const item of Object.entries(gpu.data)) rows += `<tr><td>${item[0]}</td><td>${item[1]}</td></tr>`;
gpuTbody.innerHTML = rows;
if (gpu.chart && gpu.chart.length === 2) updateGPUChart(gpu.chart);
}
gpuEl.style.display = 'block';
} catch (e) {
error('updateGPU', e);
clearInterval(gpuInterval);
gpuEl.style.display = 'none';
}
}
async function startGPU() {
const gpuEl = document.getElementById('gpu');
gpuEl.style.display = 'block';
if (gpuInterval) clearInterval(gpuInterval);
const interval = window.opts?.gpu_monitor || 3000;
log('startGPU', interval);
gpuInterval = setInterval(updateGPU, interval);
updateGPU();
}
async function disableGPU() {
clearInterval(gpuInterval);
const gpuEl = document.getElementById('gpu');
gpuEl.style.display = 'none';
}
-109
View File
@@ -1,109 +0,0 @@
let nvmlInterval = null; // eslint-disable-line prefer-const
let nvmlEl = null;
let nvmlTable = null;
const chartData = { mem: [], load: [] };
async function updateNVMLChart(mem, load) {
const maxLen = 120;
const colorRangeMap = $.range_map({ // eslint-disable-line no-undef
'0:5': '#fffafa',
'6:10': '#fff7ed',
'11:20': '#fed7aa',
'21:30': '#fdba74',
'31:40': '#fb923c',
'41:50': '#f97316',
'51:60': '#ea580c',
'61:70': '#c2410c',
'71:80': '#9a3412',
'81:90': '#7c2d12',
'91:100': '#6c2e12',
});
const sparklineConfigLOAD = { type: 'bar', height: '100px', barWidth: '2px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, barColor: '#89007D' };
const sparklineConfigMEM = { type: 'bar', height: '100px', barWidth: '2px', barSpacing: '1px', chartRangeMin: 0, chartRangeMax: 100, colorMap: colorRangeMap, composite: true };
if (chartData.load.length > maxLen) chartData.load.shift();
chartData.load.push(load);
if (chartData.mem.length > maxLen) chartData.mem.shift();
chartData.mem.push(mem);
$('#nvmlChart').sparkline(chartData.load, sparklineConfigLOAD); // eslint-disable-line no-undef
$('#nvmlChart').sparkline(chartData.mem, sparklineConfigMEM); // eslint-disable-line no-undef
}
async function updateNVML() {
try {
const res = await fetch(`${window.api}/nvml`);
if (!res.ok) {
clearInterval(nvmlInterval);
nvmlEl.style.display = 'none';
return;
}
const data = await res.json();
if (!data) {
clearInterval(nvmlInterval);
nvmlEl.style.display = 'none';
return;
}
const nvmlTbody = nvmlTable.querySelector('tbody');
for (const gpu of data) {
const rows = `
<tr><td>GPU</td><td>${gpu.name}</td></tr>
<tr><td>Driver</td><td>${gpu.version.driver}</td></tr>
<tr><td>VBIOS</td><td>${gpu.version.vbios}</td></tr>
<tr><td>ROM</td><td>${gpu.version.rom}</td></tr>
<tr><td>Driver</td><td>${gpu.version.driver}</td></tr>
<tr><td>PCI</td><td>Gen.${gpu.pci.link} x${gpu.pci.width}</td></tr>
<tr><td>Memory</td><td>${gpu.memory.used}Mb / ${gpu.memory.total}Mb</td></tr>
<tr><td>Clock</td><td>${gpu.clock.gpu[0]}Mhz / ${gpu.clock.gpu[1]}Mhz</td></tr>
<tr><td>Power</td><td>${gpu.power[0]}W / ${gpu.power[1]}W</td></tr>
<tr><td>Load GPU</td><td>${gpu.load.gpu}%</td></tr>
<tr><td>Load Memory</td><td>${gpu.load.memory}%</td></tr>
<tr><td>Temperature</td><td>${gpu.load.temp}°C</td></tr>
<tr><td>Fans</td><td>${gpu.load.fan}%</td></tr>
<tr><td>State</td><td>${gpu.state}</td></tr>
`;
nvmlTbody.innerHTML = rows;
updateNVMLChart(gpu.load.memory, gpu.load.gpu);
}
nvmlEl.style.display = 'block';
} catch (e) {
clearInterval(nvmlInterval);
nvmlEl.style.display = 'none';
}
}
async function initNVML() {
nvmlEl = document.getElementById('nvml');
if (!nvmlEl) {
nvmlEl = document.createElement('div');
nvmlEl.className = 'nvml';
nvmlEl.id = 'nvml';
nvmlTable = document.createElement('table');
nvmlTable.className = 'nvml-table';
nvmlTable.id = 'nvml-table';
nvmlTable.innerHTML = `
<thead><tr><th></th><th></th></tr></thead>
<tbody></tbody>
`;
const nvmlChart = document.createElement('div');
nvmlChart.id = 'nvmlChart';
nvmlEl.appendChild(nvmlTable);
nvmlEl.appendChild(nvmlChart);
gradioApp().appendChild(nvmlEl);
log('initNVML');
}
}
async function startNVML() {
nvmlEl = document.getElementById('nvml');
if (nvmlInterval) {
clearInterval(nvmlInterval);
nvmlInterval = null;
nvmlEl.style.display = 'none';
} else {
nvmlInterval = setInterval(updateNVML, 1000);
}
}
async function disableNVML() {
clearInterval(nvmlInterval);
nvmlEl.style.display = 'none';
}
+1 -2
View File
@@ -1616,14 +1616,13 @@ background: var(--background-color)
padding: 6px !important;
}
.nvml {
.gpu {
background: var(--background-fill-primary);
border: 1px solid var(--button-primary-border-color);
bottom: 10px;
color: var(--button-primary-text-color);
display: none;
font-family: monospace;
font-size: var(--text-xxs);
padding: 6px;
position: fixed;
right: 10px;
-1
View File
@@ -39,7 +39,6 @@ async function initStartup() {
executeCallbacks(uiReadyCallbacks);
initLogMonitor();
setupExtraNetworks();
initNVML();
// optinally wait for modern ui
if (window.waitForUiReady) await waitForUiReady();