Skip to content

Commit adb59ce

Browse files
committed
[Benchmarks] Add benchmarks logger
1 parent 156429e commit adb59ce

File tree

16 files changed

+310
-142
lines changed

16 files changed

+310
-142
lines changed

devops/scripts/benchmarks/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ are stored [here](https://oneapi-src.github.io/unified-runtime/performance/).
4545
## Output formats
4646
You can display the results in the form of a HTML file by using `--ouptut-html` and a markdown file by using `--output-markdown`. Due to character limits for posting PR comments, the final content of the markdown file might be reduced. In order to obtain the full markdown output, use `--output-markdown full`.
4747

48+
## Logging
49+
50+
The benchmark runner uses a configurable logging system with different log levels that can be set using the `--log-level` command-line option.
51+
52+
Available log levels:
53+
- `debug`
54+
- `info` (default)
55+
- `warning`
56+
- `error`
57+
- `critical`
58+
59+
To set the log level, use the `--log-level` option:
60+
```bash
61+
./main.py ~/benchmarks_workdir/ --sycl ~/llvm/build/ --log-level debug
62+
```
63+
64+
You can also use the `--verbose` flag, which sets the log level to `debug` and overrides any `--log-level` setting:
65+
```bash
66+
./main.py ~/benchmarks_workdir/ --sycl ~/llvm/build/ --verbose
67+
```
68+
4869
## Requirements
4970

5071
### Python

devops/scripts/benchmarks/benches/benchdnn.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
# See LICENSE.TXT
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6+
67
from pathlib import Path
8+
79
from .base import Suite, Benchmark
810
from options import options
911
from utils.utils import git_clone, run, create_build_path
1012
from utils.result import Result
1113
from utils.oneapi import get_oneapi
14+
from utils.logger import log
1215
from .benchdnn_list import get_bench_dnn_list
1316

1417

@@ -150,8 +153,7 @@ def run(self, env_vars):
150153
)
151154
result_value = self._extract_time(output)
152155

153-
if options.verbose:
154-
print(f"[{self.name()}] Output: {output}")
156+
log.debug(f"[{self.name()}] Output: {output}")
155157

156158
return [
157159
Result(

devops/scripts/benchmarks/benches/gromacs.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

66
import os
7-
import subprocess
87
from pathlib import Path
8+
import re
9+
910
from .base import Suite, Benchmark
1011
from options import options
1112
from utils.utils import git_clone, download, run, create_build_path
1213
from utils.result import Result
1314
from utils.oneapi import get_oneapi
14-
import re
15+
from utils.logger import log
1516

1617

1718
class GromacsBench(Suite):
18-
1919
def git_url(self):
2020
return "https://gitlab.com/gromacs/gromacs.git"
2121

@@ -209,8 +209,7 @@ def run(self, env_vars):
209209

210210
time = self._extract_execution_time(mdrun_output)
211211

212-
if options.verbose:
213-
print(f"[{self.name()}] Time: {time:.3f} seconds")
212+
log.debug(f"[{self.name()}] Time: {time:.3f} seconds")
214213

215214
return [
216215
Result(
@@ -259,7 +258,7 @@ def _validate_correctness(self, log_file):
259258
drift_value = float(match.group(1))
260259
return abs(drift_value) <= threshold
261260
except ValueError:
262-
print(
261+
log.warning(
263262
f"Parsed drift value: {drift_value} exceeds threshold"
264263
)
265264
return False

devops/scripts/benchmarks/benches/umf.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
# See LICENSE.TXT
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6-
import random
7-
from utils.utils import git_clone
8-
from .base import Benchmark, Suite
9-
from utils.result import Result
10-
from utils.utils import run, create_build_path
11-
from options import options
12-
from utils.oneapi import get_oneapi
136
import os
147
import csv
158
import io
169
import re
1710

11+
from .base import Benchmark, Suite
12+
from utils.result import Result
13+
from options import options
14+
from utils.oneapi import get_oneapi
15+
from utils.logger import log
16+
1817

1918
def isUMFAvailable():
2019
return options.umf is not None
@@ -93,7 +92,7 @@ def extra_env_vars(self) -> dict:
9392

9493
def setup(self):
9594
if not isUMFAvailable():
96-
print("UMF prefix path not provided")
95+
log.warning("UMF prefix path not provided")
9796
return
9897

9998
self.oneapi = get_oneapi()

devops/scripts/benchmarks/compare.py

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
from utils.aggregate import Aggregator, SimpleMedian
2-
from utils.validate import Validate
3-
from utils.result import Result, BenchmarkRun
4-
from options import options
1+
# Copyright (C) 2024-2025 Intel Corporation
2+
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
# See LICENSE.TXT
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6-
import os
76
import re
8-
import sys
97
import json
108
import argparse
119
from datetime import datetime, timezone
1210
from pathlib import Path
1311
from dataclasses import dataclass, asdict
1412

13+
from utils.aggregate import Aggregator, SimpleMedian
14+
from utils.validate import Validate
15+
from utils.result import BenchmarkRun
16+
from utils.logger import log
17+
from options import options
18+
1519

1620
@dataclass
1721
class BenchmarkHistoricAverage:
@@ -113,8 +117,8 @@ def validate_benchmark_result(result: BenchmarkRun) -> bool:
113117
if result.hostname != hostname:
114118
return False
115119
if result.name != result_name:
116-
print(
117-
f"Warning: Result file {result_path} does not match specified result name {result.name}."
120+
log.warning(
121+
f"Result file {result_path} does not match specified result name {result.name}."
118122
)
119123
return False
120124
if result.date < datetime.strptime(cutoff, "%Y%m%d_%H%M%S").replace(
@@ -256,24 +260,24 @@ def to_hist(
256260
"""
257261

258262
if avg_type != "median":
259-
print("Only median is currently supported: Refusing to continue.")
263+
log.error("Only median is currently supported: Refusing to continue.")
260264
exit(1)
261265

262266
try:
263267
with open(compare_file, "r") as compare_f:
264268
compare_result = BenchmarkRun.from_json(json.load(compare_f))
265269
except:
266-
print(f"Unable to open {compare_file}.")
270+
log.error(f"Unable to open {compare_file}.")
267271
exit(1)
268272

269273
# Sanity checks:
270274
if compare_result.hostname == "Unknown":
271-
print(
275+
log.error(
272276
"Hostname for results in {compare_file} unknown, unable to build a historic average: Refusing to continue."
273277
)
274278
exit(1)
275279
if not Validate.timestamp(cutoff):
276-
print("Invalid timestamp provided, please follow YYYYMMDD_HHMMSS.")
280+
log.error("Invalid timestamp provided, please follow YYYYMMDD_HHMMSS.")
277281
exit(1)
278282

279283
# Build historic average and compare results against historic average:
@@ -331,7 +335,7 @@ def to_hist(
331335

332336
if args.operation == "to_hist":
333337
if args.avg_type != "median":
334-
print("Only median is currently supported: exiting.")
338+
log.error("Only median is currently supported: exiting.")
335339
exit(1)
336340
if not Validate.timestamp(args.cutoff):
337341
raise ValueError("Timestamp must be provided as YYYYMMDD_HHMMSS.")
@@ -352,28 +356,34 @@ def to_hist(
352356
else:
353357
regressions_ignored.append(test)
354358

355-
def print_regression(entry: dict):
356-
"""Print an entry outputted from Compare.to_hist"""
357-
print(f"Test: {entry['name']}")
358-
print(f"-- Historic {entry['avg_type']}: {entry['hist_avg']}")
359-
print(f"-- Run result: {entry['value']}")
360-
print(f"-- Delta: {entry['delta']}")
361-
print("")
359+
def print_regression(entry: dict, is_warning: bool = False):
360+
"""Print an entry outputted from Compare.to_hist
361+
362+
Args:
363+
entry (dict): The entry to print
364+
is_warning (bool): If True, use log.warning instead of log.info
365+
"""
366+
log_func = log.warning if is_warning else log.info
367+
log_func(f"Test: {entry['name']}")
368+
log_func(f"-- Historic {entry['avg_type']}: {entry['hist_avg']}")
369+
log_func(f"-- Run result: {entry['value']}")
370+
log_func(f"-- Delta: {entry['delta']}")
371+
log_func("")
362372

363373
if improvements:
364-
print("#\n# Improvements:\n#\n")
374+
log.info("#\n# Improvements:\n#\n")
365375
for test in improvements:
366376
print_regression(test)
367377
if regressions_ignored:
368-
print("#\n# Regressions (filtered out by regression-filter):\n#\n")
378+
log.info("#\n# Regressions (filtered out by regression-filter):\n#\n")
369379
for test in regressions_ignored:
370380
print_regression(test)
371381
if regressions_of_concern:
372-
print("#\n# Regressions:\n#\n")
382+
log.warning("#\n# Regressions:\n#\n")
373383
for test in regressions_of_concern:
374-
print_regression(test)
384+
print_regression(test, is_warning=True)
375385
exit(1) # Exit 1 to trigger github test failure
376-
print("\nNo unexpected regressions found!")
386+
log.info("\nNo unexpected regressions found!")
377387
else:
378-
print("Unsupported operation: exiting.")
388+
log.error("Unsupported operation: exiting.")
379389
exit(1)

devops/scripts/benchmarks/history.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import json
88
from pathlib import Path
99
import socket
10+
1011
from utils.result import Result, BenchmarkRun
1112
from options import Compare, options
1213
from datetime import datetime, timezone, timedelta
1314
from utils.utils import run
1415
from utils.validate import Validate
15-
16+
from utils.logger import log
1617
from utils.detect_versions import DetectVersion
1718

1819

@@ -33,8 +34,8 @@ def load_result(self, file_path: Path) -> BenchmarkRun:
3334
def load(self, n: int):
3435
results_dir = Path(self.dir) / "results"
3536
if not results_dir.exists() or not results_dir.is_dir():
36-
print(
37-
f"Warning: {results_dir} is not a valid directory: no historic results loaded."
37+
log.warning(
38+
f"{results_dir} is not a valid directory: no historic results loaded."
3839
)
3940
return
4041

@@ -97,7 +98,7 @@ def git_info_from_path(path: Path) -> (str, str):
9798

9899
if options.git_commit_override is None or options.github_repo_override is None:
99100
if options.detect_versions.sycl:
100-
print(f"Auto-detecting sycl version...")
101+
log.info(f"Auto-detecting sycl version...")
101102
github_repo, git_hash = DetectVersion.instance().get_dpcpp_git_info()
102103
else:
103104
git_hash, github_repo = git_info_from_path(
@@ -129,12 +130,12 @@ def git_info_from_path(path: Path) -> (str, str):
129130
if options.build_compute_runtime:
130131
compute_runtime = options.compute_runtime_tag
131132
elif options.detect_versions.compute_runtime:
132-
print(f"Auto-detecting compute_runtime version...")
133+
log.info(f"Auto-detecting compute_runtime version...")
133134
detect_res = DetectVersion.instance()
134135
compute_runtime = detect_res.get_compute_runtime_ver()
135136
if detect_res.get_compute_runtime_ver_cached() is None:
136-
print(
137-
"Warning: Could not find compute_runtime version via github tags API."
137+
log.warning(
138+
"Could not find compute_runtime version via github tags API."
138139
)
139140
else:
140141
compute_runtime = "unknown"
@@ -169,7 +170,7 @@ def save(self, save_name, results: list[Result], to_file=True):
169170
file_path = Path(os.path.join(results_dir, f"{save_name}_{timestamp}.json"))
170171
with file_path.open("w") as file:
171172
json.dump(serialized, file, indent=4)
172-
print(f"Benchmark results saved to {file_path}")
173+
log.info(f"Benchmark results saved to {file_path}")
173174

174175
def find_first(self, name: str) -> BenchmarkRun:
175176
for r in self.runs:

0 commit comments

Comments
 (0)