-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for NPB-3.4.3-MZ benchmark (#116)
Benchkit support is very similar to NPB-3.4.3, but is in its own directory since the benchmarks are distributed separately. Main difference in benchkit support is the `nb_threads` parameter, which for *-MZ consists of a tuple of 2 integers -- e.g. (2, 4) -- indicating the number of outer and inner threads. Signed-off-by: Rafael Chehab <[email protected]>
- Loading branch information
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Copyright (C) 2024 Huawei Technologies Co., Ltd. All rights reserved. | ||
# SPDX-License-Identifier: MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
# Copyright (C) 2024 Huawei Technologies Co., Ltd. All rights reserved. | ||
# SPDX-License-Identifier: MIT | ||
|
||
import pathlib | ||
from typing import Any, Dict, Iterable, List, Optional, Tuple | ||
|
||
from benchkit.benchmark import Benchmark, CommandAttachment, PostRunHook, PreRunHook | ||
from benchkit.campaign import CampaignCartesianProduct | ||
from benchkit.commandwrappers import CommandWrapper | ||
from benchkit.dependencies.packages import PackageDependency | ||
from benchkit.platforms import Platform | ||
from benchkit.sharedlibs import SharedLib | ||
from benchkit.utils.types import CpuOrder, PathType | ||
|
||
|
||
class NPBMZBench(Benchmark): | ||
""" | ||
Benchmark object for Will-it-Scale benchmark. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
src_dir: PathType, | ||
command_wrappers: Iterable[CommandWrapper], | ||
command_attachments: Iterable[CommandAttachment], | ||
shared_libs: Iterable[SharedLib], | ||
pre_run_hooks: Iterable[PreRunHook], | ||
post_run_hooks: Iterable[PostRunHook], | ||
platform: Platform | None = None, | ||
) -> None: | ||
super().__init__( | ||
command_wrappers=command_wrappers, | ||
command_attachments=command_attachments, | ||
shared_libs=shared_libs, | ||
pre_run_hooks=pre_run_hooks, | ||
post_run_hooks=post_run_hooks, | ||
) | ||
|
||
if platform is not None: | ||
self.platform = platform # TODO Warning! overriding upper class platform | ||
|
||
# TODO duplication with LevelDB & perhaps many more in the future. | ||
bench_src_path = pathlib.Path(src_dir) | ||
if not self.platform.comm.isdir(bench_src_path) and self.platform.comm.isfile( | ||
bench_src_path / "NPB3.4-MZ-SER.README" | ||
): | ||
raise ValueError( | ||
f"Invalid NAS parallel benchmark MZ source path: {bench_src_path}\n" | ||
"src_dir argument can be defined manually." | ||
) | ||
self._bench_src_path = bench_src_path | ||
|
||
@property | ||
def bench_src_path(self) -> str: | ||
return self._bench_src_path | ||
|
||
@staticmethod | ||
def get_build_var_names() -> List[str]: | ||
return [ | ||
"test_name", | ||
"t_class", | ||
] | ||
|
||
@staticmethod | ||
def get_run_var_names() -> List[str]: | ||
return [ | ||
"cpu_order", | ||
"master_thread_core", | ||
"nb_threads", | ||
] | ||
|
||
@staticmethod | ||
def get_tilt_var_names() -> List[str]: | ||
return [] | ||
|
||
def dependencies(self) -> List[PackageDependency]: | ||
return super().dependencies() + [ | ||
PackageDependency("build-essential"), | ||
PackageDependency("libhwloc-dev"), | ||
] | ||
|
||
def build_tilt(self, **kwargs) -> None: | ||
raise NotImplementedError("Tilt is not necessary for this benchmark.") | ||
|
||
def prebuild_bench( | ||
self, | ||
**_kwargs, | ||
) -> None: | ||
self.platform.comm.shell(command="make clean", current_dir=self.bench_src_path) | ||
|
||
def build_bench( # pylint: disable=arguments-differ | ||
self, | ||
test_name: str, | ||
t_class: str, | ||
**_kwargs, | ||
) -> None: | ||
self.platform.comm.shell( | ||
command=f"make clean", | ||
current_dir=self.bench_src_path, | ||
print_input=True, | ||
print_output=True, | ||
) | ||
|
||
if not self.platform.comm.isdir(self._bench_src_path / "bin"): | ||
self.platform.comm.shell( | ||
command=f"mkdir -p bin", | ||
current_dir=self.bench_src_path, | ||
print_input=True, | ||
print_output=True, | ||
) | ||
|
||
self.platform.comm.shell( | ||
command=f"make {test_name} CLASS={t_class}", | ||
current_dir=self.bench_src_path, | ||
print_input=True, | ||
print_output=True, | ||
) | ||
|
||
def clean_bench(self) -> None: | ||
pass | ||
|
||
def single_run( # pylint: disable=arguments-differ | ||
self, | ||
benchmark_duration_seconds: int, | ||
build_variables: Dict[str, Any], | ||
cpu_order: CpuOrder = None, | ||
nb_threads: Tuple[int, int] = (2, 2), | ||
master_thread_core: Optional[int] = None, | ||
**kwargs, | ||
) -> str: | ||
|
||
test_name: str = build_variables["test_name"] | ||
t_class: str = build_variables["t_class"] | ||
|
||
environment = self._preload_env( | ||
cpu_order=cpu_order, | ||
master_thread_core=master_thread_core, | ||
**kwargs, | ||
) | ||
if environment is None: | ||
environment = {} | ||
|
||
outer_threads, inner_threads = nb_threads | ||
|
||
environment["OMP_NUM_THREADS"] = f"{outer_threads},{inner_threads}" | ||
|
||
run_command = [ | ||
f"./bin/{test_name}.{t_class}.x", | ||
] | ||
|
||
wrapped_run_command, wrapped_environment = self._wrap_command( | ||
run_command=run_command, | ||
environment=environment, | ||
cpu_order=cpu_order, | ||
master_thread_core=master_thread_core, | ||
**kwargs, | ||
) | ||
|
||
output = self.run_bench_command( | ||
run_command=run_command, | ||
wrapped_run_command=wrapped_run_command, | ||
current_dir=self._bench_src_path, | ||
environment=environment, | ||
wrapped_environment=wrapped_environment, | ||
print_output=False, | ||
) | ||
|
||
return output | ||
|
||
def parse_output_to_results( # pylint: disable=arguments-differ | ||
self, | ||
command_output: str, | ||
benchmark_duration_seconds: int, | ||
**kwargs, | ||
) -> Dict[str, Any]: | ||
|
||
total_time = command_output.strip().split('seconds =')[1].split('\n')[0].strip() | ||
mops_total = command_output.strip().split('Mop/s total =')[1].split('\n')[0].strip() | ||
mops_thread = command_output.strip().split('Mop/s/thread =')[1].split('\n')[0].strip() | ||
|
||
result_dict = { | ||
"duration": total_time, | ||
"throughput": mops_total, | ||
"throughput_thread": mops_thread, | ||
} | ||
|
||
return result_dict | ||
|
||
|
||
def npb_mz_campaign( | ||
name: str = "npb_mz_campaign", | ||
benchmark: Optional[NPBMZBench] = None, | ||
src_dir: Optional[PathType] = None, | ||
results_dir: Optional[PathType] = None, | ||
command_wrappers: Iterable[CommandWrapper] = (), | ||
command_attachments: Iterable[CommandAttachment] = (), | ||
shared_libs: Iterable[SharedLib] = (), | ||
pre_run_hooks: Iterable[PreRunHook] = (), | ||
post_run_hooks: Iterable[PostRunHook] = (), | ||
platform: Platform | None = None, | ||
nb_runs: int = 1, | ||
benchmark_duration_seconds: int = 5, | ||
test_name: Iterable[str] = ("mg",), | ||
t_class: Iterable[str] = ("C",), | ||
cpu_order: Iterable[CpuOrder] = (), | ||
nb_threads: Iterable[Tuple[int, int]] = ((1, 1),), | ||
debug: bool = False, | ||
gdb: bool = False, | ||
enable_data_dir: bool = False, | ||
continuing: bool = False, | ||
constants: Optional[Dict[str, Any]] = None, | ||
pretty: Optional[Dict[str, str]] = None, | ||
) -> CampaignCartesianProduct: | ||
"""Return a cartesian product campaign configured for the Will-it-Scale benchmark.""" | ||
variables = { | ||
"test_name": test_name, | ||
"t_class": t_class, | ||
"cpu_order": cpu_order, | ||
"nb_threads": nb_threads, | ||
} | ||
if pretty is not None: | ||
pretty = {"lock": pretty} | ||
|
||
if src_dir is None: | ||
pass # TODO try some search heuristics | ||
|
||
if benchmark is None: | ||
benchmark = NPBMZBench( | ||
src_dir=src_dir, | ||
command_wrappers=command_wrappers, | ||
command_attachments=command_attachments, | ||
shared_libs=shared_libs, | ||
pre_run_hooks=pre_run_hooks, | ||
post_run_hooks=post_run_hooks, | ||
platform=platform, | ||
) | ||
|
||
return CampaignCartesianProduct( | ||
name=name, | ||
benchmark=benchmark, | ||
nb_runs=nb_runs, | ||
variables=variables, | ||
constants=constants, | ||
debug=debug, | ||
gdb=gdb, | ||
enable_data_dir=enable_data_dir, | ||
continuing=continuing, | ||
benchmark_duration_seconds=benchmark_duration_seconds, | ||
results_dir=results_dir, | ||
pretty=pretty, | ||
) |