Skip to content

Commit 4ec1f15

Browse files
Fixes for preprocessing submission
1 parent 99cbec8 commit 4ec1f15

File tree

4 files changed

+53
-36
lines changed

4 files changed

+53
-36
lines changed

tools/submission/preprocess_submission.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def get_args():
5151
parser.add_argument("--nodelete-failed",
5252
help="do not delete failed results (submission checker will fail)",
5353
default=False, action="store_true")
54+
parser.add_argument("--keep-structure",
55+
help="keep folder structure (newer versions of submission checker might fail)",
56+
default=False, action="store_true")
5457

5558
parser.add_argument(
5659
"--version",
@@ -96,7 +99,7 @@ def delete_empty_dirs(src):
9699
return False
97100

98101

99-
def copy_submission_dir(src, dst, filter_submitter):
102+
def copy_submission_dir(src, dst, filter_submitter, keep_structure = True):
100103
"""
101104
Copies the submission tree to output directory for processing
102105
"""
@@ -106,10 +109,26 @@ def copy_submission_dir(src, dst, filter_submitter):
106109
for submitter in next(os.walk(os.path.join(src, division)))[1]:
107110
if filter_submitter and submitter != filter_submitter:
108111
continue
109-
shutil.copytree(
110-
os.path.join(src, division, submitter),
111-
os.path.join(dst, division, submitter),
112-
)
112+
if keep_structure:
113+
shutil.copytree(
114+
os.path.join(src, division, submitter),
115+
os.path.join(dst, division, submitter),
116+
)
117+
else:
118+
for object in os.listdir(os.path.join(src, division, submitter)):
119+
if os.path.isfile(os.path.join(src, division, submitter, object)):
120+
shutil.copyfile(
121+
os.path.join(src, division, submitter, object),
122+
os.path.join(dst, division, submitter, object),
123+
dirs_exist_ok = True
124+
)
125+
elif os.path.isdir(os.path.join(src, division, submitter, object)):
126+
target_dir = "results" if object in ["compliance", "measurements"] else object
127+
shutil.copytree(
128+
os.path.join(src, division, submitter, object),
129+
os.path.join(dst, division, submitter, target_dir),
130+
dirs_exist_ok = True
131+
)
113132

114133

115134
def change_first_directory_to_open(path):
@@ -247,8 +266,7 @@ def clean_invalid_results(args, log_path, config, system_desc, system_json,
247266

248267
compliance_is_valid = True
249268
if is_closed_or_network:
250-
compliance_dir = change_folder_name_in_path(
251-
scenario_path, "results", "compliance")
269+
compliance_dir = scenario_path
252270
if not checker.check_compliance_dir(
253271
compliance_dir,
254272
mlperf_model,
@@ -262,12 +280,10 @@ def clean_invalid_results(args, log_path, config, system_desc, system_json,
262280

263281
is_valid = accuracy_is_valid and perf_is_valid and compliance_is_valid
264282
if not is_valid: # Remove the scenario result
265-
scenario_measurements_path = change_folder_name_in_path(
266-
scenario_path, "results", "measurements")
283+
scenario_measurements_path = scenario_path
267284
if scenario in [
268285
"Offline", "MultiStream"] and (not accuracy_is_valid or not perf_is_valid) or division == "open": # they can be inferred
269-
scenario_compliance_path = change_folder_name_in_path(
270-
scenario_path, "results", "compliance")
286+
scenario_compliance_path = scenario_path
271287
log.warning(
272288
f"{scenario} scenario result is invalid for {system_desc}: {model} in {division} division. Accuracy: {accuracy_is_valid}, Performance: {perf_is_valid}. Removing...")
273289
if os.path.exists(scenario_path):
@@ -278,10 +294,8 @@ def clean_invalid_results(args, log_path, config, system_desc, system_json,
278294
shutil.rmtree(scenario_compliance_path)
279295
elif division in ["closed", "network"]:
280296
model_results_path = os.path.dirname(scenario_path)
281-
model_measurements_path = change_folder_name_in_path(
282-
model_results_path, "results", "measurements")
283-
model_compliance_path = change_folder_name_in_path(
284-
model_results_path, "results", "compliance")
297+
model_measurements_path = model_results_path
298+
model_compliance_path = model_results_path
285299
model_code_path = os.path.join(
286300
change_folder_name_in_path(
287301
log_path, "results", "code"), model)
@@ -301,8 +315,7 @@ def clean_invalid_results(args, log_path, config, system_desc, system_json,
301315
f"{scenario} scenario result is invalid for {system_desc}: {model} in {division} and open divisions. Accuracy: {accuracy_is_valid}, Performance: {perf_is_valid}. Removing it...")
302316
if os.path.exists(scenario_path):
303317
shutil.rmtree(scenario_path)
304-
scenario_measurements_path = change_folder_name_in_path(
305-
scenario_path, "results", "measurements")
318+
scenario_measurements_path = scenario_path
306319
if os.path.exists(scenario_measurements_path):
307320
shutil.rmtree(scenario_measurements_path)
308321
if not os.path.exists(target_results_path):
@@ -367,9 +380,7 @@ def infer_scenario_results(args, config):
367380
continue
368381

369382
# process results
370-
for directory in ["results", "measurements"] + \
371-
(["compliance"] if division == "closed" else []):
372-
383+
for directory in ["results"]:
373384
log_path = os.path.join(division, submitter, directory)
374385
if not os.path.exists(log_path):
375386
log.error("no submission in %s", log_path)
@@ -550,7 +561,7 @@ def main():
550561
log.error(f"output directory {args.output} already exists")
551562
sys.exit(1)
552563
os.makedirs(args.output)
553-
copy_submission_dir(args.input, args.output, args.submitter)
564+
copy_submission_dir(args.input, args.output, args.submitter, args.keep_structure)
554565
src_dir = args.output
555566

556567
config = checker.Config(
@@ -574,3 +585,6 @@ def main():
574585

575586
if __name__ == "__main__":
576587
sys.exit(main())
588+
589+
if __name__ == "__main__":
590+
sys.exit(main())

tools/submission/submission_checker.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,9 @@ def set_type(self, submission_type):
10611061
self.optional = self.base["optional-scenarios-datacenter-edge"]
10621062
else:
10631063
raise ValueError("invalid system type")
1064+
1065+
def skip_calibration(self):
1066+
return self.skip_calibration_check or self.version in ["v5.0"]
10641067

10651068
def get_mlperf_model(self, model, extra_model_mapping=None):
10661069
# preferred - user is already using the official name
@@ -2392,7 +2395,7 @@ def log_result(
23922395
results[os.path.join(results_path)] = None
23932396

23942397
# Check for calibration documentation
2395-
if not config.skip_calibration_check and division not in ["open"]:
2398+
if not config.skip_calibration() and division not in ["open"]:
23962399
calibration_path_root = os.path.join(
23972400
division, submitter, "calibration.md")
23982401
calibration_path_doc = os.path.join(
@@ -3026,9 +3029,16 @@ def check_measurement_dir(
30263029
log.error("%s is having empty %s", measurement_dir, i)
30273030
is_valid = False
30283031

3029-
logging.info("%s", files)
3030-
if "measurements.json" in files:
3031-
system_file = "measurements.json"
3032+
for i in files:
3033+
if i.startswith(system_desc) and i.endswith(
3034+
"_" + scenario + ".json"):
3035+
system_file = i
3036+
end = len("_" + scenario + ".json")
3037+
break
3038+
elif i.startswith(system_desc) and i.endswith(".json"):
3039+
system_file = i
3040+
end = len(".json")
3041+
break
30323042

30333043

30343044
weight_data_types = None

tools/submission/submission_structure.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ The following diagram describes the submission structure
4242
│ │ │ │ │ │ │ │ │ ├── mlperf_log_detail.txt
4343
│ │ │ │ │ │ │ │ │ └── mlperf_log_summary.txt
4444
│ │ │ │ │ │ ├── measurements.json
45-
│ │ │ │ │ │ ├── mlperf.conf
46-
│ │ │ │ │ │ ├── user.conf
47-
│ │ │ │ │ │ └── accuracy
45+
│ │ │ │ │ │ ├── mlperf.conf (optional)
46+
│ │ │ │ │ │ └── user.conf
4847
│ │ │ ├── ...
4948
│ │ │ └── <system_desc_id_n>
5049
│ │ ├── systems

tools/submission/truncate_accuracy_log.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,7 @@ def truncate_results_dir(filter_submitter, backup, scenarios_to_skip):
142142
continue
143143

144144
# process results
145-
required_dirs = [
146-
"results", "compliance"] if division in [
147-
"closed", "network"] else ["results"]
145+
required_dirs = ["results"]
148146
for directory in required_dirs:
149147

150148
log_path = os.path.join(division, submitter, directory)
@@ -164,10 +162,6 @@ def truncate_results_dir(filter_submitter, backup, scenarios_to_skip):
164162
name = os.path.join(
165163
log_path, system_desc, model, scenario
166164
)
167-
if directory == "compliance":
168-
name = os.path.join(
169-
log_path, system_desc, model, scenario, test
170-
)
171165

172166
hash_val = None
173167
acc_path = os.path.join(name, "accuracy")
@@ -178,7 +172,7 @@ def truncate_results_dir(filter_submitter, backup, scenarios_to_skip):
178172
acc_path, "accuracy.txt")
179173

180174
# only TEST01 has an accuracy log
181-
if directory == "compliance" and test != "TEST01":
175+
if str(test).startswith("TEST") and test != "TEST01":
182176
continue
183177
if not os.path.exists(acc_log):
184178
log.error("%s missing", acc_log)

0 commit comments

Comments
 (0)