Skip to content

Commit 9df68fc

Browse files
authored
Merge pull request #2364 from pbalcer/new-benchmarks-mkl
add 3 more benchmarks
2 parents a563456 + c0a7191 commit 9df68fc

File tree

7 files changed

+224
-88
lines changed

7 files changed

+224
-88
lines changed

scripts/benchmarks/benches/base.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,21 @@ def run_bench(self, command, env_vars, ld_library=[]):
4040
ld_library=ld_library
4141
).stdout.decode()
4242

43-
def create_data_path(self, name):
44-
data_path = os.path.join(self.directory, "data", name)
45-
46-
if options.rebuild and Path(data_path).exists():
47-
shutil.rmtree(data_path)
43+
def create_data_path(self, name, skip_data_dir = False):
44+
if skip_data_dir:
45+
data_path = os.path.join(self.directory, name)
46+
else:
47+
data_path = os.path.join(self.directory, 'data', name)
48+
if options.rebuild and Path(data_path).exists():
49+
shutil.rmtree(data_path)
4850

4951
Path(data_path).mkdir(parents=True, exist_ok=True)
5052

5153
return data_path
5254

53-
def download(self, name, url, file, untar = False):
54-
self.data_path = self.create_data_path(name)
55-
return download(self.data_path, url, file, True)
55+
def download(self, name, url, file, untar = False, unzip = False, skip_data_dir = False):
56+
self.data_path = self.create_data_path(name, skip_data_dir)
57+
return download(self.data_path, url, file, untar, unzip)
5658

5759
def name(self):
5860
raise NotImplementedError()

scripts/benchmarks/benches/llamacpp.py

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,85 +6,14 @@
66
import csv
77
import io
88
from pathlib import Path
9-
import re
10-
import shutil
119
from utils.utils import download, git_clone
1210
from .base import Benchmark, Suite
1311
from .result import Result
1412
from utils.utils import run, create_build_path
1513
from .options import options
14+
from .oneapi import get_oneapi
1615
import os
1716

18-
class OneAPI:
19-
# random unique number for benchmark oneAPI installation
20-
ONEAPI_BENCHMARK_INSTANCE_ID = 98765
21-
def __init__(self, directory):
22-
self.oneapi_dir = os.path.join(directory, 'oneapi')
23-
Path(self.oneapi_dir).mkdir(parents=True, exist_ok=True)
24-
# delete if some option is set?
25-
26-
# can we just hardcode these links?
27-
self.install_package('dnnl', 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/87e117ab-039b-437d-9c80-dcd5c9e675d5/intel-onednn-2025.0.0.862_offline.sh')
28-
self.install_package('mkl', 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/79153e0f-74d7-45af-b8c2-258941adf58a/intel-onemkl-2025.0.0.940_offline.sh')
29-
return
30-
31-
def install_package(self, name, url):
32-
package_path = os.path.join(self.oneapi_dir, name)
33-
if Path(package_path).exists():
34-
print(f"{package_path} exists, skipping installing oneAPI package {name}...")
35-
return
36-
37-
package = download(self.oneapi_dir, url, f'package_{name}.sh')
38-
try:
39-
print(f"installing f{name}")
40-
run(f"sh {package} -a -s --eula accept --install-dir {self.oneapi_dir} --instance f{self.ONEAPI_BENCHMARK_INSTANCE_ID}")
41-
except:
42-
print("oneAPI installation likely exists already")
43-
return
44-
print(f"f{name} installation complete")
45-
46-
def package_dir(self, package, dir):
47-
return os.path.join(self.oneapi_dir, package, 'latest', dir)
48-
49-
def package_cmake(self, package):
50-
package_lib = self.package_dir(package, 'lib')
51-
return os.path.join(package_lib, 'cmake', package)
52-
53-
def mkl_lib(self):
54-
return self.package_dir('mkl', 'lib')
55-
56-
def mkl_include(self):
57-
return self.package_dir('mkl', 'include')
58-
59-
def mkl_cmake(self):
60-
return self.package_cmake('mkl')
61-
62-
def dnn_lib(self):
63-
return self.package_dir('dnnl', 'lib')
64-
65-
def dnn_include(self):
66-
return self.package_dir('dnnl', 'include')
67-
68-
def dnn_cmake(self):
69-
return self.package_cmake('dnnl')
70-
71-
def tbb_lib(self):
72-
return self.package_dir('tbb', 'lib')
73-
74-
def tbb_cmake(self):
75-
return self.package_cmake('tbb')
76-
77-
def compiler_lib(self):
78-
return self.package_dir('compiler', 'lib')
79-
80-
def ld_libraries(self):
81-
return [
82-
self.compiler_lib(),
83-
self.mkl_lib(),
84-
self.tbb_lib(),
85-
self.dnn_lib()
86-
]
87-
8817
class LlamaCppBench(Suite):
8918
def __init__(self, directory):
9019
if options.sycl is None:
@@ -103,7 +32,7 @@ def setup(self):
10332

10433
self.model = download(self.models_dir, "https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-gguf/resolve/main/Phi-3-mini-4k-instruct-q4.gguf", "Phi-3-mini-4k-instruct-q4.gguf")
10534

106-
self.oneapi = OneAPI(self.directory)
35+
self.oneapi = get_oneapi()
10736

10837
self.build_path = create_build_path(self.directory, 'llamacpp-build')
10938

scripts/benchmarks/benches/oneapi.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (C) 2024 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 utils.utils import download, run
8+
from .options import options
9+
import os
10+
11+
class OneAPI:
12+
# random unique number for benchmark oneAPI installation
13+
ONEAPI_BENCHMARK_INSTANCE_ID = 98765
14+
def __init__(self):
15+
self.oneapi_dir = os.path.join(options.workdir, 'oneapi')
16+
Path(self.oneapi_dir).mkdir(parents=True, exist_ok=True)
17+
# delete if some option is set?
18+
19+
# can we just hardcode these links?
20+
self.install_package('dnnl', 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/87e117ab-039b-437d-9c80-dcd5c9e675d5/intel-onednn-2025.0.0.862_offline.sh')
21+
self.install_package('mkl', 'https://registrationcenter-download.intel.com/akdlm/IRC_NAS/79153e0f-74d7-45af-b8c2-258941adf58a/intel-onemkl-2025.0.0.940_offline.sh')
22+
return
23+
24+
def install_package(self, name, url):
25+
package_path = os.path.join(self.oneapi_dir, name)
26+
if Path(package_path).exists():
27+
print(f"{package_path} exists, skipping installing oneAPI package {name}...")
28+
return
29+
30+
package = download(self.oneapi_dir, url, f'package_{name}.sh')
31+
try:
32+
print(f"installing f{name}")
33+
run(f"sh {package} -a -s --eula accept --install-dir {self.oneapi_dir} --instance f{self.ONEAPI_BENCHMARK_INSTANCE_ID}")
34+
except:
35+
print("oneAPI installation likely exists already")
36+
return
37+
print(f"f{name} installation complete")
38+
39+
def package_dir(self, package, dir):
40+
return os.path.join(self.oneapi_dir, package, 'latest', dir)
41+
42+
def package_cmake(self, package):
43+
package_lib = self.package_dir(package, 'lib')
44+
return os.path.join(package_lib, 'cmake', package)
45+
46+
def mkl_lib(self):
47+
return self.package_dir('mkl', 'lib')
48+
49+
def mkl_include(self):
50+
return self.package_dir('mkl', 'include')
51+
52+
def mkl_cmake(self):
53+
return self.package_cmake('mkl')
54+
55+
def dnn_lib(self):
56+
return self.package_dir('dnnl', 'lib')
57+
58+
def dnn_include(self):
59+
return self.package_dir('dnnl', 'include')
60+
61+
def dnn_cmake(self):
62+
return self.package_cmake('dnnl')
63+
64+
def tbb_lib(self):
65+
return self.package_dir('tbb', 'lib')
66+
67+
def tbb_cmake(self):
68+
return self.package_cmake('tbb')
69+
70+
def compiler_lib(self):
71+
return self.package_dir('compiler', 'lib')
72+
73+
def ld_libraries(self):
74+
return [
75+
self.compiler_lib(),
76+
self.mkl_lib(),
77+
self.tbb_lib(),
78+
self.dnn_lib()
79+
]
80+
81+
oneapi_instance = None
82+
83+
def get_oneapi() -> OneAPI: # oneAPI singleton
84+
if not hasattr(get_oneapi, "instance"):
85+
get_oneapi.instance = OneAPI()
86+
return get_oneapi.instance

scripts/benchmarks/benches/options.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Compare(Enum):
88

99
@dataclass
1010
class Options:
11+
workdir: str = None
1112
sycl: str = None
1213
ur: str = None
1314
ur_adapter: str = None

scripts/benchmarks/benches/velocity.py

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
from .result import Result
1111
from utils.utils import run, create_build_path
1212
from .options import options
13+
from .oneapi import get_oneapi
14+
import shutil
15+
1316
import os
1417

1518
class VelocityBench(Suite):
@@ -35,7 +38,10 @@ def benchmarks(self) -> list[Benchmark]:
3538
CudaSift(self),
3639
Easywave(self),
3740
QuickSilver(self),
38-
SobelFilter(self)
41+
SobelFilter(self),
42+
DLCifar(self),
43+
DLMnist(self),
44+
SVM(self)
3945
]
4046

4147
class VelocityBase(Benchmark):
@@ -50,6 +56,12 @@ def __init__(self, name: str, bin_name: str, vb: VelocityBench, unit: str):
5056
def download_deps(self):
5157
return
5258

59+
def extra_cmake_args(self) -> list[str]:
60+
return []
61+
62+
def ld_libraries(self) -> list[str]:
63+
return []
64+
5365
def setup(self):
5466
self.download_deps()
5567
self.benchmark_bin = os.path.join(self.directory, self.bench_name, self.bin_name)
@@ -62,8 +74,10 @@ def setup(self):
6274
f"-S {self.code_path}",
6375
f"-DCMAKE_BUILD_TYPE=Release"
6476
]
77+
configure_command += self.extra_cmake_args()
78+
6579
run(configure_command, {'CC': 'clang', 'CXX':'clang++'}, add_sycl=True)
66-
run(f"cmake --build {build_path} -j", add_sycl=True)
80+
run(f"cmake --build {build_path} -j", add_sycl=True, ld_library=self.ld_libraries())
6781

6882
def bin_args(self) -> list[str]:
6983
return []
@@ -82,7 +96,7 @@ def run(self, env_vars) -> list[Result]:
8296
]
8397
command += self.bin_args()
8498

85-
result = self.run_bench(command, env_vars)
99+
result = self.run_bench(command, env_vars, ld_library=self.ld_libraries())
86100

87101
return [ Result(label=self.name(), value=self.parse_output(result), command=command, env=env_vars, stdout=result, unit=self.unit) ]
88102

@@ -136,7 +150,6 @@ def __init__(self, vb: VelocityBench):
136150

137151
def download_deps(self):
138152
self.download("sobel_filter", "https://github.com/oneapi-src/Velocity-Bench/raw/main/sobel_filter/res/sobel_filter_data.tgz?download=", "sobel_filter_data.tgz", untar=True)
139-
return
140153

141154
def name(self):
142155
return "Velocity-Bench Sobel Filter"
@@ -228,7 +241,6 @@ def get_last_elapsed_time(self, log_file_path) -> float:
228241
def parse_output(self, stdout: str) -> float:
229242
return self.get_last_elapsed_time(os.path.join(options.benchmark_cwd, "easywave.log"))
230243

231-
232244
class CudaSift(VelocityBase):
233245
def __init__(self, vb: VelocityBench):
234246
super().__init__("cudaSift", "cudaSift", vb, "ms")
@@ -248,3 +260,103 @@ def parse_output(self, stdout: str) -> float:
248260
return float(match.group(1))
249261
else:
250262
raise ValueError("Failed to parse benchmark output.")
263+
264+
class DLCifar(VelocityBase):
265+
def __init__(self, vb: VelocityBench):
266+
self.oneapi = get_oneapi()
267+
super().__init__("dl-cifar", "dl-cifar_sycl", vb, "s")
268+
269+
def ld_libraries(self):
270+
return self.oneapi.ld_libraries()
271+
272+
def download_deps(self):
273+
# TODO: dl-cifar hardcodes the path to this dataset as "../../datasets/cifar-10-binary"...
274+
self.download("datasets", "https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz", "cifar-10-binary.tar.gz", untar=True, skip_data_dir=True)
275+
return
276+
277+
def extra_cmake_args(self):
278+
return [
279+
f"-DCMAKE_CXX_FLAGS=-O3 -fsycl -ffast-math -I{self.oneapi.dnn_include()} -I{self.oneapi.mkl_include()} -L{self.oneapi.dnn_lib()} -L{self.oneapi.mkl_lib()}"
280+
]
281+
282+
def name(self):
283+
return "Velocity-Bench dl-cifar"
284+
285+
def parse_output(self, stdout: str) -> float:
286+
match = re.search(r'dl-cifar - total time for whole calculation: (\d+\.\d+) s', stdout)
287+
if match:
288+
return float(match.group(1))
289+
else:
290+
raise ValueError("Failed to parse benchmark output.")
291+
292+
class DLMnist(VelocityBase):
293+
def __init__(self, vb: VelocityBench):
294+
self.oneapi = get_oneapi()
295+
super().__init__("dl-mnist", "dl-mnist-sycl", vb, "s")
296+
297+
def ld_libraries(self):
298+
return self.oneapi.ld_libraries()
299+
300+
def download_deps(self):
301+
# TODO: dl-mnist hardcodes the path to this dataset as "../../datasets/"...
302+
self.download("datasets", "https://raw.githubusercontent.com/fgnt/mnist/master/train-images-idx3-ubyte.gz", "train-images.idx3-ubyte.gz", unzip=True, skip_data_dir=True)
303+
self.download("datasets", "https://raw.githubusercontent.com/fgnt/mnist/master/train-labels-idx1-ubyte.gz", "train-labels.idx1-ubyte.gz", unzip=True, skip_data_dir=True)
304+
self.download("datasets", "https://raw.githubusercontent.com/fgnt/mnist/master/t10k-images-idx3-ubyte.gz", "t10k-images.idx3-ubyte.gz", unzip=True, skip_data_dir=True)
305+
self.download("datasets", "https://raw.githubusercontent.com/fgnt/mnist/master/t10k-labels-idx1-ubyte.gz", "t10k-labels.idx1-ubyte.gz", unzip=True, skip_data_dir=True)
306+
307+
def extra_cmake_args(self):
308+
return [
309+
f"-DCMAKE_CXX_FLAGS=-O3 -fsycl -ffast-math -I{self.oneapi.dnn_include()} -I{self.oneapi.mkl_include()} -L{self.oneapi.dnn_lib()} -L{self.oneapi.mkl_lib()}"
310+
]
311+
312+
def name(self):
313+
return "Velocity-Bench dl-mnist"
314+
315+
def bin_args(self):
316+
return [
317+
"-conv_algo", "ONEDNN_AUTO"
318+
]
319+
320+
# TODO: This shouldn't be required.
321+
# The application crashes with a segfault without it.
322+
def extra_env_vars(self):
323+
return {
324+
"NEOReadDebugKeys":"1",
325+
"DisableScratchPages":"0",
326+
}
327+
328+
def parse_output(self, stdout: str) -> float:
329+
match = re.search(r'dl-mnist - total time for whole calculation: (\d+\.\d+) s', stdout)
330+
if match:
331+
return float(match.group(1))
332+
else:
333+
raise ValueError("Failed to parse benchmark output.")
334+
335+
class SVM(VelocityBase):
336+
def __init__(self, vb: VelocityBench):
337+
self.oneapi = get_oneapi()
338+
super().__init__("svm", "svm_sycl", vb, "s")
339+
340+
def ld_libraries(self):
341+
return self.oneapi.ld_libraries()
342+
343+
def extra_cmake_args(self):
344+
return [
345+
f"-DCMAKE_CXX_FLAGS=-O3 -fsycl -ffast-math -I{self.oneapi.dnn_include()} -I{self.oneapi.mkl_include()} -L{self.oneapi.dnn_lib()} -L{self.oneapi.mkl_lib()}"
346+
]
347+
348+
def name(self):
349+
return "Velocity-Bench svm"
350+
351+
def bin_args(self):
352+
return [
353+
f"{self.code_path}/a9a",
354+
f"{self.code_path}/a.m",
355+
]
356+
357+
def parse_output(self, stdout: str) -> float:
358+
match = re.search(r'Total elapsed time : (\d+\.\d+) s', stdout)
359+
if match:
360+
return float(match.group(1))
361+
else:
362+
raise ValueError("Failed to parse benchmark output.")

0 commit comments

Comments
 (0)