Skip to content

[UR][Benchmarks] Support for Unitrace for all benchmarks #19320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: sycl
Choose a base branch
from
48 changes: 38 additions & 10 deletions devops/scripts/benchmarks/benches/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from dataclasses import dataclass
import os
import shutil
import subprocess
Expand All @@ -12,6 +11,7 @@
from options import options
from utils.utils import download, run
from abc import ABC, abstractmethod
from utils.unitrace import get_unitrace

benchmark_tags = [
BenchmarkTag("SYCL", "Benchmark uses SYCL runtime"),
Expand Down Expand Up @@ -61,6 +61,12 @@ def enabled(self) -> bool:
By default, it returns True, but can be overridden to disable a benchmark."""
return True

def traceable(self) -> bool:
"""Returns whether this benchmark should be traced by Unitrace.
By default, it returns True, but can be overridden to disable tracing for a benchmark.
"""
return True

@abstractmethod
def setup(self):
pass
Expand All @@ -70,7 +76,7 @@ def teardown(self):
pass

@abstractmethod
def run(self, env_vars) -> list[Result]:
def run(self, env_vars: dict, run_unitrace: bool = False) -> list[Result]:
pass

@staticmethod
Expand All @@ -86,7 +92,14 @@ def get_adapter_full_path():
), f"could not find adapter file {adapter_path} (and in similar lib paths)"

def run_bench(
Copy link
Preview

Copilot AI Jul 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Avoid mutable default arguments like extra_unitrace_opt=[]; use None and set to an empty list inside the function to prevent unintended sharing.

Copilot uses AI. Check for mistakes.

self, command, env_vars, ld_library=[], add_sycl=True, use_stdout=True
self,
command,
env_vars,
ld_library=[],
add_sycl=True,
use_stdout=True,
run_unitrace=False,
extra_unitrace_opt=None,
):
env_vars = env_vars.copy()
if options.ur is not None:
Expand All @@ -99,13 +112,28 @@ def run_bench(
ld_libraries = options.extra_ld_libraries.copy()
ld_libraries.extend(ld_library)

result = run(
command=command,
env_vars=env_vars,
add_sycl=add_sycl,
cwd=options.benchmark_cwd,
ld_library=ld_libraries,
)
if self.traceable() and run_unitrace:
if extra_unitrace_opt is None:
extra_unitrace_opt = []
unitrace_output, command = get_unitrace().setup(
self.name(), command, extra_unitrace_opt
)

try:
result = run(
command=command,
env_vars=env_vars,
add_sycl=add_sycl,
cwd=options.benchmark_cwd,
ld_library=ld_libraries,
)
except subprocess.CalledProcessError:
if run_unitrace:
get_unitrace().cleanup(options.benchmark_cwd, unitrace_output)
raise

if self.traceable() and run_unitrace:
get_unitrace().handle_output(unitrace_output)

if use_stdout:
return result.stdout.decode()
Expand Down
4 changes: 3 additions & 1 deletion devops/scripts/benchmarks/benches/benchdnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def setup(self):
if not self.bench_bin.exists():
raise FileNotFoundError(f"Benchmark binary not found: {self.bench_bin}")

def run(self, env_vars):
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
command = [
str(self.bench_bin),
*self.bench_args.split(),
Expand All @@ -151,6 +151,8 @@ def run(self, env_vars):
add_sycl=True,
ld_library=ld_library,
use_stdout=True,
run_unitrace=run_unitrace,
extra_unitrace_opt=["--chrome-dnn-logging"],
)
result_value = self._extract_time(output)

Expand Down
1 change: 1 addition & 0 deletions devops/scripts/benchmarks/benches/benchdnn_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"graph",
"sdpa-plain-f16",
"--reset --dt=f16 --case=complex_fusion/mha/sdpa-plain-implicit-causal-mask-fp32-bs1.json",
False, # Do not run SYCL graph for this benchmark
],
[
"graph",
Expand Down
29 changes: 27 additions & 2 deletions devops/scripts/benchmarks/benches/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,24 @@ def parse_unit_type(compute_unit):


class ComputeBenchmark(Benchmark):

# List of benchmarks that should not be traced by Unitrace
not_traceable = [
# timeouts with v2 adapter
"graph_api_benchmark_l0 SubmitGraph numKernels:4 ioq 0 measureCompletion 0",
"graph_api_benchmark_l0 SubmitGraph numKernels:4 ioq 0 measureCompletion 1",
"graph_api_benchmark_l0 SubmitGraph numKernels:10 ioq 0 measureCompletion 0",
"graph_api_benchmark_l0 SubmitGraph numKernels:10 ioq 0 measureCompletion 1",
"graph_api_benchmark_l0 SubmitGraph numKernels:32 ioq 0 measureCompletion 0",
"graph_api_benchmark_l0 SubmitGraph numKernels:32 ioq 0 measureCompletion 1",
"graph_api_benchmark_l0 SubmitGraph numKernels:4 ioq 1 measureCompletion 0",
"graph_api_benchmark_l0 SubmitGraph numKernels:4 ioq 1 measureCompletion 1",
"graph_api_benchmark_l0 SubmitGraph numKernels:32 ioq 1 measureCompletion 0",
"graph_api_benchmark_l0 SubmitGraph numKernels:32 ioq 1 measureCompletion 1",
"graph_api_benchmark_ur SubmitGraph numKernels:10 ioq 0 measureCompletion 0",
"graph_api_benchmark_ur SubmitGraph numKernels:10 ioq 0 measureCompletion 1",
]

def __init__(self, bench, name, test, runtime: RUNTIMES = None):
super().__init__(bench.directory, bench)
self.bench = bench
Expand Down Expand Up @@ -273,6 +291,9 @@ def enabled(self) -> bool:
# Check if the specific runtime is enabled (or no specific runtime required)
return self.runtime is None or self.runtime in self.enabled_runtimes()

def traceable(self) -> bool:
return self.bench_name not in self.not_traceable

def bin_args(self) -> list[str]:
return []

Expand All @@ -290,7 +311,7 @@ def explicit_group(self):
def description(self) -> str:
return ""

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
command = [
f"{self.benchmark_bin}",
f"--test={self.test}",
Expand All @@ -301,7 +322,11 @@ def run(self, env_vars) -> list[Result]:
command += self.bin_args()
env_vars.update(self.extra_env_vars())

result = self.run_bench(command, env_vars)
result = self.run_bench(
command,
env_vars,
run_unitrace=run_unitrace,
)
parsed_results = self.parse_output(result)
ret = []
for label, median, stddev, unit in parsed_results:
Expand Down
3 changes: 2 additions & 1 deletion devops/scripts/benchmarks/benches/gromacs.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def setup(self):
ld_library=self.suite.oneapi.ld_libraries(),
)

def run(self, env_vars):
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
model_dir = self.grappa_dir / self.model

env_vars.update({"SYCL_CACHE_PERSISTENT": "1"})
Expand Down Expand Up @@ -202,6 +202,7 @@ def run(self, env_vars):
add_sycl=True,
use_stdout=False,
ld_library=self.suite.oneapi.ld_libraries(),
run_unitrace=run_unitrace,
)

if not self._validate_correctness(options.benchmark_cwd + "/md.log"):
Expand Down
7 changes: 5 additions & 2 deletions devops/scripts/benchmarks/benches/llamacpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def get_tags(self):
def lower_is_better(self):
return False

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
command = [
f"{self.benchmark_bin}",
"--output",
Expand All @@ -141,7 +141,10 @@ def run(self, env_vars) -> list[Result]:
]

result = self.run_bench(
command, env_vars, ld_library=self.bench.oneapi.ld_libraries()
command,
env_vars,
ld_library=self.bench.oneapi.ld_libraries(),
run_unitrace=run_unitrace,
)
parsed = self.parse_output(result)
results = []
Expand Down
8 changes: 6 additions & 2 deletions devops/scripts/benchmarks/benches/syclbench.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def setup(self):
self.directory, "sycl-bench-build", self.bench_name
)

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
self.outputfile = os.path.join(self.bench.directory, self.test + ".csv")

command = [
Expand All @@ -151,7 +151,11 @@ def run(self, env_vars) -> list[Result]:
env_vars.update(self.extra_env_vars())

# no output to stdout, all in outputfile
self.run_bench(command, env_vars)
self.run_bench(
command,
env_vars,
run_unitrace=run_unitrace,
)

with open(self.outputfile, "r") as f:
reader = csv.reader(f)
Expand Down
2 changes: 1 addition & 1 deletion devops/scripts/benchmarks/benches/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def notes(self) -> str:
def unstable(self) -> str:
return self.unstable_text

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
random_value = self.value + random.uniform(-1 * (self.diff), self.diff)
return [
Result(
Expand Down
8 changes: 6 additions & 2 deletions devops/scripts/benchmarks/benches/umf.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def get_names_of_benchmarks_to_be_run(self, command, env_vars):

return all_names

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
command = [f"{self.benchmark_bin}"]

all_names = self.get_names_of_benchmarks_to_be_run(command, env_vars)
Expand All @@ -151,7 +151,11 @@ def run(self, env_vars) -> list[Result]:
specific_benchmark = command + ["--benchmark_filter=^" + name + "$"]

result = self.run_bench(
specific_benchmark, env_vars, add_sycl=False, ld_library=[self.umf_lib]
specific_benchmark,
env_vars,
add_sycl=False,
ld_library=[self.umf_lib],
run_unitrace=run_unitrace,
)

parsed = self.parse_output(result)
Expand Down
11 changes: 8 additions & 3 deletions devops/scripts/benchmarks/benches/velocity.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,20 @@ def description(self) -> str:
def get_tags(self):
return ["SYCL", "application"]

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
env_vars.update(self.extra_env_vars())

command = [
f"{self.benchmark_bin}",
]
command += self.bin_args()

result = self.run_bench(command, env_vars, ld_library=self.ld_libraries())
result = self.run_bench(
command,
env_vars,
ld_library=self.ld_libraries(),
run_unitrace=run_unitrace,
)

return [
Result(
Expand Down Expand Up @@ -282,7 +287,7 @@ class QuickSilver(VelocityBase):
def __init__(self, vb: VelocityBench):
super().__init__("QuickSilver", "qs", vb, "MMS/CTT")

def run(self, env_vars) -> list[Result]:
def run(self, env_vars, run_unitrace: bool = False) -> list[Result]:
# TODO: fix the crash in QuickSilver when UR_L0_USE_IMMEDIATE_COMMANDLISTS=0
if (
"UR_L0_USE_IMMEDIATE_COMMANDLISTS" in env_vars
Expand Down
24 changes: 15 additions & 9 deletions devops/scripts/benchmarks/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from utils.validate import Validate
from utils.logger import log
from utils.detect_versions import DetectVersion
from utils.unitrace import get_unitrace


class BenchmarkHistory:
Expand Down Expand Up @@ -150,23 +151,28 @@ def git_info_from_path(path: Path) -> (str, str):
compute_runtime=compute_runtime,
)

def save(self, save_name, results: list[Result], to_file=True):
def save(self, save_name, results: list[Result]):
benchmark_data = self.create_run(save_name, results)
self.runs.append(benchmark_data)

if not to_file:
if options.save_name is None:
return

serialized = benchmark_data.to_json()
serialized = benchmark_data.to_json() # type: ignore
results_dir = Path(os.path.join(self.dir, "results"))
os.makedirs(results_dir, exist_ok=True)

# Use formatted timestamp for the filename
timestamp = (
datetime.now(tz=timezone.utc).strftime("%Y%m%d_%H%M%S")
if options.timestamp_override is None
else options.timestamp_override
)
if get_unitrace() is not None:
timestamp = get_unitrace().timestamp # type: ignore
elif options.timestamp_override is not None:
timestamp = options.timestamp_override
else:
timestamp = (
datetime.now(tz=timezone.utc).strftime("%Y%m%d_%H%M%S")
if options.timestamp_override is None
else options.timestamp_override
)

file_path = Path(os.path.join(results_dir, f"{save_name}_{timestamp}.json"))
with file_path.open("w") as file:
json.dump(serialized, file, indent=4)
Expand Down
1 change: 0 additions & 1 deletion devops/scripts/benchmarks/html/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@
benchmarkRuns = [];

defaultCompareNames = [];

Loading
Loading