@@ -55,6 +55,8 @@ def __init__(self, device_id=0, nvidia_smi_fallback="nvidia-smi", use_locked_clo
5555 self .mem_clock_default = None
5656 self .supported_mem_clocks = []
5757 self .supported_gr_clocks = {}
58+ self .applications_gr_clock = self .gr_clock_default
59+ self .applications_mem_clock = self .mem_clock_default
5860
5961 self .supported_mem_clocks = pynvml .nvmlDeviceGetSupportedMemoryClocks (self .dev )
6062
@@ -71,6 +73,8 @@ def __init__(self, device_id=0, nvidia_smi_fallback="nvidia-smi", use_locked_clo
7173 # try to set highest supported clocks
7274 mem_clock = self .supported_mem_clocks [0 ]
7375 gr_clock = self .supported_gr_clocks [mem_clock ][0 ]
76+ self .locked_gr_clock = 0
77+ self .locked_mem_clock = 0
7478 self .set_clocks (mem_clock , gr_clock )
7579 except pynvml .NVMLError_NotSupported :
7680 # switch to using application clocks
@@ -142,6 +146,8 @@ def persistence_mode(self, new_mode):
142146
143147 def set_clocks (self , mem_clock , gr_clock ):
144148 """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 ))
145151 if mem_clock not in self .supported_mem_clocks :
146152 raise ValueError ("Illegal value for memory clock" )
147153 if gr_clock not in self .supported_gr_clocks [mem_clock ]:
@@ -165,6 +171,8 @@ def set_clocks(self, mem_clock, gr_clock):
165171 command_set_gpu_clocks = f"--lock-gpu-clocks={ str (gr_clock )} ,{ str (gr_clock )} "
166172 subprocess .run (args + [command_set_gpu_clocks ], check = True )
167173 subprocess .run (args + [command_set_mem_clocks ], check = True )
174+ self .locked_gr_clock = gr_clock
175+ self .locked_mem_clock = mem_clock
168176 else :
169177 try :
170178 pynvml .nvmlDeviceSetApplicationsClocks (self .dev , mem_clock , gr_clock )
@@ -173,6 +181,8 @@ def set_clocks(self, mem_clock, gr_clock):
173181 args = ["sudo" , self .nvidia_smi , "-i" , str (self .id )]
174182 command_set_clocks = f"--applications-clocks={ str (mem_clock )} ,{ str (gr_clock )} "
175183 subprocess .run (args + [command_set_clocks ], check = True )
184+ self .applications_gr_clock = gr_clock
185+ self .applications_mem_clock = mem_clock
176186
177187 # Store the fact that we have modified the clocks
178188 self .modified_clocks = True
@@ -210,32 +220,33 @@ def reset_clocks(self):
210220
211221 @property
212222 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 )
218224
219225 @gr_clock .setter
220226 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 )
223235
224236 @property
225237 def mem_clock (self ):
226238 """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 )
234240
235241 @mem_clock .setter
236242 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 )
239250
240251 @property
241252 def temperature (self ):
0 commit comments