Skip to content

Commit 1fea7bc

Browse files
Add power metric to output summary
1 parent a10cbc0 commit 1fea7bc

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

tools/submission/submission_checker/checks/power_check.py

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
from ..utils import *
77
import os
88
import sys
9+
import datetime
910

1011
class 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

tools/submission/submission_checker/results.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def add_result(self, submission_logs: SubmissionLogs):
8282
row["weight_data_types"] = submission_logs.measurements_json["weight_data_types"]
8383
self.rows.append(row.copy())
8484
if row["has_power"]:
85-
row["Result"] = submission_logs.loader_data["division"] #TODO
85+
row["Result"] = submission_logs.loader_data["power_metric"]
8686
power_unit = POWER_UNIT_DICT[row["Scenario"]]
8787
row["Units"] = power_unit
8888
self.rows.append(row.copy())

0 commit comments

Comments
 (0)