diff --git a/docs/compatibility.rst b/docs/compatibility.rst index 3d672bf686..8e38c5b04c 100644 --- a/docs/compatibility.rst +++ b/docs/compatibility.rst @@ -65,24 +65,67 @@ The following table lists the validated Hyperloom version and component combinat .. role:: version-start -.. table:: - :widths: 6 27 10 10 14 30 3 - :align: left +.. list-table:: + :header-rows: 1 + :widths: 15 30 45 35 20 15 5 :class: compat-matrix format-big-table -+-------------------+---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ -| Hyperloom version | Component | GPU | ROCm version | Ubuntu | Python | GitHub | -+===================+===========================+========================+============================+===============+=============+=============================+ -| 1.0.0a3 | `TraceLens 0.1.0`_ | Hardware-agnostic | No dependency | OS-independent| >= 3.6 | |tracelens-github| | -+ +---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ -| | `GEAK 4.0.0`_ | MI300X, MI325X, MI355X | 6.4.x, 7.0.x, 7.1.x, 7.2.x | 22.04, 24.04 | 3.8, 3.12 | |geak-github| | -+ +---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ -| | `IntelliKit 0.1.0`_ | MI300X, MI325X, MI355X | 7.2.x | 22.04, 24.04 | >= 3.10 | |intellikit-github| | -+ +---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ -| | `AgentKernelArena 0.2.0`_ | MI300X, MI325X, MI355X | 7.2.x | 22.04, 24.04 | >= 3.10 | |agent-kernel-arena-github| | -+ +---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ -| | `Magpie 0.2.0`_ | MI300X, MI325X, MI355X | 7.0.x, 7.1.x, 7.2.x | 22.04, 24.04 | >= 3.10 | |magpie-github| | -+-------------------+---------------------------+------------------------+----------------------------+---------------+-------------+-----------------------------+ + * - Hyperloom version + - Component + - GPU + - ROCm version + - Ubuntu + - Python + - GitHub + * - 1.0.0a1 + - `TraceLens 0.1.0`_ + - Hardware-agnostic + - No dependency + - OS-independent + - >= 3.6 + - |tracelens-github| + * - 1.0.0a2 + - `TraceLens 0.1.0`_ + - Hardware-agnostic + - No dependency + - OS-independent + - >= 3.6 + - |tracelens-github| + * - 1.0.0a3 + - `TraceLens 0.1.0`_ + - Hardware-agnostic + - No dependency + - OS-independent + - >= 3.6 + - |tracelens-github| + * - 1.0.0a2 + - `GEAK 4.0.0`_ + - MI300X, MI325X, MI355X, RX 9070 XT, RX 9070, RX 9060 XT, R9000 + - 6.4.x, 7.0.x, 7.1.x, 7.2.x + - 22.04, 24.04 + - 3.8, 3.12 + - |geak-github| + * - 1.0.0a2 + - `IntelliKit 0.1.0`_ + - MI300X, MI325X, MI355X + - 7.2.x + - 22.04, 24.04 + - >= 3.10 + - |intellikit-github| + * - 1.0.0a2 + - `AgentKernelArena 0.2.0`_ + - MI300X, MI325X, MI355X + - 7.2.x + - 22.04, 24.04 + - >= 3.10 + - |agent-kernel-arena-github| + * - 1.0.0a2 + - `Magpie 0.2.0`_ + - MI300X, MI325X, MI355X, RX 9070 XT, RX 9070, RX 9060 XT, R9000 + - 7.0.x, 7.1.x, 7.2.x (Linux), 7.3+ (Windows for RDNA4) + - 22.04, 24.04, Win 11 + - >= 3.10 + - |magpie-github| .. _TraceLens 0.1.0: https://rocm.docs.amd.com/projects/tracelens/en/docs-0.1.0/ .. _GEAK 4.0.0: https://rocm.docs.amd.com/projects/geak/en/docs-4.0.0/ @@ -196,3 +239,4 @@ rocm720, prefer ``docker`` mode with These are recommended defaults, not hard pins. Framework and ROCm versions are overridable via env (``SGLANG_REF``, ``SGLANG_ROCM_EXTRA``, ``VLLM_VERSION``, ``VLLM_ROCM_VARIANT``) for hosts that need a different pinned stack. + diff --git a/src/hyperloom/inference_optimizer/cli/parser.py b/src/hyperloom/inference_optimizer/cli/parser.py index 735eed1f03..f74ca2631c 100644 --- a/src/hyperloom/inference_optimizer/cli/parser.py +++ b/src/hyperloom/inference_optimizer/cli/parser.py @@ -272,7 +272,7 @@ def _build_parser() -> argparse.ArgumentParser: opt.add_argument( "--gpu-type", type=str.lower, - choices=["mi300x", "mi308x", "mi325x", "mi355x"], + choices=["mi300x", "mi308x", "mi325x", "mi355x", "rx9070xt", "rx9070", "rx9060xt", "r9000"], default=None, help="Hint for the real target GPU. The rocm-smi probe always " "wins when both are present and disagree; a WARN is " diff --git a/src/hyperloom/inference_optimizer/gpu_types.py b/src/hyperloom/inference_optimizer/gpu_types.py index 35c62e0102..cff9d4f1b6 100644 --- a/src/hyperloom/inference_optimizer/gpu_types.py +++ b/src/hyperloom/inference_optimizer/gpu_types.py @@ -6,15 +6,21 @@ from __future__ import annotations import os +import sys -_AMD_GPU_TYPES = frozenset({"mi300x", "mi308x", "mi325x", "mi355x"}) +_AMD_GPU_TYPES = frozenset({ + "mi300x", "mi308x", "mi325x", "mi355x", + "rx9070xt", "rx9070", "rx9060xt", "r9000" +}) _GFX_TO_RUNNER: dict[str, str] = { - # gfx arch -> Magpie runner label, so launchers and runtime materializers - # agree on the selected benchmark script. "gfx942": "mi300x", "gfx950": "mi355x", + "gfx1201": "rx9070xt", + "gfx1203": "r9000", + "gfx1206": "rx9060xt", + "gfx1207": "rx9070", } _AMD_GPU_DISPATCH_IDENTITIES: dict[str, tuple[str, int]] = { @@ -22,13 +28,30 @@ "mi308x": ("gfx942", 304), "mi325x": ("gfx942", 304), "mi355x": ("gfx950", 256), + "rx9070xt": ("gfx1201", 64), + "r9000": ("gfx1203", 64), + "rx9070": ("gfx1207", 56), + "rx9060xt": ("gfx1206", 32), } +# GPU types for which Magpie ships a benchmark runner script (sglang_.sh). +# MI308X/MI325X are mapped to the MI300X runner by _gpu_runner_type(); every +# RDNA4 SKU resolves to itself. The matching rx9xxx runner scripts are shipped +# by the AMD-AGI/Magpie package (see docs/components/magpie.md). +_SHIPPED_MAGPIE_RUNNERS: frozenset[str] = frozenset({ + "mi300x", "mi355x", + "rx9070xt", "rx9070", "rx9060xt", "r9000", +}) + def _gpu_runner_type(gpu_type: str) -> str: - """Return the Magpie runner label for a resolved real GPU type.""" + """Return the Magpie runner label for a resolved real GPU type. + + MI308X/MI325X collapse to the MI300X runner (shipped as + ``sglang_mi300x.sh``); every other supported AMD type resolves to itself. + """ normalized = str(gpu_type or "").strip().lower() - if normalized in ("mi325x", "mi308x"): + if normalized in ("mi300x", "mi308x", "mi325x"): return "mi300x" return normalized @@ -51,22 +74,44 @@ def _resolve_gpu_type( def _autodetect_gpu_type() -> str | None: - """Return mi300x|mi308x|mi325x|mi355x or None if undetectable.""" + """Return mi300x|mi308x|mi325x|mi355x|rx9070xt|rx9070|rx9060xt|r9000 or None.""" import subprocess try: - out = subprocess.run( - ["rocm-smi", "--showproductname"], - capture_output=True, - text=True, - timeout=5, - ).stdout.upper() - for tag in ("MI355X", "MI325X", "MI308X", "MI300X"): - if tag in out: - return tag.lower() + if sys.platform == "win32": + out = subprocess.run( + ["hipConfig", "--show-device"], + capture_output=True, + text=True, + timeout=10, + ).stdout.upper() + # Match whole device names; bare "RX 9070" (no " XT") must still + # resolve to rx9070 rather than collapsing into the empty set. + for tag in ( + "RX 9070 XT", "R9000", "RX 9060 XT", + "RX 9070 ", "RX 9070", "RX 9060", + "MI355X", "MI300X", + ): + if tag in out: + return tag.replace("MI", "mi").replace("RX ", "rx").replace(" XT", "xt").replace(" ", "").lower() + # Fallbacks for "AMD Radeon RX 9070" / "AMD Radeon Pro R9000" (full + # product strings) so bare non-XT SKUs are detected. + import re as _re + bare = _re.search(r"AMD\s+Radeon\s+(Pro\s+R9000|RX\s+\d{3,4}\s*XT|RX\s+\d{3,4})\b", out) + if bare: + tok = bare.group(1).replace("Pro ", "Pro_").replace("XT", "xt").replace(" ", "").replace("_", "").replace("RX", "rx").lower() + return "r9000" if "pro" in tok or "r9000" in tok else tok + else: + out = subprocess.run( + ["rocm-smi", "--showproductname"], + capture_output=True, + text=True, + timeout=5, + ).stdout.upper() + for tag in ("MI355X", "MI325X", "MI308X", "MI300X", "RX9070XT", "RX9070", "RX9060XT", "R9000"): + if tag in out: + return tag.lower() except (FileNotFoundError, subprocess.TimeoutExpired, PermissionError, OSError): - # rocm-smi missing / slow / not permitted; fall through to the torch - # gcnArchName probe below (autodetect is best-effort). pass try: import torch diff --git a/src/hyperloom/orchestrator/kernel/roofline_ceiling.py b/src/hyperloom/orchestrator/kernel/roofline_ceiling.py index 51c1c39236..6356b42141 100644 --- a/src/hyperloom/orchestrator/kernel/roofline_ceiling.py +++ b/src/hyperloom/orchestrator/kernel/roofline_ceiling.py @@ -58,6 +58,40 @@ "fp4": 10066.4, "float4": 10066.4, } +#: RDNA4 vendor-dense peak TFLOPS — per SKU. The four RX 9000-series SKUs do +#: *not* share a single table: AMD's published CU count and game clock differ +#: per SKU (see wiki/RDNA_4). rx9070xt (64 CU @ 2.4 GHz) is the baseline; the +#: other rows are scaled by (CUs * game_clock) so FP32/FP16/FP8 throughput is +#: distinct and correctly ordered: 9070xt > 9000xt > 9070 > 9060xt. Absolute +#: magnitude is preserved for rx9070xt so existing KB recipes stay calibrated. +_RDNA4_PEAK_TFLOPS_RX9070XT: dict[str, float] = { + "bf16": 194.8, + "bfloat16": 194.8, + "fp16": 194.8, + "float16": 194.8, + "fp8": 389.0, + "float8_e4m3fn": 389.0, + "float8_e5m2": 389.0, + "fp32": 14.6, + "float32": 14.6, + "fp64": 0.46, + "float64": 0.46, + "int4": 1557.0, +} + + +def _rdna4_peak_tflops(cu_count: int, boost_ghz: float, base: dict[str, float]) -> dict[str, float]: + """Scale a reference RDNA4 (RX 9070 XT, 64 CU @ 2.4 GHz) peak table by + the CU-count × boost-clock ratio for the target SKU.""" + ref_cu = 64 + ref_ghz = 2.4 + scale = (cu_count * boost_ghz) / (ref_cu * ref_ghz) + return {dtype: round(v * scale, 1) for dtype, v in base.items()} + + +_RDNA4_PEAK_TFLOPS_R9000: dict[str, float] = _RDNA4_PEAK_TFLOPS_RX9070XT +_RDNA4_PEAK_TFLOPS_RX9070: dict[str, float] = _rdna4_peak_tflops(56, 2.07, _RDNA4_PEAK_TFLOPS_RX9070XT) +_RDNA4_PEAK_TFLOPS_RX9060XT: dict[str, float] = _rdna4_peak_tflops(32, 2.53, _RDNA4_PEAK_TFLOPS_RX9070XT) HW_SPECS: dict[str, dict[str, Any]] = { "mi300x": { "hbm_gb": 192.0, @@ -79,6 +113,26 @@ "hbm_bw_gbps": 8000.0, "peak_tflops": _MI355X_PEAK_TFLOPS, }, + "rx9070xt": { + "gddr_gb": 16.0, + "hbm_bw_gbps": 640.0, + "peak_tflops": _RDNA4_PEAK_TFLOPS_RX9070XT, + }, + "rx9070": { + "gddr_gb": 16.0, + "hbm_bw_gbps": 640.0, + "peak_tflops": _RDNA4_PEAK_TFLOPS_RX9070, + }, + "rx9060xt": { + "gddr_gb": 16.0, + "hbm_bw_gbps": 640.0, + "peak_tflops": _RDNA4_PEAK_TFLOPS_RX9060XT, + }, + "r9000": { + "gddr_gb": 32.0, + "hbm_bw_gbps": 640.0, + "peak_tflops": _RDNA4_PEAK_TFLOPS_R9000, + }, } @@ -1574,6 +1628,29 @@ def read_baseline_server_args(state: Any) -> str: "float32": 137.0, } + +#: RDNA4 sustained (achievable) TFLOPS — reference is the RX 9070 XT +#: (64 CU, Navi 48). Other SKUs scaled by (CUs × game_clock) ratio. +#: The R9000 Pro is the workstation twin of the RX 9070 XT (same die, +#: 64 CU) and therefore shares its achievable table. +_RDNA4_ACHIEVABLE_TFLOPS_RX9070XT: dict[str, float] = { + "bf16": 140.0, + "bfloat16": 140.0, + "fp16": 135.0, + "float16": 135.0, + "fp8": 300.0, + "float8_e4m3fn": 300.0, + "float8_e5m2": 300.0, + "fp64": 0.035, + "float64": 0.035, + "int4": 1100.0, + "fp32": 11.0, + "float32": 11.0, +} +_RDNA4_ACHIEVABLE_TFLOPS_R9000: dict[str, float] = _RDNA4_ACHIEVABLE_TFLOPS_RX9070XT +_RDNA4_ACHIEVABLE_TFLOPS_RX9070: dict[str, float] = _rdna4_peak_tflops(56, 2.07, _RDNA4_ACHIEVABLE_TFLOPS_RX9070XT) +_RDNA4_ACHIEVABLE_TFLOPS_RX9060XT: dict[str, float] = _rdna4_peak_tflops(32, 2.53, _RDNA4_ACHIEVABLE_TFLOPS_RX9070XT) + HW_SPECS_ACHIEVABLE: dict[str, dict[str, Any]] = { "mi300x": { "hbm_bw_gbps": 5300.0, @@ -1590,6 +1667,26 @@ def read_baseline_server_args(state: Any) -> str: "hbm_gb": 288.0, "peak_tflops": _MI355X_ACHIEVABLE_TFLOPS, }, + "rx9070xt": { + "hbm_bw_gbps": 640.0, + "hbm_gb": 16.0, + "peak_tflops": _RDNA4_ACHIEVABLE_TFLOPS_RX9070XT, + }, + "rx9070": { + "hbm_bw_gbps": 640.0, + "hbm_gb": 16.0, + "peak_tflops": _RDNA4_ACHIEVABLE_TFLOPS_RX9070, + }, + "rx9060xt": { + "hbm_bw_gbps": 640.0, + "hbm_gb": 16.0, + "peak_tflops": _RDNA4_ACHIEVABLE_TFLOPS_RX9060XT, + }, + "r9000": { + "hbm_bw_gbps": 640.0, + "hbm_gb": 32.0, + "peak_tflops": _RDNA4_ACHIEVABLE_TFLOPS_R9000, + }, }