Files
TheRock/tests/extended_tests/benchmark/scripts/test_rccl_benchmark.py
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

199 lines
6.8 KiB
Python

# Copyright Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
"""
RCCL Benchmark Test
Runs RCCL collective communication benchmarks, collects results, and uploads to results API.
"""
import json
import re
import sys
from pathlib import Path
from typing import Dict, List, Tuple, Any
from prettytable import PrettyTable
sys.path.insert(0, str(Path(__file__).resolve().parents[2])) # For extended_tests/utils
sys.path.insert(0, str(Path(__file__).parent)) # For benchmark_base
from benchmark_base import BenchmarkBase, run_benchmark_main
from github_actions_api import get_visible_gpu_count
from utils.logger import log
class RCCLBenchmark(BenchmarkBase):
"""RCCL benchmark test."""
def __init__(self):
super().__init__(benchmark_name="rccl", display_name="RCCL")
self.log_file = self.script_dir / "rccl_bench.log"
self.ngpu = get_visible_gpu_count(therock_bin_dir=self.therock_bin_dir)
# Validate OpenMPI is available (from base class)
self._validate_openmpi()
def run_benchmarks(self) -> None:
"""Run RCCL benchmarks and save output to log file."""
# Load benchmark configuration
config_file = self.script_dir.parent / "configs" / "rccl.json"
with open(config_file, "r") as f:
config_data = json.load(f)
# Get configuration
benchmarks = config_data.get("benchmarks")
data_types = config_data.get("data_types")
min_size = config_data.get("min_size")
max_size = config_data.get("max_size")
step_factor = config_data.get("step_factor")
warmup_iters = config_data.get("warmup_iters")
test_iters = config_data.get("test_iters")
operations = config_data.get("operations")
# Apply GPU-specific overrides
if self.amdgpu_families:
overrides = config_data.get("gpu_overrides", {}).get(
self.amdgpu_families, {}
)
max_size = overrides.get("max_size", max_size)
log.info("Running RCCL Benchmarks")
with open(self.log_file, "w+") as f:
for benchmark in benchmarks:
bench_binary = Path(self.therock_bin_dir) / benchmark
if not bench_binary.exists():
log.warning(f"Benchmark binary not found: {bench_binary}")
continue
for dtype in data_types:
for operation in operations:
# Write section header to log file for parsing
section_header = f"\n{'='*80}\nBenchmark: {benchmark}\nDataType: {dtype}\nOperation: {operation}\n\n"
f.write(section_header)
# Build environment variables
env_vars = {"HSA_FORCE_FINE_GRAIN_PCIE": "1"}
# Construct benchmark command with MPI
cmd = [
"mpirun",
"--np",
"1",
str(bench_binary),
"--minbytes",
min_size,
"--maxbytes",
max_size,
"--stepfactor",
step_factor,
"--ngpus",
str(self.ngpu),
"--op",
operation,
"--datatype",
dtype,
"--iters",
test_iters,
"--warmup_iters",
warmup_iters,
]
self.execute_command(cmd, f, env=env_vars)
log.info("RCCL benchmarks execution complete")
def parse_results(self) -> Tuple[List[Dict[str, Any]], PrettyTable]:
"""Parse benchmark results from log file.
Returns:
tuple: (test_results list, PrettyTable object)
"""
# Regex patterns for parsing
pattern_benchmark = re.compile(r"Benchmark:\s*(\S+)")
pattern_dtype = re.compile(r"DataType:\s*(\S+)")
pattern_operation = re.compile(r"Operation:\s*(\S+)")
pattern_bandwidth = re.compile(r"#\s+Avg bus bandwidth\s+:\s+(\d+\.\d+)")
log.info("Parsing Results")
# Setup table
field_names = [
"TestName",
"SubTests",
"nGPU",
"Result",
"Scores",
"Units",
"Flag",
]
table = PrettyTable(field_names)
test_results = []
try:
with open(self.log_file, "r") as log_fp:
content = log_fp.read()
# Split by benchmark sections
sections = content.split("=" * 80)
for section in sections:
if not section.strip():
continue
# Extract metadata
benchmark_match = re.search(pattern_benchmark, section)
dtype_match = re.search(pattern_dtype, section)
operation_match = re.search(pattern_operation, section)
bandwidth_match = re.search(pattern_bandwidth, section)
if not (benchmark_match and dtype_match and bandwidth_match):
continue
benchmark_name = benchmark_match.group(1)
dtype = dtype_match.group(1)
operation = operation_match.group(1) if operation_match else "sum"
bandwidth = float(bandwidth_match.group(1))
# Determine status
status = "PASS" if bandwidth > 0 else "FAIL"
# Build subtest name
subtest_name = f"{benchmark_name}_{dtype}_{operation}"
# Add to table and results
table.add_row(
[
self.benchmark_name,
subtest_name,
self.ngpu,
status,
bandwidth,
"GB/s",
"H",
]
)
test_results.append(
self.create_test_result(
self.benchmark_name,
subtest_name,
status,
bandwidth,
"GB/s",
"H",
ngpu=self.ngpu,
dtype=dtype,
operation=operation,
)
)
except OSError as e:
raise ValueError(f"IO Error in Score Extractor: {e}")
return test_results, table
if __name__ == "__main__":
run_benchmark_main(RCCLBenchmark())