Merge branch 'main' into dev
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ComfyUI-Crystools [](https://hits.seeyoufarm.com) [](https://paypal.me/crystian77)
|
||||
# ComfyUI-Crystools [](https://hits.seeyoufarm.com) [](https://paypal.me/crystian77) <a src="https://colab.research.google.com/assets/colab-badge.svg" href="https://colab.research.google.com/drive/1xiTiPmZkcIqNOsLQPO1UNCdJZqgK3U5k?usp=sharing"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"></a>
|
||||
|
||||
**_🪛 A powerful set of tools for your belt when you work with ComfyUI 🪛_**
|
||||
|
||||
@@ -37,13 +37,12 @@ You can configure the refresh rate which resources to show:
|
||||
|
||||
> **Notes:**
|
||||
> - The GPU data is only available when you use CUDA (only NVIDIA cards, sorry AMD users).
|
||||
> - It is not perfect, but it is a good approximation.
|
||||
> - This extension needs ComfyUI 1915 (or higher).
|
||||
> - The cost of the monitor is low (0.1 to 0.5% of utilization), you can disable it from settings (`Refres rate` to `0`).
|
||||
> - Data comes from these libraries:
|
||||
> - [psutil](https://pypi.org/project/psutil/)
|
||||
> - [torch](https://pytorch.org/)
|
||||
> - [pynvml](https://pypi.org/project/pynvml/) (official NVIDIA library)
|
||||
> - This is a beta version, so please report any issue you find.
|
||||
|
||||
|
||||
|
||||
### Progress bar
|
||||
@@ -513,6 +512,9 @@ You have predefined switches (string, latent, image, conditioning) but you can u
|
||||
|
||||
### Crystools
|
||||
|
||||
### 1.10.0 (17/01/2024)
|
||||
- Multi-gpu added
|
||||
|
||||
### 1.9.2 (15/01/2024)
|
||||
- Big refactor on hardwareInfo and monitor.ts, gpu was separated on another file, preparing for multi-gpu support
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
@author: Crystian
|
||||
@title: Crystools
|
||||
@nickname: Crystools
|
||||
@version: 1.9.3
|
||||
@version: 1.10.0
|
||||
@project: "https://github.com/crystian/ComfyUI-Crystools",
|
||||
@description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia
|
||||
"""
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
version = "1.9.3"
|
||||
version = "1.10.0"
|
||||
|
||||
+33
-14
@@ -15,8 +15,8 @@ class CGPUInfo:
|
||||
torchDevice = 'cpu'
|
||||
cudaDevice = 'cpu'
|
||||
cudaDevicesFound = 0
|
||||
switchGPU = False
|
||||
switchVRAM = False
|
||||
switchGPU = True
|
||||
switchVRAM = True
|
||||
gpus = []
|
||||
gpusUtilization = []
|
||||
gpusVRAM = []
|
||||
@@ -31,11 +31,17 @@ class CGPUInfo:
|
||||
|
||||
if self.pynvmlLoaded and pynvml.nvmlDeviceGetCount() > 0:
|
||||
self.cudaDevicesFound = pynvml.nvmlDeviceGetCount()
|
||||
|
||||
logger.info(f"GPU/s:")
|
||||
|
||||
# for simulate multiple GPUs (for testing) interchange these comments:
|
||||
# for deviceIndex in range(3):
|
||||
# deviceHandle = pynvml.nvmlDeviceGetHandleByIndex(0)
|
||||
for deviceIndex in range(self.cudaDevicesFound):
|
||||
deviceHandle = pynvml.nvmlDeviceGetHandleByIndex(deviceIndex)
|
||||
|
||||
gpuName = pynvml.nvmlDeviceGetName(deviceHandle)
|
||||
|
||||
logger.info(f"GPU/s:")
|
||||
logger.info(f"{deviceIndex}) {gpuName}")
|
||||
|
||||
self.gpus.append({
|
||||
@@ -44,8 +50,8 @@ class CGPUInfo:
|
||||
})
|
||||
|
||||
# same index as gpus, with default values
|
||||
self.gpusUtilization.append(False)
|
||||
self.gpusVRAM.append(False)
|
||||
self.gpusUtilization.append(True)
|
||||
self.gpusVRAM.append(True)
|
||||
|
||||
self.cuda = True
|
||||
logger.info(f'NVIDIA Driver: {pynvml.nvmlSystemGetDriverVersion()}')
|
||||
@@ -80,26 +86,39 @@ class CGPUInfo:
|
||||
if self.cudaDevice == 'cpu':
|
||||
gpuType = 'cpu'
|
||||
gpus.append({
|
||||
'gpu_utilization': -1,
|
||||
'vram_total': -1,
|
||||
'vram_used': -1,
|
||||
'vram_used_percent': -1,
|
||||
'gpu_utilization': 0,
|
||||
'vram_total': 0,
|
||||
'vram_used': 0,
|
||||
'vram_used_percent': 0,
|
||||
})
|
||||
else:
|
||||
gpuType = self.cudaDevice
|
||||
|
||||
if self.pynvmlLoaded and self.cuda and self.cudaAvailable:
|
||||
|
||||
# for simulate multiple GPUs (for testing) interchange these comments:
|
||||
# for deviceIndex in range(3):
|
||||
# deviceHandle = pynvml.nvmlDeviceGetHandleByIndex(0)
|
||||
for deviceIndex in range(self.cudaDevicesFound):
|
||||
deviceHandle = pynvml.nvmlDeviceGetHandleByIndex(deviceIndex)
|
||||
|
||||
# GPU Utilization
|
||||
# if self.switchGPU and self.gpusUtilization[deviceIndex]:
|
||||
if self.switchGPU:
|
||||
utilization = pynvml.nvmlDeviceGetUtilizationRates(deviceHandle)
|
||||
gpuUtilization = utilization.gpu
|
||||
if self.switchGPU and self.gpusUtilization[deviceIndex]:
|
||||
gpuUtilization = 0
|
||||
try:
|
||||
utilization = pynvml.nvmlDeviceGetUtilizationRates(deviceHandle)
|
||||
gpuUtilization = utilization.gpu
|
||||
except Exception as e:
|
||||
if str(e) == "Unknown Error":
|
||||
logger.error('For some reason, pynvml is not working in a laptop with only battery, try to connect and turn on the monitor')
|
||||
else:
|
||||
logger.error('Could not get GPU utilization.' + str(e))
|
||||
|
||||
logger.error('Monitor of GPU is turning off (not on UI!)')
|
||||
self.switchGPU = False
|
||||
|
||||
# VRAM
|
||||
if self.switchVRAM:
|
||||
if self.switchVRAM and self.gpusVRAM[deviceIndex]:
|
||||
# Torch or pynvml?, pynvml is more accurate with the system, torch is more accurate with comfyUI
|
||||
memory = pynvml.nvmlDeviceGetMemoryInfo(deviceHandle)
|
||||
vramUsed = memory.used
|
||||
|
||||
+6
-15
@@ -28,13 +28,6 @@ async def newSettings(request):
|
||||
|
||||
cmonitor.hardwareInfo.switchCPU = switchCPU
|
||||
|
||||
if 'switchGPU' in settings is not None:
|
||||
switchGPU = settings['switchGPU']
|
||||
if type(switchGPU) is not bool:
|
||||
raise Exception('switchGPU must be an boolean.')
|
||||
|
||||
cmonitor.hardwareInfo.switchGPU = switchGPU
|
||||
|
||||
if 'switchHDD' in settings is not None:
|
||||
switchHDD = settings['switchHDD']
|
||||
if type(switchHDD) is not bool:
|
||||
@@ -49,13 +42,6 @@ async def newSettings(request):
|
||||
|
||||
cmonitor.hardwareInfo.switchRAM = switchRAM
|
||||
|
||||
if 'switchVRAM' in settings is not None:
|
||||
switchVRAM = settings['switchVRAM']
|
||||
if type(switchVRAM) is not bool:
|
||||
raise Exception('switchVRAM must be an boolean.')
|
||||
|
||||
cmonitor.hardwareInfo.switchVRAM = switchVRAM
|
||||
|
||||
if 'whichHDD' in settings is not None:
|
||||
whichHDD = settings['whichHDD']
|
||||
if type(whichHDD) is not str:
|
||||
@@ -104,7 +90,6 @@ def getHDDs(request):
|
||||
def getGPUs(request):
|
||||
try:
|
||||
gpuInfo = cmonitor.hardwareInfo.getGPUInfo()
|
||||
print(gpuInfo)
|
||||
return web.json_response(gpuInfo)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
@@ -122,6 +107,12 @@ async def getGPUs(request):
|
||||
|
||||
cmonitor.hardwareInfo.GPUInfo.gpusUtilization[int(index)] = settings['utilization']
|
||||
|
||||
if 'vram' in settings is not None:
|
||||
if type(settings['vram']) is not bool:
|
||||
raise Exception('vram must be an boolean.')
|
||||
|
||||
cmonitor.hardwareInfo.GPUInfo.gpusVRAM[int(index)] = settings['vram']
|
||||
|
||||
return web.Response(status=200)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
+140
-62
@@ -51,6 +51,18 @@ class CrystoolsMonitor {
|
||||
writable: true,
|
||||
value: '/'
|
||||
});
|
||||
Object.defineProperty(this, "monitorGPUSettings", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: []
|
||||
});
|
||||
Object.defineProperty(this, "monitorVRAMSettings", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: []
|
||||
});
|
||||
Object.defineProperty(this, "monitorCPUElement", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
@@ -118,50 +130,6 @@ class CrystoolsMonitor {
|
||||
},
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "monitorGPUElement", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: {
|
||||
id: 'Crystools.switchGPU',
|
||||
name: this.menuPrefix + ' [monitor] GPU Usage',
|
||||
type: 'boolean',
|
||||
label: 'GPU',
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#0C86F4',
|
||||
onChange: async (value) => {
|
||||
this.updateWidget(this.monitorGPUElement);
|
||||
await this.updateServer({
|
||||
switchGPU: value,
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "monitorVRAMElement", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: {
|
||||
id: 'Crystools.switchVRAM',
|
||||
name: this.menuPrefix + ' [monitor] VRAM Used',
|
||||
type: 'boolean',
|
||||
label: 'VRAM',
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#176EC7',
|
||||
onChange: async (value) => {
|
||||
this.updateWidget(this.monitorVRAMElement);
|
||||
await this.updateServer({
|
||||
switchVRAM: value,
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "createSettings", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
@@ -169,8 +137,6 @@ class CrystoolsMonitor {
|
||||
value: () => {
|
||||
app.ui.settings.addSetting(this.monitorCPUElement);
|
||||
app.ui.settings.addSetting(this.monitorRAMElement);
|
||||
app.ui.settings.addSetting(this.monitorGPUElement);
|
||||
app.ui.settings.addSetting(this.monitorVRAMElement);
|
||||
app.ui.settings.addSetting(this.monitorHDDElement);
|
||||
app.ui.settings.addSetting({
|
||||
id: this.idInputRate,
|
||||
@@ -246,6 +212,64 @@ class CrystoolsMonitor {
|
||||
},
|
||||
});
|
||||
});
|
||||
void this.getGPUsFromServer().then((gpus) => {
|
||||
let moreThanOneGPU = false;
|
||||
if (gpus.length > 1) {
|
||||
moreThanOneGPU = true;
|
||||
}
|
||||
gpus?.forEach(({ name, index }) => {
|
||||
if (name === undefined || index === undefined) {
|
||||
console.warn('getGPUsFromServer: name or index undefined', name, index);
|
||||
return;
|
||||
}
|
||||
let label = 'GPU';
|
||||
let labelVRAM = 'VRAM';
|
||||
if (moreThanOneGPU) {
|
||||
label = 'GPU ' + index;
|
||||
labelVRAM = 'VRAM' + index;
|
||||
}
|
||||
const monitorGPUNElement = {
|
||||
id: 'Crystools.switchGPU' + index,
|
||||
name: this.menuPrefix + `[menu] Display GPU monitor\r\n[${index}] ${name}`,
|
||||
type: 'boolean',
|
||||
label,
|
||||
title: `${index}: ${name}`,
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#0C86F4',
|
||||
onChange: async (value) => {
|
||||
this.updateWidget(monitorGPUNElement);
|
||||
void await this.updateServerGPU(index, {
|
||||
utilization: value
|
||||
});
|
||||
},
|
||||
};
|
||||
const monitorVRAMNElement = {
|
||||
id: 'Crystools.switchVRAM' + index,
|
||||
name: this.menuPrefix + `[menu] Display GPU VRAM monitor\r\n[${index}] ${name}`,
|
||||
type: 'boolean',
|
||||
label: labelVRAM,
|
||||
title: `${index}: ${name}`,
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#176EC7',
|
||||
onChange: async (value) => {
|
||||
this.updateWidget(monitorVRAMNElement);
|
||||
void await this.updateServerGPU(index, {
|
||||
vram: value
|
||||
});
|
||||
},
|
||||
};
|
||||
this.monitorGPUSettings[index] = monitorGPUNElement;
|
||||
this.monitorVRAMSettings[index] = monitorVRAMNElement;
|
||||
app.ui.settings.addSetting(this.monitorGPUSettings[index]);
|
||||
app.ui.settings.addSetting(this.monitorVRAMSettings[index]);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updateServer", {
|
||||
@@ -264,6 +288,22 @@ class CrystoolsMonitor {
|
||||
throw new Error(resp.statusText);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updateServerGPU", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: async (index, data) => {
|
||||
const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
cache: 'no-store',
|
||||
});
|
||||
if (resp.status === 200) {
|
||||
return await resp.text();
|
||||
}
|
||||
throw new Error(resp.statusText);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "getHDDsFromServer", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
@@ -272,6 +312,14 @@ class CrystoolsMonitor {
|
||||
return this.getDataFromServer('HDD');
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "getGPUsFromServer", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: async () => {
|
||||
return this.getDataFromServer('GPU');
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "getDataFromServer", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
@@ -294,9 +342,13 @@ class CrystoolsMonitor {
|
||||
value: () => {
|
||||
this.updateWidget(this.monitorCPUElement);
|
||||
this.updateWidget(this.monitorRAMElement);
|
||||
this.updateWidget(this.monitorGPUElement);
|
||||
this.updateWidget(this.monitorVRAMElement);
|
||||
this.updateWidget(this.monitorHDDElement);
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updateWidget(monitorSettings);
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updateWidget(monitorSettings);
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updateWidget", {
|
||||
@@ -322,13 +374,28 @@ class CrystoolsMonitor {
|
||||
console.warn('UpdateAllMonitors: no GPU data');
|
||||
return;
|
||||
}
|
||||
const gpu = data.gpus[0] ? data.gpus[0] : {
|
||||
gpu_utilization: 0, vram_used_percent: 0,
|
||||
};
|
||||
const gpu_utilization = gpu.gpu_utilization;
|
||||
const vram_used_percent = gpu.vram_used_percent;
|
||||
this.updateMonitor(this.monitorGPUElement, gpu_utilization);
|
||||
this.updateMonitor(this.monitorVRAMElement, vram_used_percent);
|
||||
this.monitorGPUSettings.forEach((monitorSettings, index) => {
|
||||
if (data.gpus[index]) {
|
||||
const gpu = data.gpus[index];
|
||||
if (gpu === undefined) {
|
||||
return;
|
||||
}
|
||||
this.updateMonitor(monitorSettings, gpu.gpu_utilization);
|
||||
}
|
||||
else {
|
||||
}
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings, index) => {
|
||||
if (data.gpus[index]) {
|
||||
const gpu = data.gpus[index];
|
||||
if (gpu === undefined) {
|
||||
return;
|
||||
}
|
||||
this.updateMonitor(monitorSettings, gpu.vram_used_percent);
|
||||
}
|
||||
else {
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updateMonitor", {
|
||||
@@ -341,9 +408,6 @@ class CrystoolsMonitor {
|
||||
}
|
||||
monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}%`;
|
||||
monitorSettings.htmlMonitorSliderRef.style.width = monitorSettings.htmlMonitorLabelRef.innerHTML;
|
||||
if (monitorSettings.tooltip) {
|
||||
monitorSettings.htmlMonitorLabelRef.title = monitorSettings.tooltip;
|
||||
}
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updateAllAnimationDuration", {
|
||||
@@ -353,9 +417,13 @@ class CrystoolsMonitor {
|
||||
value: (value) => {
|
||||
this.updatedAnimationDuration(this.monitorCPUElement, value);
|
||||
this.updatedAnimationDuration(this.monitorRAMElement, value);
|
||||
this.updatedAnimationDuration(this.monitorGPUElement, value);
|
||||
this.updatedAnimationDuration(this.monitorVRAMElement, value);
|
||||
this.updatedAnimationDuration(this.monitorHDDElement, value);
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updatedAnimationDuration(monitorSettings, value);
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updatedAnimationDuration(monitorSettings, value);
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, "updatedAnimationDuration", {
|
||||
@@ -375,6 +443,9 @@ class CrystoolsMonitor {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: (monitorSettings) => {
|
||||
if (!monitorSettings) {
|
||||
return document.createElement('div');
|
||||
}
|
||||
const htmlMain = document.createElement('div');
|
||||
htmlMain.setAttribute('id', monitorSettings.id);
|
||||
htmlMain.style.margin = '2px 10px';
|
||||
@@ -384,6 +455,9 @@ class CrystoolsMonitor {
|
||||
htmlMain.style.alignItems = 'center';
|
||||
htmlMain.style.flexDirection = 'row';
|
||||
monitorSettings.htmlMonitorRef = htmlMain;
|
||||
if (monitorSettings.title) {
|
||||
htmlMain.title = monitorSettings.title;
|
||||
}
|
||||
const htmlMonitorText = document.createElement('div');
|
||||
htmlMonitorText.style.width = '35px';
|
||||
htmlMonitorText.style.fontSize = '10px';
|
||||
@@ -448,8 +522,12 @@ class CrystoolsMonitor {
|
||||
ctoolsRoot.append(htmlContainer);
|
||||
htmlContainer.append(this.createMonitor(this.monitorCPUElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorRAMElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorGPUElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorVRAMElement));
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings));
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings));
|
||||
});
|
||||
htmlContainer.append(this.createMonitor(this.monitorHDDElement));
|
||||
const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate));
|
||||
this.updateAllAnimationDuration(currentRate);
|
||||
|
||||
+148
-93
@@ -12,6 +12,8 @@ class CrystoolsMonitor {
|
||||
defaultRate = .5;
|
||||
idWhichHDD = 'Crystools.whichHDD';
|
||||
defaultWhichHDD = '/';
|
||||
monitorGPUSettings: TMonitorSettings[] = [];
|
||||
monitorVRAMSettings: TMonitorSettings[] = [];
|
||||
|
||||
// CPU Variables
|
||||
monitorCPUElement: TMonitorSettings = {
|
||||
@@ -71,44 +73,6 @@ class CrystoolsMonitor {
|
||||
},
|
||||
};
|
||||
|
||||
// GPU Variables
|
||||
monitorGPUElement: TMonitorSettings = {
|
||||
id: 'Crystools.switchGPU',
|
||||
name: this.menuPrefix + ' [monitor] GPU Usage',
|
||||
type: 'boolean',
|
||||
label: 'GPU',
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#0C86F4',
|
||||
onChange: async(value: boolean) => {
|
||||
this.updateWidget(this.monitorGPUElement);
|
||||
await this.updateServer({
|
||||
switchGPU: value,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// VRAM Variables
|
||||
monitorVRAMElement: TMonitorSettings = {
|
||||
id: 'Crystools.switchVRAM',
|
||||
name: this.menuPrefix + ' [monitor] VRAM Used',
|
||||
type: 'boolean',
|
||||
label: 'VRAM',
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#176EC7',
|
||||
onChange: async(value: boolean) => {
|
||||
this.updateWidget(this.monitorVRAMElement);
|
||||
await this.updateServer({
|
||||
switchVRAM: value,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
constructor() {
|
||||
this.createSettings();
|
||||
}
|
||||
@@ -116,8 +80,6 @@ class CrystoolsMonitor {
|
||||
createSettings = (): void => {
|
||||
app.ui.settings.addSetting(this.monitorCPUElement);
|
||||
app.ui.settings.addSetting(this.monitorRAMElement);
|
||||
app.ui.settings.addSetting(this.monitorGPUElement);
|
||||
app.ui.settings.addSetting(this.monitorVRAMElement);
|
||||
app.ui.settings.addSetting(this.monitorHDDElement);
|
||||
|
||||
app.ui.settings.addSetting({
|
||||
@@ -199,27 +161,76 @@ class CrystoolsMonitor {
|
||||
});
|
||||
});
|
||||
|
||||
void this.getGPUsFromServer().then((gpus: TGpuName[]): void => {
|
||||
let moreThanOneGPU = false;
|
||||
if (gpus.length > 1) {
|
||||
moreThanOneGPU = true;
|
||||
}
|
||||
|
||||
// void this.getGPUsFromServer().then((gpus: TGpuName[]): void => {
|
||||
// console.log(gpus);
|
||||
// gpus?.forEach(({
|
||||
// name, index
|
||||
// }) => {
|
||||
// const id = this.idSwitchGPU + index;
|
||||
// app.ui.settings.addSetting({
|
||||
// id,
|
||||
// name: this.menuPrefix + `[menu] Display GPU monitor\r\n[${index}] ${name}`,
|
||||
// type: 'boolean',
|
||||
// defaultValue: this.defaultSwitchGPU,
|
||||
// onChange: async(value: boolean)=> {
|
||||
// // this.updateWidget(value, this.htmlMonitorGPURef);
|
||||
// void await this.updateServerGPU(index,{
|
||||
// utilization: value
|
||||
// });
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
gpus?.forEach(({
|
||||
name, index
|
||||
}) => {
|
||||
|
||||
if(name === undefined || index === undefined) {
|
||||
console.warn('getGPUsFromServer: name or index undefined', name, index);
|
||||
return;
|
||||
}
|
||||
|
||||
let label = 'GPU';
|
||||
let labelVRAM = 'VRAM';
|
||||
if (moreThanOneGPU) {
|
||||
label = 'GPU '+index;
|
||||
labelVRAM = 'VRAM'+index;
|
||||
}
|
||||
|
||||
// GPU Utilization Variables
|
||||
const monitorGPUNElement: TMonitorSettings = {
|
||||
id: 'Crystools.switchGPU' + index,
|
||||
name: this.menuPrefix + `[menu] Display GPU monitor\r\n[${index}] ${name}`,
|
||||
type: 'boolean',
|
||||
label,
|
||||
title: `${index}: ${name}`,
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#0C86F4',
|
||||
onChange: async(value: boolean) => {
|
||||
this.updateWidget(monitorGPUNElement);
|
||||
void await this.updateServerGPU(index,{
|
||||
utilization: value
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// GPU VRAM Variables
|
||||
const monitorVRAMNElement: TMonitorSettings = {
|
||||
id: 'Crystools.switchVRAM' + index,
|
||||
name: this.menuPrefix + `[menu] Display GPU VRAM monitor\r\n[${index}] ${name}`,
|
||||
type: 'boolean',
|
||||
label: labelVRAM,
|
||||
title: `${index}: ${name}`,
|
||||
defaultValue: true,
|
||||
htmlMonitorRef: undefined,
|
||||
htmlMonitorSliderRef: undefined,
|
||||
htmlMonitorLabelRef: undefined,
|
||||
cssColor: '#176EC7',
|
||||
onChange: async(value: boolean) => {
|
||||
this.updateWidget(monitorVRAMNElement);
|
||||
void await this.updateServerGPU(index,{
|
||||
vram: value
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
this.monitorGPUSettings[index] = monitorGPUNElement;
|
||||
this.monitorVRAMSettings[index] = monitorVRAMNElement;
|
||||
// @ts-ignore
|
||||
app.ui.settings.addSetting(this.monitorGPUSettings[index]);
|
||||
// @ts-ignore
|
||||
app.ui.settings.addSetting(this.monitorVRAMSettings[index]);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -235,26 +246,25 @@ class CrystoolsMonitor {
|
||||
throw new Error(resp.statusText);
|
||||
};
|
||||
|
||||
// updateServerGPU = async(index: number, data: TGpuSettings): Promise<string> => {
|
||||
// console.log('updateServerGPU', index, data);
|
||||
// const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, {
|
||||
// method: 'PATCH',
|
||||
// body: JSON.stringify(data),
|
||||
// cache: 'no-store',
|
||||
// });
|
||||
// if (resp.status === 200) {
|
||||
// return await resp.text();
|
||||
// }
|
||||
// throw new Error(resp.statusText);
|
||||
// };
|
||||
updateServerGPU = async(index: number, data: TGpuSettings): Promise<string> => {
|
||||
const resp = await api.fetchApi(`/crystools/monitor/GPU/${index}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
cache: 'no-store',
|
||||
});
|
||||
if (resp.status === 200) {
|
||||
return await resp.text();
|
||||
}
|
||||
throw new Error(resp.statusText);
|
||||
};
|
||||
|
||||
getHDDsFromServer = async(): Promise<string[]> => {
|
||||
return this.getDataFromServer('HDD');
|
||||
};
|
||||
|
||||
// getGPUsFromServer = async(): Promise<TGpuName[]> => {
|
||||
// return this.getDataFromServer<TGpuName>('GPU');
|
||||
// };
|
||||
getGPUsFromServer = async(): Promise<TGpuName[]> => {
|
||||
return this.getDataFromServer<TGpuName>('GPU');
|
||||
};
|
||||
|
||||
getDataFromServer = async<T>(what: string): Promise<T[]> => {
|
||||
const resp = await api.fetchApi(`/crystools/monitor/${what}`, {
|
||||
@@ -270,9 +280,14 @@ class CrystoolsMonitor {
|
||||
updateAllWidget = (): void => {
|
||||
this.updateWidget(this.monitorCPUElement);
|
||||
this.updateWidget(this.monitorRAMElement);
|
||||
this.updateWidget(this.monitorGPUElement);
|
||||
this.updateWidget(this.monitorVRAMElement);
|
||||
this.updateWidget(this.monitorHDDElement);
|
||||
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updateWidget(monitorSettings);
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updateWidget(monitorSettings);
|
||||
});
|
||||
};
|
||||
|
||||
updateWidget = (monitorSettings: TMonitorSettings): void => {
|
||||
@@ -293,15 +308,34 @@ class CrystoolsMonitor {
|
||||
return;
|
||||
}
|
||||
|
||||
const gpu = data.gpus[0] ? data.gpus[0] : {
|
||||
gpu_utilization: 0, vram_used_percent: 0,
|
||||
};
|
||||
|
||||
const gpu_utilization = gpu.gpu_utilization;
|
||||
const vram_used_percent = gpu.vram_used_percent;
|
||||
this.monitorGPUSettings.forEach((monitorSettings, index) => {
|
||||
if (data.gpus[index]) {
|
||||
const gpu = data.gpus[index];
|
||||
if (gpu === undefined) {
|
||||
// console.error('UpdateAllMonitors: no GPU data for index', index);
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateMonitor(this.monitorGPUElement, gpu_utilization);
|
||||
this.updateMonitor(this.monitorVRAMElement, vram_used_percent);
|
||||
this.updateMonitor(monitorSettings, gpu.gpu_utilization);
|
||||
} else {
|
||||
// console.error('UpdateAllMonitors: no GPU data for index', index);
|
||||
}
|
||||
});
|
||||
|
||||
this.monitorVRAMSettings.forEach((monitorSettings, index) => {
|
||||
if (data.gpus[index]) {
|
||||
const gpu = data.gpus[index];
|
||||
if (gpu === undefined) {
|
||||
// console.error('UpdateAllMonitors: no GPU VRAM data for index', index);
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateMonitor(monitorSettings, gpu.vram_used_percent);
|
||||
} else {
|
||||
// console.error('UpdateAllMonitors: no GPU VRAM data for index', index);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
updateMonitor = (monitorSettings: TMonitorSettings, percent: number): void => {
|
||||
@@ -311,17 +345,18 @@ class CrystoolsMonitor {
|
||||
|
||||
monitorSettings.htmlMonitorLabelRef.innerHTML = `${Math.floor(percent)}%`;
|
||||
monitorSettings.htmlMonitorSliderRef.style.width = monitorSettings.htmlMonitorLabelRef.innerHTML;
|
||||
if (monitorSettings.tooltip) {
|
||||
monitorSettings.htmlMonitorLabelRef.title = monitorSettings.tooltip;
|
||||
}
|
||||
};
|
||||
|
||||
updateAllAnimationDuration = (value: number): void => {
|
||||
this.updatedAnimationDuration(this.monitorCPUElement, value);
|
||||
this.updatedAnimationDuration(this.monitorRAMElement, value);
|
||||
this.updatedAnimationDuration(this.monitorGPUElement, value);
|
||||
this.updatedAnimationDuration(this.monitorVRAMElement, value);
|
||||
this.updatedAnimationDuration(this.monitorHDDElement, value);
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updatedAnimationDuration(monitorSettings, value);
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && this.updatedAnimationDuration(monitorSettings, value);
|
||||
});
|
||||
};
|
||||
|
||||
updatedAnimationDuration = (monitorSettings: TMonitorSettings, value: number): void => {
|
||||
@@ -356,8 +391,21 @@ class CrystoolsMonitor {
|
||||
|
||||
htmlContainer.append(this.createMonitor(this.monitorCPUElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorRAMElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorGPUElement));
|
||||
htmlContainer.append(this.createMonitor(this.monitorVRAMElement));
|
||||
|
||||
// gpu0 > gpu1 > vram0 > vram1
|
||||
this.monitorGPUSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings));
|
||||
});
|
||||
this.monitorVRAMSettings.forEach((monitorSettings) => {
|
||||
monitorSettings && htmlContainer.append(this.createMonitor(monitorSettings));
|
||||
});
|
||||
|
||||
// gpu0 > vram0 > gpu1 > vram1
|
||||
// this.monitorGPUSettings.forEach((_monitorSettings, index) => {
|
||||
// this.monitorGPUSettings[index] && htmlContainer.append(this.createMonitor(this.monitorGPUSettings[index]));
|
||||
// this.monitorVRAMSettings[index] && htmlContainer.append(this.createMonitor(this.monitorVRAMSettings[index]));
|
||||
// });
|
||||
|
||||
htmlContainer.append(this.createMonitor(this.monitorHDDElement));
|
||||
|
||||
const currentRate = parseFloat(app.ui.settings.getSettingValue(this.idInputRate, this.defaultRate));
|
||||
@@ -366,7 +414,11 @@ class CrystoolsMonitor {
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
createMonitor = (monitorSettings: TMonitorSettings): HTMLDivElement => {
|
||||
createMonitor = (monitorSettings?: TMonitorSettings): HTMLDivElement => {
|
||||
if (!monitorSettings) {
|
||||
// just for typescript
|
||||
return document.createElement('div');
|
||||
}
|
||||
const htmlMain = document.createElement('div');
|
||||
htmlMain.setAttribute('id', monitorSettings.id);
|
||||
htmlMain.style.margin = '2px 10px';
|
||||
@@ -377,6 +429,10 @@ class CrystoolsMonitor {
|
||||
htmlMain.style.flexDirection = 'row';
|
||||
monitorSettings.htmlMonitorRef = htmlMain;
|
||||
|
||||
if (monitorSettings.title) {
|
||||
htmlMain.title = monitorSettings.title;
|
||||
}
|
||||
|
||||
const htmlMonitorText = document.createElement('div');
|
||||
htmlMonitorText.style.width = '35px';
|
||||
htmlMonitorText.style.fontSize = '10px';
|
||||
@@ -395,7 +451,6 @@ class CrystoolsMonitor {
|
||||
htmlMonitorSlider.style.height = '100%';
|
||||
htmlMonitorSlider.style.width = '0';
|
||||
htmlMonitorSlider.style.backgroundColor = monitorSettings.cssColor;
|
||||
// htmlMonitorSlider.style.transition = 'width 0.5s';
|
||||
monitorSettings.htmlMonitorSliderRef = htmlMonitorSlider;
|
||||
htmlMonitorContent.append(htmlMonitorSlider);
|
||||
|
||||
|
||||
Vendored
+2
-1
@@ -41,7 +41,8 @@ type TMonitorSettings = {
|
||||
id: string,
|
||||
name: string,
|
||||
label: string, // on monitor
|
||||
tooltip?: string,
|
||||
title?: string, // on monitor
|
||||
tooltip?: string, // on settings
|
||||
type: 'boolean' | 'number' | 'string',
|
||||
defaultValue: boolean,
|
||||
onChange: (value: boolean) => Promise<void>,
|
||||
|
||||
@@ -126,7 +126,6 @@ class CrystoolsProgressBar {
|
||||
else if (this.currentStatus === EStatus.execution_error) {
|
||||
this.htmlProgressLabelRef.innerHTML = 'ERROR';
|
||||
this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)';
|
||||
console.log('execution_error');
|
||||
}
|
||||
else if (this.currentStatus === EStatus.executing) {
|
||||
this.htmlProgressLabelRef.innerHTML = `${this.currentProgress}%`;
|
||||
|
||||
@@ -68,7 +68,6 @@ class CrystoolsProgressBar {
|
||||
// an error occurred
|
||||
this.htmlProgressLabelRef.innerHTML = 'ERROR';
|
||||
this.htmlProgressSliderRef.style.backgroundColor = 'var(--error-text)';
|
||||
console.log('execution_error');
|
||||
|
||||
} else if (this.currentStatus === EStatus.executing) {
|
||||
// on going
|
||||
|
||||
Reference in New Issue
Block a user