Skip to content

Commit fb18321

Browse files
authored
[UR][Benchmarks] Add oneDNN benchmarks (#18883)
A selection of OneDNN benchmarks added to the benchmark suite --------- Signed-off-by: Mateusz P. Nowak <mateusz.p.nowak@intel.com>
1 parent cdcf7d8 commit fb18321

File tree

6 files changed

+554
-1
lines changed

6 files changed

+554
-1
lines changed

devops/scripts/benchmarks/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Scripts for running performance tests on SYCL and Unified Runtime.
88
- [Compute Benchmarks](https://github.com/intel/compute-benchmarks/)
99
- [LlamaCpp Benchmarks](https://github.com/ggerganov/llama.cpp)
1010
- [SYCL-Bench](https://github.com/unisa-hpc/sycl-bench)
11+
- [Gromacs](https://gitlab.com/gromacs/gromacs.git)/[Grappa](https://github.com/graeter-group/grappa)
12+
- [BenchDNN](https://github.com/uxlfoundation/oneDNN/tree/main/tests/benchdnn)
1113

1214
## Running
1315

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Copyright (C) 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
5+
6+
from pathlib import Path
7+
from .base import Suite, Benchmark
8+
from options import options
9+
from utils.utils import git_clone, run, create_build_path
10+
from utils.result import Result
11+
from utils.oneapi import get_oneapi
12+
from .benchdnn_list import get_bench_dnn_list
13+
14+
15+
class OneDnnBench(Suite):
16+
def __init__(self, directory):
17+
self.directory = Path(directory).resolve()
18+
build_path = create_build_path(self.directory, "onednn-build")
19+
self.build_dir = Path(build_path)
20+
self.src_dir = self.directory / "onednn-repo"
21+
22+
def git_url(self):
23+
return "https://github.com/uxlfoundation/oneDNN.git"
24+
25+
def git_tag(self):
26+
return "v3.8"
27+
28+
def name(self):
29+
return "BenchDNN"
30+
31+
def benchmarks(self) -> list:
32+
benchmarks = []
33+
for entry in get_bench_dnn_list():
34+
rungraph = True
35+
if len(entry) == 3:
36+
bench_driver, bench_name, bench_args = entry
37+
elif len(entry) == 4:
38+
bench_driver, bench_name, bench_args, rungraph = entry
39+
else:
40+
raise ValueError(
41+
f"Invalid benchmark entry: {entry}. Expected 3 elements."
42+
)
43+
44+
# Create a benchmark instance for both eager and graph execution modes
45+
benchmarks.append(
46+
OneDnnBenchmark(
47+
self, bench_driver, bench_name, bench_args, syclgraph=False
48+
)
49+
)
50+
if rungraph == True:
51+
benchmarks.append(
52+
OneDnnBenchmark(
53+
self, bench_driver, bench_name, bench_args, syclgraph=True
54+
)
55+
)
56+
return benchmarks
57+
58+
def setup(self):
59+
if options.sycl is None:
60+
return
61+
62+
self.src_dir = git_clone(
63+
self.directory,
64+
"onednn-repo",
65+
self.git_url(),
66+
self.git_tag(),
67+
)
68+
69+
self.oneapi = get_oneapi()
70+
cmake_args = [
71+
"cmake",
72+
f"-S {self.src_dir}",
73+
f"-B {self.build_dir}",
74+
f"-DCMAKE_PREFIX_PATH={options.sycl}",
75+
"-DCMAKE_BUILD_TYPE=Release",
76+
"-DDNNL_BUILD_TESTS=ON",
77+
"-DDNNL_BUILD_EXAMPLES=OFF",
78+
"-DDNNL_CPU_RUNTIME=NONE", # Disable SYCL support
79+
"-DDNNL_GPU_RUNTIME=SYCL", # Enable SYCL GPU support
80+
]
81+
run(
82+
cmake_args,
83+
add_sycl=True,
84+
)
85+
86+
run(
87+
f"cmake --build {self.build_dir} --target benchdnn -j {options.build_jobs}",
88+
add_sycl=True,
89+
ld_library=[str(self.build_dir) + "/src"] + self.oneapi.ld_libraries(),
90+
)
91+
92+
def teardown(self):
93+
pass
94+
95+
96+
class OneDnnBenchmark(Benchmark):
97+
def __init__(self, suite, bench_driver, bench_name, bench_args, syclgraph=True):
98+
self.suite = suite
99+
self.bench_name = f"{bench_driver}-{bench_name}"
100+
self.bench_args = f"--{bench_driver} --mode=P --engine=gpu --max-ms-per-prb=100"
101+
102+
self.exp_group = self.bench_name
103+
if syclgraph:
104+
self.bench_args += " --execution-mode=graph"
105+
self.bench_name += "-graph"
106+
else:
107+
self.bench_args += " --execution-mode=direct"
108+
self.bench_name += "-eager"
109+
self.bench_args += f" {bench_args}"
110+
self.bench_bin = suite.build_dir / "tests" / "benchdnn" / "benchdnn"
111+
112+
def enabled(self):
113+
if options.sycl is None:
114+
return False
115+
if options.ur_adapter == "cuda" or options.ur_adapter == "hip":
116+
return False
117+
return True
118+
119+
def name(self):
120+
return f"onednn-{self.bench_name}"
121+
122+
def explicit_group(self) -> str:
123+
return self.exp_group
124+
125+
def setup(self):
126+
if not self.bench_bin.exists():
127+
raise FileNotFoundError(f"Benchmark binary not found: {self.bench_bin}")
128+
129+
def run(self, env_vars):
130+
command = [
131+
str(self.bench_bin),
132+
*self.bench_args.split(),
133+
]
134+
135+
ld_library = self.suite.oneapi.ld_libraries() + [
136+
str(self.suite.build_dir / "src")
137+
]
138+
139+
env_vars = dict(env_vars) if env_vars else {}
140+
env_vars["ONEAPI_DEVICE_SELECTOR"] = "level_zero:*"
141+
142+
output = self.run_bench(
143+
command,
144+
env_vars,
145+
add_sycl=True,
146+
ld_library=ld_library,
147+
use_stdout=True,
148+
)
149+
result_value = self._extract_time(output)
150+
151+
if options.verbose:
152+
print(f"[{self.name()}] Output: {output}")
153+
154+
return [
155+
Result(
156+
label=self.name(),
157+
value=result_value,
158+
unit="ms",
159+
command=command,
160+
env=env_vars,
161+
stdout=output,
162+
git_url=self.suite.git_url(),
163+
git_hash=self.suite.git_tag(),
164+
)
165+
]
166+
167+
# example output:
168+
# Output template: perf, %engine%,%-time%,%-ops%,%-MB%,%-pr
169+
# perf,gpu,0.000000,0.000000,0.000000,0
170+
# perf,gpu,0.000000,0.000000,0.000000,0
171+
def _extract_time(self, output):
172+
lines = output.splitlines()
173+
idx_time = None
174+
values = []
175+
for i, line in enumerate(lines):
176+
if line.startswith("Output template:"):
177+
template = line.replace("Output template: ", "").strip().split(",")
178+
try:
179+
idx_time = template.index("%-time%")
180+
except ValueError:
181+
return 0.0
182+
continue
183+
if idx_time is not None and line.startswith("perf,"):
184+
fields = line.strip().split(",")
185+
if len(fields) > idx_time:
186+
try:
187+
values.append(float(fields[idx_time]))
188+
except Exception:
189+
continue
190+
if values:
191+
return sum(values)
192+
return 0.0
193+
194+
def teardown(self):
195+
pass

0 commit comments

Comments
 (0)