CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
284 lines
8.6 KiB
Python
284 lines
8.6 KiB
Python
# Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
"""Run a benchmark suite."""
|
|
|
|
import argparse
|
|
import datetime
|
|
import importlib.util
|
|
import os
|
|
import subprocess
|
|
from dataclasses import fields
|
|
from itertools import chain
|
|
from pathlib import Path
|
|
|
|
import pandas as pd
|
|
import rrperf
|
|
import rrperf.dump_csv
|
|
import yaml
|
|
|
|
|
|
def submit_directory(suite: str, wrkdir: Path, ptsdir: Path) -> None:
|
|
"""Consolidate performance data and submit it to SOMEWHERE.
|
|
|
|
Performance data is read from .yaml files in the work directory
|
|
for the given suite. Consolidated data is written to a SOMEWHERE
|
|
directory and submitted.
|
|
"""
|
|
results = []
|
|
for jpath in wrkdir.glob(f"{suite}-*.yaml"):
|
|
results.extend(yaml.load(jpath.read_text()))
|
|
df = pd.DataFrame(results)
|
|
df.to_csv(f"{str(ptsdir)}/{suite}-benchmark.csv", index=False)
|
|
# TODO: add call to SOMEWHERE to submit
|
|
|
|
|
|
def from_token(token: str):
|
|
yield rrperf.problems.upcast_to_run(eval(token, rrperf.problems.__dict__))
|
|
|
|
|
|
def run_problems(
|
|
generator,
|
|
build_dir: Path,
|
|
work_dir: Path,
|
|
env: dict[str, str],
|
|
id_filter: list[str],
|
|
l2: bool,
|
|
) -> bool:
|
|
|
|
SOLUTION_NOT_SUPPORTED_ON_ARCH = 3
|
|
|
|
already_run = set()
|
|
result = True
|
|
failed = []
|
|
|
|
for i, problem in enumerate(generator):
|
|
if id_filter is not None and not any(
|
|
problem.id.startswith(filt) for filt in id_filter
|
|
):
|
|
continue
|
|
|
|
if problem in already_run:
|
|
continue
|
|
|
|
id = getattr(problem, "id", None)
|
|
yaml = (work_dir / f"{problem.group}-{i:06d}.yaml").resolve()
|
|
problem.set_output(yaml)
|
|
cmd = problem.command()
|
|
log = yaml.with_suffix(".log")
|
|
rr_env = {k: str(v) for k, v in env.items() if k.startswith("ROC")}
|
|
rr_env_str = " ".join([f"{k}={v}" for k, v in rr_env.items()])
|
|
|
|
if l2:
|
|
counters = str(yaml.resolve().parent / yaml.stem)
|
|
cmd = [
|
|
"rocprofv3",
|
|
"--pmc=TCC_HIT,TCC_MISS",
|
|
"--output-file=" + counters,
|
|
"--output-format=json",
|
|
"--",
|
|
] + cmd
|
|
|
|
with log.open("w") as f:
|
|
scmd = " ".join(cmd)
|
|
print(f"# env: {rr_env_str}", file=f, flush=True)
|
|
print(f"# command: {scmd}", file=f, flush=True)
|
|
print(f"# token: {repr(problem)}", file=f, flush=True)
|
|
print("running:")
|
|
print(f" id: {id}")
|
|
print(f" command: {scmd}")
|
|
print(f" wrkdir: {work_dir.resolve()}")
|
|
print(f" log: {log.resolve()}")
|
|
p = subprocess.run(cmd, stdout=f, cwd=build_dir, env=env, check=False)
|
|
status = None
|
|
if p.returncode == 0:
|
|
status = "ok"
|
|
elif p.returncode == SOLUTION_NOT_SUPPORTED_ON_ARCH:
|
|
status = "skipped (not supported on " + rrperf.utils.rocm_gfx() + ")"
|
|
else:
|
|
status = "error"
|
|
result = False
|
|
failed.append((i, problem))
|
|
print(f" status: {status}", flush=True)
|
|
|
|
already_run.add(problem)
|
|
|
|
if len(failed) > 0:
|
|
ids = [getattr(problem, "id", None) for i, problem in failed]
|
|
print("")
|
|
print(f"Failed {len(failed)} problems ids:")
|
|
print(" ".join([str(id) for id in ids]))
|
|
print("")
|
|
print(f"Failed {len(failed)} problems:")
|
|
for i, problem in failed:
|
|
cmd = list(map(str, problem.command()))
|
|
print(f"{i}: {' '.join(cmd)}")
|
|
|
|
return result
|
|
|
|
|
|
def generate_missing_attr_value(run, attr):
|
|
"""Generate value for an option missing in previous rrperf version."""
|
|
match attr:
|
|
case "workgroupMapping":
|
|
wgm_dim = getattr(run, "workgroupMappingDim")
|
|
wgm_value = getattr(run, "workgroupMappingValue")
|
|
return (wgm_dim, wgm_value)
|
|
case "matchMemoryAccess":
|
|
return True
|
|
case "unroll_x" | "unroll_y":
|
|
return 0
|
|
case "storeLDS_D":
|
|
store = getattr(run, "store")
|
|
return "LDS" in store
|
|
case "streamK":
|
|
# Old version used bool, new version uses str
|
|
streamK = getattr(run, "streamK", "None")
|
|
if isinstance(streamK, str):
|
|
return streamK != "None"
|
|
return streamK
|
|
case "streamKTwoTile":
|
|
streamK = getattr(run, "streamK", "None")
|
|
return streamK == "TwoTile"
|
|
case "streamKTwoTileDPFirst":
|
|
streamK = getattr(run, "streamK", "None")
|
|
return streamK == "TwoTileDPFirst"
|
|
case _:
|
|
raise RuntimeError(
|
|
f"Cannot handle attribute missing in previous rrperf version: {attr}"
|
|
)
|
|
|
|
|
|
def backcast(generator, build_dir):
|
|
"""Reconstruct run objects from `generator` into run objects from previous rrperf version."""
|
|
pdef = build_dir.parent / "scripts" / "lib" / "rrperf" / "problems.py"
|
|
spec = importlib.util.spec_from_file_location("problems", str(pdef))
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
for run in generator:
|
|
className = run.__class__.__name__
|
|
backClass = getattr(module, className, None)
|
|
if backClass is not None:
|
|
backObj = backClass(
|
|
**{
|
|
f.name: (
|
|
getattr(run, f.name)
|
|
if hasattr(run, f.name)
|
|
else generate_missing_attr_value(run, f.name)
|
|
)
|
|
for f in fields(backClass)
|
|
}
|
|
)
|
|
yield backObj
|
|
|
|
|
|
def get_args(parser: argparse.ArgumentParser):
|
|
common_args = [
|
|
rrperf.args.rundir,
|
|
rrperf.args.suite,
|
|
rrperf.args.id_filter,
|
|
]
|
|
for arg in common_args:
|
|
arg(parser)
|
|
|
|
parser.add_argument(
|
|
"--submit",
|
|
help="Submit results to SOMEWHERE.",
|
|
action="store_true",
|
|
default=False,
|
|
)
|
|
parser.add_argument("--token", help="Benchmark token to run.")
|
|
parser.add_argument(
|
|
"--amd_smi",
|
|
"--rocm_smi",
|
|
default="amd-smi",
|
|
help="Location of amd-smi (--rocm_smi is deprecated).",
|
|
)
|
|
parser.add_argument(
|
|
"--l2",
|
|
action="store_true",
|
|
help="Collect L2 performance counters (TCC_HIT and TCC_MISS).",
|
|
)
|
|
parser.add_argument(
|
|
"--dump_csv",
|
|
help="Dump benchmark CSV with included headers.",
|
|
action="store_true",
|
|
default=False,
|
|
)
|
|
|
|
|
|
def run(args):
|
|
"""Run benchmarks!"""
|
|
run_cli(**args.__dict__)
|
|
|
|
|
|
def run_cli( # noqa: C901
|
|
token: str = None,
|
|
suite: str = None,
|
|
submit: bool = False,
|
|
id_filter: list[str] = None,
|
|
rundir: str = None,
|
|
build_dir: str = None,
|
|
amd_smi: str = "amd-smi",
|
|
recast: bool = False,
|
|
l2: bool = False,
|
|
**kwargs,
|
|
) -> tuple[bool, Path]:
|
|
"""Run benchmarks!
|
|
|
|
Implements the CLI 'run' subcommand.
|
|
"""
|
|
|
|
if suite is None and token is None:
|
|
if rrperf.utils.rocm_gfx().startswith("gfx120"):
|
|
suite = "all_gfx120X"
|
|
else:
|
|
suite = "all"
|
|
|
|
generator = rrperf.utils.empty()
|
|
if suite is not None:
|
|
generator = chain(generator, rrperf.utils.load_suite(suite))
|
|
if token is not None:
|
|
generator = chain(generator, from_token(token))
|
|
if recast:
|
|
generator = backcast(generator, build_dir)
|
|
|
|
if build_dir is None:
|
|
build_dir = rrperf.utils.get_build_dir()
|
|
else:
|
|
build_dir = Path(build_dir)
|
|
|
|
env = dict(os.environ)
|
|
env["ROCROLLER_ENFORCE_GRAPH_CONSTRAINTS"] = "1"
|
|
env["ROCROLLER_AUDIT_CONTROL_TRACERS"] = "1"
|
|
|
|
rundir = rrperf.utils.get_work_dir(rundir, build_dir)
|
|
rundir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# pts.create_git_info(str(wrkdir / "git-commit.txt"))
|
|
git_commit = rundir / "git-commit.txt"
|
|
try:
|
|
hash = rrperf.git.full_hash(build_dir)
|
|
git_commit.write_text(f"{hash}\n")
|
|
except Exception:
|
|
git_commit.write_text("NO_COMMIT\n")
|
|
# pts.create_specs_info(str(wrkdir / "machine-specs.txt"))
|
|
machine_specs = rundir / "machine-specs.txt"
|
|
machine_specs.write_text(str(rrperf.specs.get_machine_specs(0, amd_smi)) + "\n")
|
|
|
|
timestamp = rundir / "timestamp.txt"
|
|
timestamp.write_text(str(datetime.datetime.now().timestamp()) + "\n")
|
|
|
|
result = run_problems(generator, build_dir, rundir, env, id_filter, l2)
|
|
|
|
if submit:
|
|
ptsdir = rundir / "rocRoller"
|
|
ptsdir.mkdir(parents=True)
|
|
# XXX if running single token, suite might be None
|
|
submit_directory(suite, rundir, ptsdir)
|
|
|
|
if kwargs.get("dump_csv", False):
|
|
rrperf.dump_csv.dump_csv(suite, rundir)
|
|
|
|
return result, rundir
|