1313class tegra :
1414 """Class that gathers the Tegra functionality for one device."""
1515
16- def __init__ (self , powerPath , tempPath ):
17- self .has_changed_clocks = False
16+ def __init__ (self , power_path , temp_path ):
1817 """Create object to control GPU core clock on a Tegra device."""
18+ self .has_changed_clocks = False
19+
1920 # Get paths
2021 self .dev_path = self .get_dev_path ()
21- if tempPath == "" :
22+ if temp_path == "" :
2223 self .gpu_temp_path = self .get_temp_path ()
2324 else :
24- self .gpu_temp_path = tempPath
25- if powerPath == "" :
25+ self .gpu_temp_path = temp_path
26+ if power_path == "" :
2627 self .gpu_power_path = self .get_power_path ()
2728 else :
28- self .gpu_power_path = powerPath
29+ self .gpu_power_path = power_path
2930 self .gpu_channel = self .get_gpu_channel ()
30-
31+
3132 # Read default clock values
3233 self .default_min_gr_clock = self ._read_clock_file ("min_freq" )
3334 self .default_max_gr_clock = self ._read_clock_file ("max_freq" )
3435 self .supported_gr_clocks = self ._read_clock_file ("available_frequencies" )
3536
3637 self .default_railgate_status = self ._read_railgate_file ()
37-
38+
3839 @staticmethod
3940 def get_dev_path ():
4041 """Get the path to device core clock control in /sys"""
@@ -55,20 +56,20 @@ def get_temp_path(self):
5556 with open (zone / Path ("type" )) as fp :
5657 name = fp .read ().strip ()
5758 if name == "GPU-therm" :
58- gpu_temp_path = str (zone ) + "/"
59+ gpu_temp_path = str (zone )
5960 break
60- else :
61+
62+ if gpu_temp_path is None :
6163 raise FileNotFoundError ("No GPU sensor for temperature found" )
62-
64+
6365 return gpu_temp_path
6466
6567 def get_power_path (self , start_path = "/sys/bus/i2c/drivers/ina3221" ):
66- """Recursively search for a file which holds power readings
67- starting from start_path."""
68+ """Search for a file which holds power readings"""
6869 for entry in os .listdir (start_path ):
6970 path = os .path .join (start_path , entry )
7071 if os .path .isfile (path ) and entry == "curr1_input" :
71- return start_path + "/"
72+ return start_path
7273 elif entry in start_path :
7374 continue
7475 elif os .path .isdir (path ):
@@ -79,10 +80,9 @@ def get_power_path(self, start_path="/sys/bus/i2c/drivers/ina3221"):
7980
8081 def get_gpu_channel (self ):
8182 """Get the channel number of the sensor which measures the GPU power"""
82-
83- # Iterate over all channels in the of_node dir of the power path to
84- # find the channel which holds GPU power information
85- for channel_dir in Path (self .gpu_power_path + "of_node/" ).iterdir ():
83+ # Iterate over all channels in the of_node dir of the power path to
84+ # find the channel which holds GPU power information
85+ for channel_dir in Path (self .gpu_power_path + "/of_node/" ).iterdir ():
8686 if ("channel@" in channel_dir .name ):
8787 with open (channel_dir / Path ("label" )) as fp :
8888 channel_label = fp .read ().strip ()
@@ -173,18 +173,18 @@ def __del__(self):
173173
174174 def read_gpu_temp (self ):
175175 """Read GPU temperature"""
176- with open (self .gpu_temp_path + "temp" ) as fp :
176+ with open (self .gpu_temp_path + "/ temp" ) as fp :
177177 temp = int (fp .read ())
178178 return temp / 1000
179-
179+
180180 def read_gpu_power (self ):
181181 """Read the current and voltage to calculate and return the power int watt"""
182-
183- result_cur = subprocess .run (["sudo" , "cat" , f"{ self .gpu_power_path } curr{ self .gpu_channel } _input" ], capture_output = True , text = True )
182+
183+ result_cur = subprocess .run (["sudo" , "cat" , f"{ self .gpu_power_path } / curr{ self .gpu_channel } _input" ], capture_output = True , text = True )
184184 current = int (result_cur .stdout .strip ()) / 1000
185- result_vol = subprocess .run (["sudo" , "cat" , f"{ self .gpu_power_path } in{ self .gpu_channel } _input" ], capture_output = True , text = True )
185+ result_vol = subprocess .run (["sudo" , "cat" , f"{ self .gpu_power_path } / in{ self .gpu_channel } _input" ], capture_output = True , text = True )
186186 voltage = int (result_vol .stdout .strip ()) / 1000
187-
187+
188188 return current * voltage
189189
190190class TegraObserver (BenchmarkObserver ):
@@ -203,20 +203,20 @@ def __init__(
203203 self ,
204204 observables ,
205205 save_all = False ,
206- powerPath = "" ,
207- tempPath = ""
206+ power_path = "" ,
207+ temp_path = ""
208208 ):
209209 """Create a TegraObserver"""
210- self .tegra = tegra (powerPath = powerPath , tempPath = tempPath )
210+ self .tegra = tegra (power_path = power_path , temp_path = temp_path )
211211 self .save_all = save_all
212212 self ._set_units = False
213-
213+
214214 supported = ["core_freq" , "gpu_temp" , "gpu_power" , "gpu_energy" ]
215215 for obs in observables :
216216 if obs not in supported :
217217 raise ValueError (f"Observable { obs } not in supported: { supported } " )
218218 self .observables = observables
219-
219+
220220 # Observe power measurements with the continuous observer
221221 self .measure_power = False
222222 self .needs_power = ["gpu_power" , "gpu_energy" ]
@@ -228,7 +228,7 @@ def __init__(
228228 )
229229 # remove power observables
230230 self .observables = [obs for obs in observables if obs not in self .needs_power ]
231-
231+
232232 self .results = {}
233233 for obs in self .observables :
234234 self .results [obs + "s" ] = []
@@ -309,13 +309,13 @@ class tegraPowerObserver(ContinuousObserver):
309309 """Observer that measures power using tegra and continuous benchmarking."""
310310 def __init__ (self , observables , parent , continous_duration = 1 ):
311311 self .parent = parent
312-
312+
313313 supported = ["gpu_power" , "gpu_energy" ]
314314 for obs in observables :
315315 if obs not in supported :
316316 raise ValueError (f"Observable { obs } not in supported: { supported } " )
317317 self .observables = observables
318-
318+
319319 # duration in seconds
320320 self .continuous_duration = continous_duration
321321
@@ -326,17 +326,17 @@ def __init__(self, observables, parent, continous_duration=1):
326326
327327 # results from the last iteration-based benchmark
328328 self .results = None
329-
329+
330330 def before_start (self ):
331331 self .parent .before_start ()
332332 self .power = 0
333333 self .energy = 0
334334 self .power_readings = []
335-
335+
336336 def after_start (self ):
337337 self .parent .after_start ()
338338 self .t0 = time .perf_counter ()
339-
339+
340340 def during (self ):
341341 self .parent .during ()
342342 power_usage = self .parent .tegra .read_gpu_power ()
@@ -347,7 +347,7 @@ def during(self):
347347 or timestamp - self .power_readings [- 1 ][0 ] > 0.01
348348 ):
349349 self .power_readings .append ([timestamp , power_usage ])
350-
350+
351351 def after_finish (self ):
352352 self .parent .after_finish ()
353353 # safeguard in case we have no measurements, perhaps the kernel was too short to measure anything
@@ -358,7 +358,7 @@ def after_finish(self):
358358 execution_time = self .results ["time" ] / 1e3
359359 self .power = np .median ([d [1 ] for d in self .power_readings ])
360360 self .energy = self .power * execution_time
361-
361+
362362 def get_results (self ):
363363 results = self .parent .get_results ()
364364 keys = list (results .keys ())
@@ -368,5 +368,5 @@ def get_results(self):
368368 results ["gpu_power" ] = self .power
369369 if "gpu_energy" in self .observables :
370370 results ["gpu_energy" ] = self .energy
371-
371+
372372 return results
0 commit comments