Skip to content

Commit 9d493f4

Browse files
committed
Make GPU total memory available widely
1 parent dbdf154 commit 9d493f4

File tree

7 files changed

+73
-45
lines changed

7 files changed

+73
-45
lines changed

library/sensors/sensors.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ def fan_percent(fan_name: str = None) -> float:
5353
class Gpu(ABC):
5454
@staticmethod
5555
@abstractmethod
56-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
56+
def stats() -> Tuple[
57+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
5758
pass
5859

5960
@staticmethod

library/sensors/sensors_librehardwaremonitor.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,12 @@ def get_gpu_to_use(cls):
274274
return gpu_to_use
275275

276276
@classmethod
277-
def stats(cls) -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
277+
def stats(cls) -> Tuple[
278+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
278279
gpu_to_use = cls.get_gpu_to_use()
279280
if gpu_to_use is None:
280281
# GPU not supported
281-
return math.nan, math.nan, math.nan, math.nan
282+
return math.nan, math.nan, math.nan, math.nan, math.nan
282283

283284
load = math.nan
284285
used_mem = math.nan
@@ -310,24 +311,7 @@ def stats(cls) -> Tuple[float, float, float, float]: # load (%) / used mem (%)
310311
"GPU Core") and sensor.Value is not None:
311312
temp = float(sensor.Value)
312313

313-
return load, (used_mem / total_mem * 100.0), used_mem, temp
314-
315-
@classmethod
316-
def total_memory(cls) -> float:
317-
gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuAmd, cls.gpu_name)
318-
if gpu_to_use is None:
319-
gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuNvidia, cls.gpu_name)
320-
if gpu_to_use is None:
321-
gpu_to_use = get_hw_and_update(Hardware.HardwareType.GpuIntel, cls.gpu_name)
322-
if gpu_to_use is None:
323-
# GPU not supported
324-
return math.nan
325-
326-
for sensor in gpu_to_use.Sensors:
327-
if sensor.SensorType == Hardware.SensorType.SmallData and str(sensor.Name).startswith("GPU Memory Total"):
328-
return float(sensor.Value)
329-
330-
return math.nan
314+
return load, (used_mem / total_mem * 100.0), used_mem, total_mem, temp
331315

332316
@classmethod
333317
def fps(cls) -> int:

library/sensors/sensors_python.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,15 @@ def fan_percent(fan_name: str = None) -> float:
173173

174174
class Gpu(sensors.Gpu):
175175
@staticmethod
176-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
176+
def stats() -> Tuple[
177+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
177178
global DETECTED_GPU
178179
if DETECTED_GPU == GpuType.AMD:
179180
return GpuAmd.stats()
180181
elif DETECTED_GPU == GpuType.NVIDIA:
181182
return GpuNvidia.stats()
182183
else:
183-
return math.nan, math.nan, math.nan, math.nan
184+
return math.nan, math.nan, math.nan, math.nan, math.nan
184185

185186
@staticmethod
186187
def fps() -> int:
@@ -233,7 +234,8 @@ def is_available() -> bool:
233234

234235
class GpuNvidia(sensors.Gpu):
235236
@staticmethod
236-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
237+
def stats() -> Tuple[
238+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
237239
# Unlike other sensors, Nvidia GPU with GPUtil pulls in all the stats at once
238240
nvidia_gpus = GPUtil.getGPUs()
239241

@@ -246,6 +248,10 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u
246248
try:
247249
memory_total_all = [item.memoryTotal for item in nvidia_gpus]
248250
memory_total_mb = sum(memory_total_all) / len(memory_total_all)
251+
except:
252+
memory_total_mb = math.nan
253+
254+
try:
249255
memory_percentage = (memory_used_mb / memory_total_mb) * 100
250256
except:
251257
memory_percentage = math.nan
@@ -262,7 +268,7 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u
262268
except:
263269
temperature = math.nan
264270

265-
return load, memory_percentage, memory_used_mb, temperature
271+
return load, memory_percentage, memory_used_mb, memory_total_mb, temperature
266272

267273
@staticmethod
268274
def fps() -> int:
@@ -298,21 +304,28 @@ def is_available() -> bool:
298304

299305
class GpuAmd(sensors.Gpu):
300306
@staticmethod
301-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
307+
def stats() -> Tuple[
308+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
302309
if pyamdgpuinfo:
303310
# Unlike other sensors, AMD GPU with pyamdgpuinfo pulls in all the stats at once
304311
pyamdgpuinfo.detect_gpus()
305312
amd_gpu = pyamdgpuinfo.get_gpu(0)
306313

307314
try:
308315
memory_used_bytes = amd_gpu.query_vram_usage()
309-
memory_used = memory_used_bytes / 1000000
316+
memory_used = memory_used_bytes / 1024 / 1024
310317
except:
311318
memory_used_bytes = math.nan
312319
memory_used = math.nan
313320

314321
try:
315322
memory_total_bytes = amd_gpu.memory_info["vram_size"]
323+
memory_total = memory_total_bytes / 1024 / 1024
324+
except:
325+
memory_total_bytes = math.nan
326+
memory_total = math.nan
327+
328+
try:
316329
memory_percentage = (memory_used_bytes / memory_total_bytes) * 100
317330
except:
318331
memory_percentage = math.nan
@@ -327,7 +340,7 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u
327340
except:
328341
temperature = math.nan
329342

330-
return load, memory_percentage, memory_used, temperature
343+
return load, memory_percentage, memory_used, memory_total, temperature
331344
elif pyadl:
332345
amd_gpu = pyadl.ADLManager.getInstance().getDevices()[0]
333346

@@ -341,8 +354,8 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u
341354
except:
342355
temperature = math.nan
343356

344-
# Memory absolute (M) and relative (%) usage not supported by pyadl
345-
return load, math.nan, math.nan, temperature
357+
# GPU memory data not supported by pyadl
358+
return load, math.nan, math.nan, math.nan, temperature
346359

347360
@staticmethod
348361
def fps() -> int:
@@ -425,6 +438,7 @@ def virtual_free() -> int: # In bytes
425438
except:
426439
return -1
427440

441+
428442
class Disk(sensors.Disk):
429443
@staticmethod
430444
def disk_usage_percent() -> float:

library/sensors/sensors_stub_random.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ def fan_percent(fan_name: str = None) -> float:
4949

5050
class Gpu(sensors.Gpu):
5151
@staticmethod
52-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
53-
return random.uniform(0, 100), random.uniform(0, 100), random.uniform(300, 16000), random.uniform(30, 90)
52+
def stats() -> Tuple[
53+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
54+
return random.uniform(0, 100), random.uniform(0, 100), random.uniform(300, 16000), 16000.0, random.uniform(30,
55+
90)
5456

5557
@staticmethod
5658
def fps() -> int:

library/sensors/sensors_stub_static.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,13 @@ def fan_percent(fan_name: str = None) -> float:
6262

6363
class Gpu(sensors.Gpu):
6464
@staticmethod
65-
def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
66-
return PERCENTAGE_SENSOR_VALUE, PERCENTAGE_SENSOR_VALUE, \
67-
GPU_MEM_TOTAL_SIZE_GB / 100 * PERCENTAGE_SENSOR_VALUE * 1000, TEMPERATURE_SENSOR_VALUE
65+
def stats() -> Tuple[
66+
float, float, float, float, float]: # load (%) / used mem (%) / used mem (Mb) / total mem (Mb) / temp (°C)
67+
return (PERCENTAGE_SENSOR_VALUE,
68+
PERCENTAGE_SENSOR_VALUE,
69+
GPU_MEM_TOTAL_SIZE_GB / 100 * PERCENTAGE_SENSOR_VALUE * 1024,
70+
GPU_MEM_TOTAL_SIZE_GB * 1024,
71+
TEMPERATURE_SENSOR_VALUE)
6872

6973
@staticmethod
7074
def fps() -> int:

library/stats.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,10 @@ class Gpu:
367367

368368
@classmethod
369369
def stats(cls):
370-
load, memory_percentage, memory_used_mb, temperature = sensors.Gpu.stats()
370+
load, memory_percentage, memory_used_mb, total_memory_mb, temperature = sensors.Gpu.stats()
371371
fps = sensors.Gpu.fps()
372372
fan_percent = sensors.Gpu.fan_percent()
373373
freq_ghz = sensors.Gpu.frequency() / 1000
374-
total_memory = sensors.Gpu.total_memory()
375374

376375
theme_gpu_data = config.THEME_DATA['STATS']['GPU']
377376

@@ -472,14 +471,19 @@ def stats(cls):
472471
)
473472

474473
# GPU mem. total memory (M)
475-
gpu_total_mem_text_data = theme_gpu_data['MEMORY_TOTAL']['TEXT']
476-
if gpu_total_mem_text_data and gpu_total_mem_text_data['SHOW']:
477-
display_themed_value(
478-
theme_data=gpu_total_mem_text_data,
479-
value=int(total_memory),
480-
min_size=5, # Adjust min_size as necessary for your display
481-
unit=" M" # Assuming the unit is in Megabytes
482-
)
474+
gpu_mem_total_text_data = theme_gpu_data['MEMORY_TOTAL']['TEXT']
475+
if math.isnan(memory_used_mb):
476+
memory_used_mb = 0
477+
if gpu_mem_total_text_data['SHOW']:
478+
logger.warning("Your GPU total memory capacity (M) is not supported yet")
479+
gpu_mem_total_text_data['SHOW'] = False
480+
481+
display_themed_value(
482+
theme_data=gpu_mem_total_text_data,
483+
value=int(total_memory_mb),
484+
min_size=5, # Adjust min_size as necessary for your display
485+
unit=" M" # Assuming the unit is in Megabytes
486+
)
483487

484488
# GPU temperature (°C)
485489
gpu_temp_text_data = theme_gpu_data['TEMPERATURE']['TEXT']

res/themes/theme_example.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,25 @@ STATS:
580580
BACKGROUND_IMAGE: background.png
581581
ALIGN: left # left / center / right
582582
ANCHOR: lt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
583+
MEMORY_TOTAL:
584+
TEXT:
585+
SHOW: False
586+
SHOW_UNIT: True
587+
X: 204
588+
Y: 195
589+
# Text sensors may vary in size and create "ghosting" effects where old value stay displayed under the new one.
590+
# To avoid this use one of these 2 methods (or both):
591+
# - either use a monospaced font (fonts with "mono" in name, see res/fonts/ for available fonts)
592+
# - or force a static width/height for the text field. Be sure to have enough space for the longest value that can be displayed (e.g. "100%" for a percentage)
593+
# WIDTH: 200 # Uncomment to force a static width
594+
# HEIGHT: 50 # Uncomment to force static height
595+
FONT: jetbrains-mono/JetBrainsMono-Bold.ttf
596+
FONT_SIZE: 23
597+
FONT_COLOR: 255, 255, 255
598+
# BACKGROUND_COLOR: 132, 154, 165
599+
BACKGROUND_IMAGE: background.png
600+
ALIGN: left # left / center / right
601+
ANCHOR: lt # Check https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html
583602
TEMPERATURE:
584603
TEXT:
585604
SHOW: False

0 commit comments

Comments
 (0)