Skip to content

Commit 6101ace

Browse files
committed
[Benchmarks] Use GitProject instead of utils methods
1 parent 611e245 commit 6101ace

File tree

13 files changed

+200
-249
lines changed

13 files changed

+200
-249
lines changed

devops/scripts/benchmarks/CONTRIB.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,17 @@ The benchmark suite generates an interactive HTML dashboard that visualizes `Res
191191

192192
## Utilities
193193

194+
* **`git_project.GitProject`:** Manages git repository cloning, building, and installation for benchmark suites:
195+
* Automatically clones repositories to a specified directory and checks out specific commits/refs.
196+
* Provides standardized directory structure with `src_dir`, `build_dir`, and `install_dir` properties.
197+
* Handles incremental updates - only re-clones if the target commit has changed.
198+
* Supports force rebuilds and custom directory naming via constructor options.
199+
* Provides `configure()`, `build()`, and `install()` methods for CMake-based projects.
200+
* Use this for benchmark suites that need to build from external git repositories (e.g., `ComputeBench`, `VelocityBench`).
194201
* **`utils.utils`:** Provides common helper functions:
195202
* `run()`: Executes shell commands with environment setup (SYCL paths, LD_LIBRARY_PATH).
196-
* `git_clone()`: Clones/updates Git repositories.
197203
* `download()`: Downloads files via HTTP, checks checksums, optionally extracts tar/gz archives.
198204
* `prepare_workdir()`: Sets up the main working directory.
199-
* `create_build_path()`: Creates a clean build directory.
200205
* **`utils.oneapi`:** Provides the `OneAPI` singleton class (`get_oneapi()`). Downloads and installs specified oneAPI components (oneDNN, oneMKL) into the working directory if needed, providing access to their paths (libs, includes, CMake configs). Use this if your benchmark depends on these components instead of requiring a system-wide install.
201206
* **`options.py`:** Defines and holds global configuration options, populated by `argparse` in `main.py`. Use options instead of defining your own global variables.
202207
* **`presets.py`:** Defines named sets of suites (`enabled_suites()`) used by the `--preset` argument.

devops/scripts/benchmarks/benches/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ def tracing_enabled(self, run_trace, force_trace, tr_type: TracingType):
8484
"""Returns whether tracing is enabled for the given type."""
8585
return (self.traceable(tr_type) or force_trace) and run_trace == tr_type
8686

87-
@abstractmethod
8887
def setup(self):
88+
"""Extra setup steps to be performed before running the benchmark."""
8989
pass
9090

9191
@abstractmethod

devops/scripts/benchmarks/benches/benchdnn.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,16 @@
88

99
from .base import Suite, Benchmark, TracingType
1010
from options import options
11-
from utils.utils import git_clone, run, create_build_path
1211
from utils.result import Result
1312
from utils.oneapi import get_oneapi
1413
from utils.logger import log
1514
from .benchdnn_list import get_bench_dnn_list
15+
from git_project import GitProject
1616

1717

1818
class OneDnnBench(Suite):
1919
def __init__(self, directory):
20-
self.directory = Path(directory).resolve()
21-
build_path = create_build_path(self.directory, "onednn-build")
22-
self.build_dir = Path(build_path)
23-
self.src_dir = self.directory / "onednn-repo"
20+
self.project = None
2421

2522
def git_url(self):
2623
return "https://github.com/uxlfoundation/oneDNN.git"
@@ -62,36 +59,35 @@ def setup(self) -> None:
6259
if options.sycl is None:
6360
return
6461

65-
self.src_dir = git_clone(
66-
self.directory,
67-
"onednn-repo",
68-
self.git_url(),
69-
self.git_tag(),
70-
)
71-
7262
self.oneapi = get_oneapi()
73-
cmake_args = [
74-
"cmake",
75-
f"-S {self.src_dir}",
76-
f"-B {self.build_dir}",
63+
if self.project is None:
64+
self.project = GitProject(
65+
self.git_url(),
66+
self.git_tag(),
67+
Path(options.workdir),
68+
"onednn",
69+
force_rebuild=True,
70+
)
71+
72+
extra_cmake_args = [
7773
f"-DCMAKE_PREFIX_PATH={options.sycl}",
7874
"-DCMAKE_CXX_COMPILER=clang++",
7975
"-DCMAKE_C_COMPILER=clang",
80-
"-DCMAKE_BUILD_TYPE=Release",
8176
"-DDNNL_BUILD_TESTS=ON",
8277
"-DDNNL_BUILD_EXAMPLES=OFF",
8378
"-DDNNL_CPU_RUNTIME=NONE", # Disable SYCL CPU support
8479
"-DDNNL_GPU_RUNTIME=SYCL", # Enable SYCL GPU support
8580
]
86-
run(
87-
cmake_args,
81+
self.project.configure(
82+
extra_cmake_args,
83+
install_prefix=False,
8884
add_sycl=True,
8985
)
90-
91-
run(
92-
f"cmake --build {self.build_dir} --target benchdnn -j {options.build_jobs}",
86+
self.project.build(
87+
target="benchdnn",
9388
add_sycl=True,
94-
ld_library=[str(self.build_dir) + "/src"] + self.oneapi.ld_libraries(),
89+
ld_library=[str(self.project.build_dir / "src")]
90+
+ self.oneapi.ld_libraries(),
9591
timeout=60 * 20,
9692
)
9793

@@ -113,7 +109,10 @@ def __init__(self, suite, bench_driver, bench_name, bench_args, syclgraph=True):
113109
self.bench_args += " --execution-mode=direct"
114110
self.bench_name += "-eager"
115111
self.bench_args += f" {bench_args}"
116-
self.bench_bin = suite.build_dir / "tests" / "benchdnn" / "benchdnn"
112+
113+
@property
114+
def benchmark_bin(self) -> Path:
115+
return self.suite.project.build_dir / "tests" / "benchdnn" / "benchdnn"
117116

118117
def enabled(self):
119118
if options.sycl is None:
@@ -129,8 +128,8 @@ def explicit_group(self) -> str:
129128
return self.exp_group
130129

131130
def setup(self):
132-
if not self.bench_bin.exists():
133-
raise FileNotFoundError(f"Benchmark binary not found: {self.bench_bin}")
131+
if not self.benchmark_bin.exists():
132+
raise FileNotFoundError(f"Benchmark binary not found: {self.benchmark_bin}")
134133

135134
def run(
136135
self,
@@ -145,12 +144,12 @@ def run(
145144
extra_trace_opt = None
146145

147146
command = [
148-
str(self.bench_bin),
147+
str(self.benchmark_bin),
149148
*self.bench_args.split(),
150149
]
151150

152151
ld_library = self.suite.oneapi.ld_libraries() + [
153-
str(self.suite.build_dir / "src")
152+
str(self.suite.project.build_dir / "src")
154153
]
155154

156155
env_vars = dict(env_vars) if env_vars else {}

devops/scripts/benchmarks/benches/compute.py

Lines changed: 23 additions & 34 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
from itertools import product
7-
import os
87
import csv
98
import io
109
import copy
1110
import math
1211
from enum import Enum
12+
from pathlib import Path
1313

14-
from utils.utils import run, git_clone, create_build_path
1514
from .base import Benchmark, Suite, TracingType
1615
from utils.result import BenchmarkMetadata, Result
1716
from .base import Benchmark, Suite
1817
from options import options
18+
from git_project import GitProject
1919

2020

2121
class RUNTIMES(Enum):
@@ -50,8 +50,8 @@ def runtime_to_tag_name(runtime: RUNTIMES) -> str:
5050

5151
class ComputeBench(Suite):
5252
def __init__(self, directory):
53-
self.directory = directory
5453
self.submit_graph_num_kernels = [4, 10, 32]
54+
self.project = None
5555

5656
def name(self) -> str:
5757
return "Compute Benchmarks"
@@ -66,47 +66,36 @@ def setup(self) -> None:
6666
if options.sycl is None:
6767
return
6868

69-
repo_path = git_clone(
70-
self.directory,
71-
"compute-benchmarks-repo",
72-
self.git_url(),
73-
self.git_hash(),
74-
)
75-
build_path = create_build_path(self.directory, "compute-benchmarks-build")
69+
if self.project is None:
70+
self.project = GitProject(
71+
self.git_url(),
72+
self.git_hash(),
73+
Path(options.workdir),
74+
"compute-benchmarks",
75+
force_rebuild=True,
76+
)
7677

77-
configure_command = [
78-
"cmake",
79-
f"-B {build_path}",
80-
f"-S {repo_path}",
81-
f"-DCMAKE_BUILD_TYPE=Release",
78+
extra_args = [
8279
f"-DBUILD_SYCL=ON",
8380
f"-DSYCL_COMPILER_ROOT={options.sycl}",
8481
f"-DALLOW_WARNINGS=ON",
8582
f"-DCMAKE_CXX_COMPILER=clang++",
8683
f"-DCMAKE_C_COMPILER=clang",
8784
]
88-
8985
if options.ur_adapter == "cuda":
90-
configure_command += [
86+
extra_args += [
9187
"-DBUILD_SYCL_WITH_CUDA=ON",
9288
"-DBUILD_L0=OFF",
9389
"-DBUILD_OCL=OFF",
9490
]
95-
9691
if options.ur is not None:
97-
configure_command += [
92+
extra_args += [
9893
f"-DBUILD_UR=ON",
9994
f"-Dunified-runtime_DIR={options.ur}/lib/cmake/unified-runtime",
10095
]
10196

102-
run(configure_command, add_sycl=True)
103-
104-
run(
105-
f"cmake --build {build_path} -j {options.build_jobs}",
106-
add_sycl=True,
107-
)
108-
109-
self.built = True
97+
self.project.configure(extra_args, install_prefix=False, add_sycl=True)
98+
self.project.build(add_sycl=True)
11099

111100
def additional_metadata(self) -> dict[str, BenchmarkMetadata]:
112101
metadata = {
@@ -370,7 +359,7 @@ def __init__(
370359
runtime: RUNTIMES = None,
371360
profiler_type: PROFILERS = PROFILERS.TIMER,
372361
):
373-
super().__init__(bench.directory, bench)
362+
super().__init__(options.workdir, bench)
374363
self.bench = bench
375364
self.bench_name = name
376365
self.test = test
@@ -384,6 +373,11 @@ def __init__(
384373
self._validate_attr("iterations_regular")
385374
self._validate_attr("iterations_trace")
386375

376+
@property
377+
def benchmark_bin(self) -> Path:
378+
"""Returns the path to the benchmark binary"""
379+
return self.bench.project.build_dir / "bin" / self.bench_name
380+
387381
def get_iters(self, run_trace: TracingType):
388382
"""Returns the number of iterations to run for the given tracing type."""
389383
return (
@@ -437,11 +431,6 @@ def bin_args(self, run_trace: TracingType = TracingType.NONE) -> list[str]:
437431
def extra_env_vars(self) -> dict:
438432
return {}
439433

440-
def setup(self):
441-
self.benchmark_bin = os.path.join(
442-
self.bench.directory, "compute-benchmarks-build", "bin", self.bench_name
443-
)
444-
445434
def explicit_group(self):
446435
return ""
447436

@@ -455,7 +444,7 @@ def run(
455444
force_trace: bool = False,
456445
) -> list[Result]:
457446
command = [
458-
f"{self.benchmark_bin}",
447+
str(self.benchmark_bin),
459448
f"--test={self.test}",
460449
"--csv",
461450
"--noHeaders",

devops/scripts/benchmarks/benches/gromacs.py

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,21 @@
99

1010
from .base import Suite, Benchmark, TracingType
1111
from options import options
12-
from utils.utils import git_clone, download, run, create_build_path
12+
from utils.utils import download, run
1313
from utils.result import Result
1414
from utils.oneapi import get_oneapi
1515
from utils.logger import log
16-
from utils.unitrace import get_unitrace
16+
from git_project import GitProject
1717

1818

1919
class GromacsBench(Suite):
20+
def __init__(self, directory):
21+
self.project = None
22+
model_path = str(Path(options.workdir) / self.grappa_file()).replace(
23+
".tar.gz", ""
24+
)
25+
self.grappa_dir = Path(model_path)
26+
2027
def git_url(self):
2128
return "https://gitlab.com/gromacs/gromacs.git"
2229

@@ -29,14 +36,6 @@ def grappa_url(self):
2936
def grappa_file(self):
3037
return Path(os.path.basename(self.grappa_url()))
3138

32-
def __init__(self, directory):
33-
self.directory = Path(directory).resolve()
34-
model_path = str(self.directory / self.grappa_file()).replace(".tar.gz", "")
35-
self.grappa_dir = Path(model_path)
36-
build_path = create_build_path(self.directory, "gromacs-build")
37-
self.gromacs_build_path = Path(build_path)
38-
self.gromacs_src = self.directory / "gromacs-repo"
39-
4039
def name(self):
4140
return "Gromacs Bench"
4241

@@ -52,24 +51,22 @@ def benchmarks(self) -> list[Benchmark]:
5251
]
5352

5453
def setup(self) -> None:
55-
self.gromacs_src = git_clone(
56-
self.directory,
57-
"gromacs-repo",
58-
self.git_url(),
59-
self.git_tag(),
60-
)
54+
if self.project is None:
55+
self.project = GitProject(
56+
self.git_url(),
57+
self.git_tag(),
58+
Path(options.workdir),
59+
"gromacs",
60+
force_rebuild=True,
61+
)
6162

6263
# TODO: Detect the GPU architecture and set the appropriate flags
6364

6465
# Build GROMACS
6566

6667
self.oneapi = get_oneapi()
6768

68-
cmd_list = [
69-
"cmake",
70-
f"-S {self.gromacs_src}",
71-
f"-B {self.gromacs_build_path}",
72-
"-DCMAKE_BUILD_TYPE=Release",
69+
extra_args = [
7370
"-DCMAKE_CXX_COMPILER=clang++",
7471
"-DCMAKE_C_COMPILER=clang",
7572
"-DGMX_GPU=SYCL",
@@ -84,21 +81,14 @@ def setup(self) -> None:
8481
]
8582

8683
if options.unitrace:
87-
cmd_list.append("-DGMX_USE_ITT=ON")
84+
extra_args.append("-DGMX_USE_ITT=ON")
8885

89-
run(
90-
cmd_list,
91-
add_sycl=True,
92-
)
93-
run(
94-
f"cmake --build {self.gromacs_build_path} -j {options.build_jobs}",
95-
add_sycl=True,
96-
ld_library=self.oneapi.ld_libraries(),
97-
)
86+
self.project.configure(extra_args, install_prefix=False, add_sycl=True)
87+
self.project.build(add_sycl=True, ld_library=self.oneapi.ld_libraries())
9888
download(
99-
self.directory,
89+
options.workdir,
10090
self.grappa_url(),
101-
self.directory / self.grappa_file(),
91+
options.workdir / self.grappa_file(),
10292
checksum="cc02be35ba85c8b044e47d097661dffa8bea57cdb3db8b5da5d01cdbc94fe6c8902652cfe05fb9da7f2af0698be283a2",
10393
untar=True,
10494
)
@@ -114,9 +104,7 @@ def __init__(self, suite, model, type, option):
114104
self.type = type # The type of benchmark ("pme" or "rf")
115105
self.option = option # "graphs" or "eager"
116106

117-
self.gromacs_src = suite.gromacs_src
118107
self.grappa_dir = suite.grappa_dir
119-
self.gmx_path = suite.gromacs_build_path / "bin" / "gmx"
120108

121109
if self.type == "pme":
122110
self.extra_args = [
@@ -129,6 +117,10 @@ def __init__(self, suite, model, type, option):
129117
else:
130118
self.extra_args = []
131119

120+
@property
121+
def gmx_path(self) -> Path:
122+
return self.suite.project.build_dir / "bin" / "gmx"
123+
132124
def name(self):
133125
return f"gromacs-{self.model}-{self.type}-{self.option}"
134126

0 commit comments

Comments
 (0)