66from ..utils import *
77import os
88import sys
9+ import datetime
910
1011class PowerCheck (BaseCheck ):
1112 def __init__ (self , log , path , config : Config , submission_logs : SubmissionLogs ):
1213 super ().__init__ (log , path )
1314 self .config = config
1415 self .submission_logs = submission_logs
16+ self .mlperf_log = self .submission_logs .performance_log
17+ self .scenario_fixed = self .submission_logs .loader_data .get ("scenario" , "" )
1518 self .power_path = self .submission_logs .loader_data .get ("power_dir_path" , "" )
1619 self .testing_path = os .path .dirname (self .submission_logs .loader_data .get ("perf_path" , "" ))
1720 self .ranging_path = os .path .join (os .path .dirname (self .testing_path ), "ranging" )
@@ -21,6 +24,7 @@ def __init__(self, log, path, config: Config, submission_logs: SubmissionLogs):
2124 def setup_checks (self ):
2225 self .checks .append (self .required_files_check )
2326 self .checks .append (self .external_power_check )
27+ self .checks .append (self .get_power_metric_check )
2428
2529
2630 def required_files_check (self ):
@@ -67,5 +71,85 @@ def external_power_check(self):
6771 "Power WG power_checker.py did not pass for: %s" ,
6872 perf_path )
6973 return False
74+ return True
75+
76+ def get_power_metric_check (self ):
77+ if not self .has_power :
78+ return True
79+ # parse the power logs
80+ is_valid = True
81+ server_timezone = datetime .timedelta (0 )
82+ client_timezone = datetime .timedelta (0 )
83+
84+ datetime_format = "%m-%d-%Y %H:%M:%S.%f"
85+ power_begin = (
86+ datetime .datetime .strptime (self .mlperf_log ["power_begin" ], datetime_format )
87+ + client_timezone
88+ )
89+ power_end = (
90+ datetime .datetime .strptime (self .mlperf_log ["power_end" ], datetime_format )
91+ + client_timezone
92+ )
93+ # Obtain the scenario also from logs to check if power is inferred
94+ scenario = self .mlperf_log ["effective_scenario" ]
95+
96+ log_path = self .testing_path
97+ spl_fname = os .path .join (log_path , "spl.txt" )
98+ power_list = []
99+ with open (spl_fname ) as f :
100+ for line in f :
101+ if not line .startswith ("Time" ):
102+ continue
103+ timestamp = (
104+ datetime .datetime .strptime (line .split ("," )[1 ], datetime_format )
105+ + server_timezone
106+ )
107+ if timestamp > power_begin and timestamp < power_end :
108+ value = float (line .split ("," )[3 ])
109+ if value > 0 :
110+ power_list .append (float (line .split ("," )[3 ]))
111+
112+ if len (power_list ) == 0 :
113+ self .log .error (
114+ "%s has no power samples falling in power range: %s - %s" ,
115+ spl_fname ,
116+ power_begin ,
117+ power_end ,
118+ )
119+ is_valid = False
120+ else :
121+ avg_power = sum (power_list ) / len (power_list )
122+ power_duration = (power_end - power_begin ).total_seconds ()
123+ if self .scenario_fixed .lower () in ["offline" , "server" , "interactive" ]:
124+ # In Offline and Server scenarios, the power metric is in W.
125+ power_metric = avg_power
126+ avg_power_efficiency = self .submission_logs .loader_data ["performance_metric" ] / avg_power
127+
128+ else :
129+ # In SingleStream and MultiStream scenarios, the power metric is in
130+ # mJ/query.
131+ assert self .scenario_fixed .lower () in [
132+ "multistream" ,
133+ "singlestream" ,
134+ ], "Unknown scenario: {:}" .format (self .scenario_fixed )
135+
136+ num_queries = int (self .mlperf_log ["result_query_count" ])
137+
138+ power_metric = avg_power * power_duration * 1000 / num_queries
139+
140+ if self .scenario_fixed .lower () in ["singlestream" ]:
141+ samples_per_query = 1
142+ elif self .scenario_fixed .lower () in ["multistream" ]:
143+ samples_per_query = 8
144+
145+ if (self .scenario_fixed .lower () in ["multistream" ]
146+ ) and scenario .lower () in ["singlestream" ]:
147+ power_metric = (
148+ avg_power * power_duration * samples_per_query * 1000 / num_queries
149+ )
150+
151+ avg_power_efficiency = (samples_per_query * 1000 ) / power_metric
70152
71- return True
153+ self .submission_logs .loader_data ["power_metric" ] = power_metric
154+ self .submission_logs .loader_data ["avg_power_efficiency" ] = avg_power_efficiency
155+ return is_valid
0 commit comments