Skip to content

Commit 742965e

Browse files
SamuelReederclaude
andauthored
[ALMIOPEN-1856] Simplify dnn-benchmarking engine comparison CLI (#7866)
## Summary This PR replaces the old A/B-specific dnn-benchmarking workflow with an explicit ordered multi-engine path. It keeps engine selection on `--engine`, supports repeated engine IDs as distinct selections, and allows comma-delimited plugin paths that map positionally to the selected engines. ## Risk Assessment Medium risk. This changes CLI behavior and removes legacy A/B flags in a benchmark tool, but the new path is covered by parser, config, execution, reporting, full Python tests, and gfx90a hardware smoke validation. ## Testing Summary - Static Python compile validation covered the changed source and tests. - Full dnn-benchmarking pytest coverage ran on Alola gfx90a with Python 3.12 and ROCm PyTorch, including GPU-marked tests. - Focused regression coverage includes CLI parsing, config validation, ordered engine/plugin selection, same-engine/different-plugin paths, absolute per-engine plugin loading, per-engine setup failures, output shape, internal profiling plugin-path forwarding, and serialization. - Pre-commit ran on all PR-changed files and passed. - Alola gfx90a validation used the installed MIOpen provider from `/opt/rocm/lib/hipdnn_plugins/engines` and ran dnn-benchmarking smoke tests for single-engine, two-engine, and comma-delimited plugin-path flows. ## Testing Checklist - [x] Python compile - `python3 -m compileall -q projects/hipdnn/tools/dnn-benchmarking/src/dnn_benchmarking projects/hipdnn/tools/dnn-benchmarking/tests` - Status: Passed - [x] Pre-commit on PR-changed files - `pre-commit run --files <PR changed files>` - Status: Passed - [x] Full dnn-benchmarking test suite - `workspace/scripts/alola-session run -- 'cd /home/AMD/sareeder/worktrees/rocmlibs-benchmarking-alola-test/projects/hipdnn/tools/dnn-benchmarking && source /workspace/.venv/bin/activate && DNN_BENCH_WORKSPACE=/workspace python -m pytest tests'` - ASICs: gfx90a - Status: Passed, 683 passed, 6 skipped, 8 xfailed - [x] Alola engine listing - `hipdnn_list_engines --plugin-dir /opt/rocm/lib/hipdnn_plugins/engines` - ASICs: gfx90a - Status: Passed, found `MIOPEN_ENGINE` and `MIOPEN_ENGINE_DETERMINISTIC` - [x] Alola single-engine smoke - `python -m dnn_benchmarking --graph graphs/sample_conv_fwd.json --warmup 1 --iters 2 --engine 1563989756945604898 --plugin-path /opt/rocm/lib/hipdnn_plugins/engines` - ASICs: gfx90a - Status: Passed - [x] Alola two-engine smoke - `python -m dnn_benchmarking --graph graphs/sample_conv_fwd.json --warmup 1 --iters 5 --engine 1563989756945604898,-6748551569128940061 --plugin-path /opt/rocm/lib/hipdnn_plugins/engines` - ASICs: gfx90a - Status: Passed - [x] Alola comma-delimited plugin-path smoke - `python -m dnn_benchmarking --graph graphs/sample_conv_fwd.json --warmup 1 --iters 1 --engine 1563989756945604898,-6748551569128940061 --plugin-path /opt/rocm/lib/hipdnn_plugins/engines,/opt/rocm/lib/hipdnn_plugins/engines` - ASICs: gfx90a - Status: Passed - [x] PR CI - GitHub PR checks - Status: Pending Example comparison: ``` Results: engine status plugin_path kernel_mean_ms kernel_median_ms e2e_mean_ms e2e_median_ms --------------------------- ------ ------------------------------------ -------------- ---------------- ----------- ------------- MIOPEN_ENGINE passed /opt/rocm/lib/hipdnn_plugins/engines 0.028 0.027 0.069 0.041 MIOPEN_ENGINE_DETERMINISTIC passed /opt/rocm/lib/hipdnn_plugins/engines 0.026 0.026 0.042 0.037 ``` ## Technical Changes - Removes legacy A/B runner/configuration code and old `--AId`, `--BId`, `--APath`, and `--BPath` flags. - Adds comma-delimited `--plugin-path` parsing with validation for one shared plugin path or one path per selected engine. - Preserves duplicate `--engine` IDs and models each requested run as an ordered engine selection with its own plugin path. - Uses absolute plugin loading mode for per-engine plugin-path setup so plugin comparisons are isolated. - Records per-engine plugin setup and handle creation failures as error rows instead of aborting the suite. - Adds per-engine summary rows with raw kernel/E2E means and medians; percent deltas are intentionally not emitted because they are derivable from the raw columns. - Serializes median timing data and plugin paths for JSON consumers. - Documents `hipdnn_list_engines --plugin-dir <path>` in CLI help so users can discover engine IDs and names. - Raises dnn-benchmarking's Python minimum to 3.12 and uses Python 3.12 tarfile data filters directly for tarball graph extraction. --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 0e6337c commit 742965e

23 files changed

Lines changed: 727 additions & 1251 deletions

projects/hipdnn/tools/dnn-benchmarking/pyproject.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "dnn-benchmarking"
33
version = "0.1.0"
44
description = "Benchmarking and validation tool for hipDNN graphs"
55
readme = "README.md"
6-
requires-python = ">=3.9"
6+
requires-python = ">=3.12"
77
license = {text = "MIT"}
88
authors = [
99
{name = "Advanced Micro Devices, Inc."},
@@ -13,9 +13,6 @@ classifiers = [
1313
"Intended Audience :: Developers",
1414
"License :: OSI Approved :: MIT License",
1515
"Programming Language :: Python :: 3",
16-
"Programming Language :: Python :: 3.9",
17-
"Programming Language :: Python :: 3.10",
18-
"Programming Language :: Python :: 3.11",
1916
"Programming Language :: Python :: 3.12",
2017
"Programming Language :: Python :: 3.13",
2118
"Topic :: Scientific/Engineering",

projects/hipdnn/tools/dnn-benchmarking/src/dnn_benchmarking/cli/ab_runner_cli.py

Lines changed: 0 additions & 172 deletions
This file was deleted.

projects/hipdnn/tools/dnn-benchmarking/src/dnn_benchmarking/cli/internal_profiling.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from ..common.exceptions import GraphLoadError
2626
from ..config.benchmark_config import MetricsConfig, SuiteConfig
27-
from ..execution.suite_runner import _run_single_provider_engine
27+
from ..execution.suite_runner import run_single_provider_engine, set_plugin_path
2828
from ..graph.loader import GraphLoader
2929

3030

@@ -49,9 +49,18 @@ def run_internal_profiling(args: argparse.Namespace) -> int:
4949
)
5050
return 1
5151

52+
plugin_path = None
53+
if args.plugin_path:
54+
if len(args.plugin_path) != 1:
55+
print(
56+
"internal-profiling-run: expected exactly one --plugin-path",
57+
file=sys.stderr,
58+
)
59+
return 1
60+
plugin_path = args.plugin_path[0]
61+
5262
try:
53-
if args.plugin_path is not None:
54-
hipdnn.set_engine_plugin_paths([str(args.plugin_path)])
63+
set_plugin_path(hipdnn, plugin_path)
5564
handle = hipdnn.Handle()
5665
except RuntimeError as e:
5766
print(
@@ -74,11 +83,9 @@ def run_internal_profiling(args: argparse.Namespace) -> int:
7483
# the inner pass; the parent already collected basic metrics on the
7584
# timed pass.
7685
#
77-
# `plugin_path` is forwarded so the child's SuiteConfig matches the
78-
# parent's. hipdnn.set_engine_plugin_paths above is what actually
79-
# loads the plugin today, but any future code that reads
80-
# config.plugin_path from inside _run_single_provider_engine would
81-
# otherwise silently see None in the child.
86+
# `plugin_path` is forwarded so the child SuiteConfig matches the
87+
# parent's selected engine/plugin row. The outer suite runner passes
88+
# exactly one plugin path for this single-engine subprocess.
8289
suite_config = SuiteConfig(
8390
warmup_iters=args.warmup,
8491
benchmark_iters=args.iters,
@@ -88,11 +95,11 @@ def run_internal_profiling(args: argparse.Namespace) -> int:
8895
reference_provider="none",
8996
verbose=False,
9097
metrics=MetricsConfig(tier="off"),
91-
plugin_path=args.plugin_path,
98+
plugin_paths=[plugin_path] if plugin_path is not None else None,
9299
)
93100

94101
try:
95-
result = _run_single_provider_engine(
102+
result = run_single_provider_engine(
96103
graph_path=graph_path,
97104
graph_json_str=json.dumps(graph_json),
98105
graph_name=graph_json.get("name", graph_path.stem),
@@ -101,6 +108,7 @@ def run_internal_profiling(args: argparse.Namespace) -> int:
101108
handle=handle,
102109
provider="profiling-inner",
103110
engine_id=engine_id,
111+
plugin_path=plugin_path,
104112
ref_provider=None,
105113
validation_requested=False,
106114
graph_json=graph_json,

projects/hipdnn/tools/dnn-benchmarking/src/dnn_benchmarking/cli/main.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
from ..common.exceptions import GraphLoadError
2828
from ..reporting.reporter import Reporter
29-
from .ab_runner_cli import run_ab_cli
3029
from .internal_profiling import run_internal_profiling
3130
from .parser import create_parser
3231
from .pytorch_runner_cli import run_pytorch_cli
@@ -82,15 +81,7 @@ def main() -> int:
8281
return 1
8382

8483
try:
85-
if args.AId is not None or args.BId is not None:
86-
if len(resolved_files) > 1:
87-
reporter.print_error(
88-
"A/B testing requires a single graph file, not a glob pattern"
89-
)
90-
return 1
91-
return run_ab_cli(args, Path(resolved_files[0]), reporter)
92-
93-
elif args.backend == "pytorch":
84+
if args.backend == "pytorch":
9485
if len(resolved_files) > 1:
9586
reporter.print_error(
9687
"Suite mode is not supported with --backend pytorch"

0 commit comments

Comments
 (0)