@@ -186,7 +186,8 @@ def read_gpu_power(self):
186186 voltage = int (result_vol .stdout .strip ()) / 1000
187187
188188 return current * voltage
189-
189+
190+
190191class TegraObserver (BenchmarkObserver ):
191192 """Observer that uses /sys/ to monitor and control graphics clock frequencies on a Tegra device.
192193
@@ -211,21 +212,20 @@ def __init__(
211212 self .save_all = save_all
212213 self ._set_units = False
213214
214- supported = ["core_freq" , "gpu_temp " , "gpu_power " , "gpu_energy " ]
215+ supported = ["core_freq" , "tegra_temp " , "tegra_power " , "tegra_energy " ]
215216 for obs in observables :
216217 if obs not in supported :
217218 raise ValueError (f"Observable { obs } not in supported: { supported } " )
218219 self .observables = observables
219220
220221 # Observe power measurements with the continuous observer
221222 self .measure_power = False
222- self .needs_power = ["gpu_power " , "gpu_energy " ]
223+ self .needs_power = ["tegra_power " , "tegra_energy " ]
223224 if any ([obs in self .needs_power for obs in observables ]):
224225 self .measure_power = True
225226 power_observables = [obs for obs in observables if obs in self .needs_power ]
226- self .continuous_observer = tegraPowerObserver (
227- power_observables , self , continous_duration = 3
228- )
227+ self .continuous_observer = ContinuousObserver ("tegra" , power_observables , self , continous_duration = 3 )
228+
229229 # remove power observables
230230 self .observables = [obs for obs in observables if obs not in self .needs_power ]
231231
@@ -236,11 +236,15 @@ def __init__(
236236 self .during_obs = [
237237 obs
238238 for obs in observables
239- if obs in ["core_freq" , "gpu_temp " ]
239+ if obs in ["core_freq" , "tegra_temp " ]
240240 ]
241241
242242 self .iteration = {obs : [] for obs in self .during_obs }
243-
243+
244+
245+ def read_power (self ):
246+ return self .tegra .read_gpu_power ()
247+
244248
245249 def before_start (self ):
246250 # clear results of the observables for next measurement
@@ -266,7 +270,7 @@ def after_finish(self):
266270 self .results ["core_freqs" ].append (np .average (self .iteration ["core_freq" ]))
267271 if "gpu_temp" in self .observables :
268272 self .results ["gpu_temps" ].append (np .average (self .iteration ["gpu_temp" ]))
269-
273+
270274 def get_results (self ):
271275 averaged_results = {}
272276
@@ -303,70 +307,3 @@ def get_tegra_gr_clocks(n=None, quiet=False):
303307 if not quiet :
304308 print ("Using gr frequencies:" , tune_params ["tegra_gr_clock" ])
305309 return tune_params
306-
307-
308- class tegraPowerObserver (ContinuousObserver ):
309- """Observer that measures power using tegra and continuous benchmarking."""
310- def __init__ (self , observables , parent , continous_duration = 1 ):
311- self .parent = parent
312-
313- supported = ["gpu_power" , "gpu_energy" ]
314- for obs in observables :
315- if obs not in supported :
316- raise ValueError (f"Observable { obs } not in supported: { supported } " )
317- self .observables = observables
318-
319- # duration in seconds
320- self .continuous_duration = continous_duration
321-
322- self .power = 0
323- self .energy = 0
324- self .power_readings = []
325- self .t0 = 0
326-
327- # results from the last iteration-based benchmark
328- self .results = None
329-
330- def before_start (self ):
331- self .parent .before_start ()
332- self .power = 0
333- self .energy = 0
334- self .power_readings = []
335-
336- def after_start (self ):
337- self .parent .after_start ()
338- self .t0 = time .perf_counter ()
339-
340- def during (self ):
341- self .parent .during ()
342- power_usage = self .parent .tegra .read_gpu_power ()
343- timestamp = time .perf_counter () - self .t0
344- # only store the result if we get a new measurement from tegra
345- if len (self .power_readings ) == 0 or (
346- self .power_readings [- 1 ][1 ] != power_usage
347- or timestamp - self .power_readings [- 1 ][0 ] > 0.01
348- ):
349- self .power_readings .append ([timestamp , power_usage ])
350-
351- def after_finish (self ):
352- self .parent .after_finish ()
353- # safeguard in case we have no measurements, perhaps the kernel was too short to measure anything
354- if not self .power_readings :
355- return
356-
357- # convert to seconds from milliseconds
358- execution_time = self .results ["time" ] / 1e3
359- self .power = np .median ([d [1 ] for d in self .power_readings ])
360- self .energy = self .power * execution_time
361-
362- def get_results (self ):
363- results = self .parent .get_results ()
364- keys = list (results .keys ())
365- for key in keys :
366- results ["pwr_" + key ] = results .pop (key )
367- if "gpu_power" in self .observables :
368- results ["gpu_power" ] = self .power
369- if "gpu_energy" in self .observables :
370- results ["gpu_energy" ] = self .energy
371-
372- return results
0 commit comments