Skip to content

Commit b23e33a

Browse files
Add docstring to new submission checker
1 parent cd4d47d commit b23e33a

File tree

10 files changed

+671
-5
lines changed

10 files changed

+671
-5
lines changed

tools/submission/submission_checker/checks/accuracy_check.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,49 @@
77

88

99
class AccuracyCheck(BaseCheck):
10+
"""Checks accuracy-related submission artifacts and reports issues.
11+
12+
The `AccuracyCheck` class performs a set of validations on submission
13+
accuracy outputs. It inspects the parsed MLPerf log and accompanying
14+
accuracy artifacts provided via `SubmissionLogs` and the test
15+
`Config` to ensure that reported accuracy metrics meet configured
16+
targets and limits, that the accuracy JSON exists and is properly
17+
truncated, that Loadgen did not report blocking errors, and that the
18+
accuracy run covered the expected dataset size.
19+
20+
Main check methods:
21+
- `accuracy_result_check`: Parses `accuracy.txt` lines to validate
22+
reported metrics against targets, upper limits, and hash presence.
23+
- `accuracy_json_check`: Ensures the accuracy JSON file exists and is
24+
within allowed size limits.
25+
- `loadgen_errors_check`: Fails if Loadgen reported non-ignored errors.
26+
- `dataset_check`: Verifies the reported sample count matches the
27+
configured dataset size unless the check is skipped.
28+
29+
Attributes:
30+
submission_logs (SubmissionLogs): Holder for submission log paths
31+
and parsed contents (accuracy logs, results, json, loader data).
32+
mlperf_log: Parsed MLPerf log object used to inspect errors and
33+
run metadata.
34+
accuracy_result (list[str]): Lines from `accuracy.txt` used to
35+
extract reported accuracy values.
36+
accuracy_json (str): Path to the accuracy JSON file.
37+
config (Config): Configuration helper providing target values and
38+
dataset sizes.
39+
"""
40+
1041
def __init__(
1142
self, log, path, config: Config, submission_logs: SubmissionLogs
1243
):
44+
"""Initialize the accuracy check helper.
45+
46+
Args:
47+
log: Logger instance used to report messages.
48+
path: Path to the submission being checked.
49+
config (Config): Configuration provider for targets and limits.
50+
submission_logs (SubmissionLogs): Parsed submission logs and
51+
artifact paths (accuracy logs, results, json, loader data).
52+
"""
1353
super().__init__(log, path)
1454
self.name = "accuracy checks"
1555
self.submission_logs = submission_logs
@@ -29,12 +69,29 @@ def __init__(
2969
self.setup_checks()
3070

3171
def setup_checks(self):
72+
"""Register individual accuracy-related checks.
73+
74+
Adds the per-submission validation callables to `self.checks` in
75+
the order they should be executed.
76+
"""
3277
self.checks.append(self.accuracy_result_check)
3378
self.checks.append(self.accuracy_json_check)
3479
self.checks.append(self.loadgen_errors_check)
3580
self.checks.append(self.dataset_check)
3681

3782
def accuracy_result_check(self):
83+
"""Validate reported accuracy metrics in `accuracy.txt`.
84+
85+
Parses lines from `self.accuracy_result` using configured patterns
86+
and compares found values against targets and optional upper
87+
limits. Also ensures a hash value is present and records the
88+
observed accuracy metrics in `submission_logs.loader_data`.
89+
90+
Returns:
91+
bool: True if accuracy checks passed (or division is 'open'),
92+
False otherwise.
93+
"""
94+
3895
patterns, acc_targets, acc_types, acc_limits, up_patterns, acc_upper_limit = self.config.get_accuracy_values(
3996
self.model
4097
)
@@ -105,6 +162,12 @@ def accuracy_result_check(self):
105162
return is_valid
106163

107164
def accuracy_json_check(self):
165+
"""Check that the accuracy JSON exists and is within size limits.
166+
167+
Returns:
168+
bool: True if the JSON file exists and its size does not
169+
exceed `MAX_ACCURACY_LOG_SIZE`, False otherwise.
170+
"""
108171
if not os.path.exists(self.accuracy_json):
109172
self.log.error("%s is missing", self.accuracy_json)
110173
return False
@@ -115,6 +178,15 @@ def accuracy_json_check(self):
115178
return True
116179

117180
def loadgen_errors_check(self):
181+
"""Detect Loadgen errors reported in the MLPerf log.
182+
183+
If errors are present and not ignored by configuration, logs the
184+
error messages and returns False to indicate failure.
185+
186+
Returns:
187+
bool: True if no blocking Loadgen errors are present,
188+
False otherwise.
189+
"""
118190
if self.mlperf_log.has_error():
119191
if self.config.ignore_uncommited:
120192
has_other_errors = False
@@ -133,6 +205,17 @@ def loadgen_errors_check(self):
133205
return True
134206

135207
def dataset_check(self):
208+
"""Verify the accuracy run covered the expected dataset size.
209+
210+
If `skip_dataset_size_check` is enabled in the configuration,
211+
this check is skipped and returns True. Otherwise compares the
212+
`qsl_reported_total_count` from the MLPerf log to the expected
213+
dataset size for the model.
214+
215+
Returns:
216+
bool: True if the dataset sizes match or the check is skipped,
217+
False if the reported count differs from expected.
218+
"""
136219
if self.config.skip_dataset_size_check:
137220
self.log.info(
138221
"%s Skipping dataset size check", self.path

tools/submission/submission_checker/checks/base.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class BaseCheck(ABC):
55
"""
66
A generic check class meant to be inherited by concrete check implementations.
7-
Subclasses must implement the `run()` method.
7+
Subclasses must register their check methods into `self.checks`.
88
"""
99

1010
def __init__(self, log, path):
@@ -16,9 +16,7 @@ def __init__(self, log, path):
1616

1717
def run_checks(self):
1818
"""
19-
Execute the check.
20-
Must be implemented by subclasses.
21-
Should return a CheckResult instance.
19+
Execute all registered checks. Returns True if all checks pass, False otherwise.
2220
"""
2321
valid = True
2422
errors = []
@@ -36,6 +34,7 @@ def run_checks(self):
3634
return valid
3735

3836
def execute(self, check):
37+
"""Custom execution of a single check method."""
3938
return check()
4039

4140
def __call__(self):

tools/submission/submission_checker/checks/compliance_check.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,32 @@
1111

1212

1313
class ComplianceCheck(BaseCheck):
14+
"""Validate compliance test artifacts for a submission.
15+
16+
The `ComplianceCheck` class runs a set of validations against the
17+
compliance directory produced with a submission. It verifies the
18+
presence of required test subdirectories and files, runs delegated
19+
performance and accuracy checks for compliance tests, and inspects
20+
compliance-specific performance outputs.
21+
22+
The class delegates some checks to `PerformanceCheck` and
23+
`AccuracyCheck` helpers when relevant. Results and file lists are
24+
logged via the provided logger.
25+
"""
26+
1427
def __init__(self, log, path, config: Config,
1528
submission_logs: SubmissionLogs):
29+
"""Initialize the compliance checker.
30+
31+
Args:
32+
log: Logger used to emit informational, warning, and error
33+
messages about the compliance checks.
34+
path: Filesystem path to the submission root being checked.
35+
config (Config): Configuration provider for models and
36+
compliance expectations.
37+
submission_logs (SubmissionLogs): Parsed submission log
38+
artifacts and loader metadata.
39+
"""
1640
super().__init__(log, path)
1741
self.submission_logs = submission_logs
1842
self.config = config
@@ -28,12 +52,30 @@ def __init__(self, log, path, config: Config,
2852
self.setup_checks()
2953

3054
def setup_checks(self):
55+
"""Register the sequence of compliance checks to run.
56+
57+
Appends the per-submission validation callables to `self.checks` in
58+
the order they should be executed by the checking framework.
59+
"""
3160
self.checks.append(self.dir_exists_check)
3261
self.checks.append(self.performance_check)
3362
self.checks.append(self.accuracy_check)
3463
self.checks.append(self.compliance_performance_check)
3564

3665
def get_test_list(self, model):
66+
"""Return the list of compliance tests applicable to `model`.
67+
68+
The mapping of models to tests is read from the configuration
69+
(`self.config.base`) using the pre-defined keys
70+
`models_TEST01`, `models_TEST04`, and `models_TEST06`.
71+
72+
Args:
73+
model (str): MLPerf benchmark/model identifier.
74+
75+
Returns:
76+
list[str]: Ordered list of compliance test names to execute.
77+
"""
78+
3779
test_list = []
3880
if model in self.config.base["models_TEST01"]:
3981
test_list.append("TEST01")
@@ -44,6 +86,18 @@ def get_test_list(self, model):
4486
return test_list
4587

4688
def dir_exists_check(self):
89+
"""Verify required compliance directories and files exist.
90+
91+
Skips checks for the 'open' division. For each test in
92+
`self.test_list`, ensures the expected test directory exists and
93+
that required verification files are present depending on the
94+
test type (accuracy/performance files for specific tests).
95+
96+
Returns:
97+
bool: True if all required files and directories are present,
98+
False otherwise.
99+
"""
100+
47101
if self.division.lower() == "open":
48102
self.log.info(
49103
"Compliance tests not needed for open division. Skipping tests on %s",
@@ -86,6 +140,17 @@ def dir_exists_check(self):
86140
return is_valid
87141

88142
def performance_check(self):
143+
"""Run performance compliance checks for applicable tests.
144+
145+
For each test that requires a performance check (TEST01 and
146+
TEST04), construct a `SubmissionLogs` object pointing at the
147+
test's performance log and delegate to `PerformanceCheck`.
148+
149+
Returns:
150+
bool: True if all delegated performance checks pass, False
151+
if any fail.
152+
"""
153+
89154
if self.division.lower() == "open":
90155
self.log.info(
91156
"Compliance tests not needed for open division. Skipping tests on %s",
@@ -108,6 +173,20 @@ def performance_check(self):
108173
return is_valid
109174

110175
def accuracy_check(self):
176+
"""Run accuracy compliance checks for applicable tests.
177+
178+
For TEST01, verifies deterministic-mode pass lines and checks the
179+
`accuracy` directory contents and baseline/compliance accuracy
180+
values against model-specific delta thresholds.
181+
182+
For TEST06, inspects the pre-parsed result lines for first-token,
183+
EOS, and sample-length checks.
184+
185+
Returns:
186+
bool: True if all required accuracy checks pass, False
187+
otherwise.
188+
"""
189+
111190
if self.division.lower() == "open":
112191
self.log.info(
113192
"Compliance tests not needed for open division. Skipping tests on %s",
@@ -228,6 +307,17 @@ def accuracy_check(self):
228307
return is_valid
229308

230309
def compliance_performance_check(self):
310+
"""Inspect compliance performance verification outputs.
311+
312+
For TEST01 and TEST04, checks the `verify_performance.txt` file for
313+
a passing indicator and ensures the `performance/run_1` directory
314+
contains the expected files (with optional exclusions).
315+
316+
Returns:
317+
bool: True if all compliance performance checks pass, False
318+
if any check fails.
319+
"""
320+
231321
if self.division.lower() == "open":
232322
self.log.info(
233323
"Compliance tests not needed for open division. Skipping tests on %s",

0 commit comments

Comments
 (0)