@@ -55,6 +55,8 @@ def __init__(self, device_id=0, nvidia_smi_fallback="nvidia-smi", use_locked_clo
55
55
self .mem_clock_default = None
56
56
self .supported_mem_clocks = []
57
57
self .supported_gr_clocks = {}
58
+ self .applications_gr_clock = self .gr_clock_default
59
+ self .applications_mem_clock = self .mem_clock_default
58
60
59
61
self .supported_mem_clocks = pynvml .nvmlDeviceGetSupportedMemoryClocks (self .dev )
60
62
@@ -71,6 +73,8 @@ def __init__(self, device_id=0, nvidia_smi_fallback="nvidia-smi", use_locked_clo
71
73
# try to set highest supported clocks
72
74
mem_clock = self .supported_mem_clocks [0 ]
73
75
gr_clock = self .supported_gr_clocks [mem_clock ][0 ]
76
+ self .locked_gr_clock = 0
77
+ self .locked_mem_clock = 0
74
78
self .set_clocks (mem_clock , gr_clock )
75
79
except pynvml .NVMLError_NotSupported :
76
80
# switch to using application clocks
@@ -142,6 +146,8 @@ def persistence_mode(self, new_mode):
142
146
143
147
def set_clocks (self , mem_clock , gr_clock ):
144
148
"""Set the memory and graphics clock for this device (may require permission)."""
149
+
150
+ mem_clock = min (self .supported_mem_clocks , key = lambda x : abs (x - mem_clock ))
145
151
if mem_clock not in self .supported_mem_clocks :
146
152
raise ValueError ("Illegal value for memory clock" )
147
153
if gr_clock not in self .supported_gr_clocks [mem_clock ]:
@@ -165,6 +171,8 @@ def set_clocks(self, mem_clock, gr_clock):
165
171
command_set_gpu_clocks = f"--lock-gpu-clocks={ str (gr_clock )} ,{ str (gr_clock )} "
166
172
subprocess .run (args + [command_set_gpu_clocks ], check = True )
167
173
subprocess .run (args + [command_set_mem_clocks ], check = True )
174
+ self .locked_gr_clock = gr_clock
175
+ self .locked_mem_clock = mem_clock
168
176
else :
169
177
try :
170
178
pynvml .nvmlDeviceSetApplicationsClocks (self .dev , mem_clock , gr_clock )
@@ -173,6 +181,8 @@ def set_clocks(self, mem_clock, gr_clock):
173
181
args = ["sudo" , self .nvidia_smi , "-i" , str (self .id )]
174
182
command_set_clocks = f"--applications-clocks={ str (mem_clock )} ,{ str (gr_clock )} "
175
183
subprocess .run (args + [command_set_clocks ], check = True )
184
+ self .applications_gr_clock = gr_clock
185
+ self .applications_mem_clock = mem_clock
176
186
177
187
# Store the fact that we have modified the clocks
178
188
self .modified_clocks = True
@@ -210,32 +220,33 @@ def reset_clocks(self):
210
220
211
221
@property
212
222
def gr_clock (self ):
213
- """Control the graphics clock (may require permission), only values compatible with the memory clock can be set directly."""
214
- if self .use_locked_clocks :
215
- return pynvml .nvmlDeviceGetClockInfo (self .dev , pynvml .NVML_CLOCK_GRAPHICS )
216
- else :
217
- return pynvml .nvmlDeviceGetApplicationsClock (self .dev , pynvml .NVML_CLOCK_GRAPHICS )
223
+ return pynvml .nvmlDeviceGetClockInfo (self .dev , pynvml .NVML_CLOCK_GRAPHICS )
218
224
219
225
@gr_clock .setter
220
226
def gr_clock (self , new_clock ):
221
- if new_clock != self .gr_clock :
222
- self .set_clocks (self .mem_clock , new_clock )
227
+ """Control the graphics clock (may require permission), only values compatible with the memory clock can be set directly."""
228
+ if self .use_locked_clocks :
229
+ if new_clock != self .locked_gr_clock :
230
+ self .set_clocks (self .mem_clock , new_clock )
231
+ else :
232
+ # if using applications clocks
233
+ if new_clock != pynvml .nvmlDeviceGetApplicationsClock (self .dev , pynvml .NVML_CLOCK_GRAPHICS ):
234
+ self .set_clocks (self .applications_mem_clock , new_clock )
223
235
224
236
@property
225
237
def mem_clock (self ):
226
238
"""Control the memory clock (may require permission), only values compatible with the graphics clock can be set directly."""
227
- if self .use_locked_clocks :
228
- # nvmlDeviceGetClock returns slightly different values than nvmlDeviceGetSupportedMemoryClocks,
229
- # therefore set mem_clock to the closest supported value
230
- mem_clock = pynvml .nvmlDeviceGetClockInfo (self .dev , pynvml .NVML_CLOCK_MEM )
231
- return min (self .supported_mem_clocks , key = lambda x : abs (x - mem_clock ))
232
- else :
233
- return pynvml .nvmlDeviceGetApplicationsClock (self .dev , pynvml .NVML_CLOCK_MEM )
239
+ return pynvml .nvmlDeviceGetClockInfo (self .dev , pynvml .NVML_CLOCK_MEM )
234
240
235
241
@mem_clock .setter
236
242
def mem_clock (self , new_clock ):
237
- if new_clock != self .mem_clock :
238
- self .set_clocks (new_clock , self .gr_clock )
243
+ if self .use_locked_clocks :
244
+ if new_clock != self .locked_mem_clock :
245
+ self .set_clocks (new_clock , self .gr_clock )
246
+ # if using applications clocks
247
+ else :
248
+ if new_clock != pynvml .nvmlDeviceGetApplicationsClock (self .dev , pynvml .NVML_CLOCK_MEM ):
249
+ self .set_clocks (new_clock , self .applications_gr_clock )
239
250
240
251
@property
241
252
def temperature (self ):
0 commit comments