87
87
logger .info ("Found Network interface: %s" % hardware .Name )
88
88
89
89
90
- def get_hw_and_update (hwtype : Hardware .HardwareType ) -> Hardware .Hardware :
90
+ def get_hw_and_update (hwtype : Hardware .HardwareType , name : str = None ) -> Hardware .Hardware :
91
91
for hardware in handle .Hardware :
92
92
if hardware .HardwareType == hwtype :
93
- hardware .Update ()
94
- return hardware
93
+ if (name and hardware .Name == name ) or not name :
94
+ hardware .Update ()
95
+ return hardware
95
96
return None
96
97
97
98
99
+ def get_gpu_name () -> str :
100
+ # Determine which GPU to use, in case there are multiple : try to avoid using discrete GPU for stats
101
+ hw_gpus = []
102
+ for hardware in handle .Hardware :
103
+ if hardware .HardwareType == Hardware .HardwareType .GpuNvidia \
104
+ or hardware .HardwareType == Hardware .HardwareType .GpuAmd \
105
+ or hardware .HardwareType == Hardware .HardwareType .GpuIntel :
106
+ hw_gpus .append (hardware )
107
+
108
+ if len (hw_gpus ) == 0 :
109
+ # No supported GPU found on the system
110
+ logger .warning ("No supported GPU found" )
111
+ return ""
112
+ elif len (hw_gpus ) == 1 :
113
+ # Found one supported GPU
114
+ logger .debug ("Found one supported GPU: %s" % hw_gpus [0 ].Name )
115
+ return str (hw_gpus [0 ].Name )
116
+ else :
117
+ # Found multiple GPUs, try to determine which one to use
118
+ amd_gpus = 0
119
+ intel_gpus = 0
120
+ nvidia_gpus = 0
121
+
122
+ gpu_to_use = ""
123
+
124
+ # Count GPUs by manufacturer
125
+ for gpu in hw_gpus :
126
+ if gpu .HardwareType == Hardware .HardwareType .GpuAmd :
127
+ amd_gpus += 1
128
+ elif gpu .HardwareType == Hardware .HardwareType .GpuIntel :
129
+ intel_gpus += 1
130
+ elif gpu .HardwareType == Hardware .HardwareType .GpuNvidia :
131
+ nvidia_gpus += 1
132
+
133
+ logger .warning (
134
+ "Found %d GPUs on your system (%d AMD / %d Nvidia / %d Intel). Auto identify which GPU to use." % (
135
+ len (hw_gpus ), amd_gpus , nvidia_gpus , intel_gpus ))
136
+
137
+ if nvidia_gpus >= 1 :
138
+ # One (or more) Nvidia GPU: use first available for stats
139
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuNvidia ).Name
140
+ elif amd_gpus == 1 :
141
+ # No Nvidia GPU, only one AMD GPU: use it
142
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuAmd ).Name
143
+ elif amd_gpus > 1 :
144
+ # No Nvidia GPU, several AMD GPUs found: try to use the real GPU but not the APU integrated in CPU
145
+ for gpu in hw_gpus :
146
+ if gpu .HardwareType == Hardware .HardwareType .GpuAmd :
147
+ for sensor in gpu .Sensors :
148
+ if sensor .SensorType == Hardware .SensorType .Load and str (sensor .Name ).startswith ("GPU Core" ):
149
+ # Found load sensor for this GPU: assume it is main GPU and use it for stats
150
+ gpu_to_use = gpu .Name
151
+ else :
152
+ # No AMD or Nvidia GPU: there are several Intel GPUs, use first available for stats
153
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuIntel ).Name
154
+
155
+ if gpu_to_use :
156
+ logger .debug ("This GPU will be used for stats: %s" % gpu_to_use )
157
+ else :
158
+ logger .warning ("No supported GPU found (no GPU with load sensor)" )
159
+
160
+ return gpu_to_use
161
+
162
+
98
163
def get_net_interface_and_update (if_name : str ) -> Hardware .Hardware :
99
164
for hardware in handle .Hardware :
100
165
if hardware .HardwareType == Hardware .HardwareType .Network and hardware .Name == if_name :
@@ -173,13 +238,16 @@ def temperature() -> float:
173
238
174
239
175
240
class Gpu (sensors .Gpu ):
176
- @staticmethod
177
- def stats () -> Tuple [float , float , float , float ]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
178
- gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuAmd )
241
+ # GPU to use is detected once, and its name is saved for future sensors readings
242
+ gpu_name = ""
243
+
244
+ @classmethod
245
+ def stats (cls ) -> Tuple [float , float , float , float ]: # load (%) / used mem (%) / used mem (Mb) / temp (°C)
246
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuAmd , cls .gpu_name )
179
247
if gpu_to_use is None :
180
- gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuNvidia )
248
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuNvidia , cls . gpu_name )
181
249
if gpu_to_use is None :
182
- gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuIntel )
250
+ gpu_to_use = get_hw_and_update (Hardware .HardwareType .GpuIntel , cls . gpu_name )
183
251
if gpu_to_use is None :
184
252
# GPU not supported
185
253
return math .nan , math .nan , math .nan , math .nan
@@ -206,17 +274,10 @@ def stats() -> Tuple[float, float, float, float]: # load (%) / used mem (%) / u
206
274
207
275
return load , (used_mem / total_mem * 100.0 ), used_mem , temp
208
276
209
- @staticmethod
210
- def is_available () -> bool :
211
- found_amd = (get_hw_and_update (Hardware .HardwareType .GpuAmd ) is not None )
212
- found_nvidia = (get_hw_and_update (Hardware .HardwareType .GpuNvidia ) is not None )
213
- found_intel = (get_hw_and_update (Hardware .HardwareType .GpuIntel ) is not None )
214
-
215
- if (found_amd and (found_nvidia or found_intel )) or (found_nvidia and found_intel ):
216
- logger .info (
217
- "Found multiple GPUs on your system. Will use dedicated GPU (AMD/Nvidia) for stats if possible." )
218
-
219
- return found_amd or found_nvidia or found_intel
277
+ @classmethod
278
+ def is_available (cls ) -> bool :
279
+ cls .gpu_name = get_gpu_name ()
280
+ return bool (cls .gpu_name )
220
281
221
282
222
283
class Memory (sensors .Memory ):
0 commit comments