From 9db3d216c400bb4da17c2e4fd5e466fb2a714473 Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Mon, 22 Jun 2026 13:40:12 -0700 Subject: [PATCH 1/6] Share PyTorch build matrix policy Move PyTorch version, Python version, and PyTorch-specific family filtering into configure_pytorch_release_matrix.py, then thread the resulting matrix through multi-arch CI and release workflows. Tests: D:/projects/TheRock/.venv/Scripts/python.exe -m pytest github_actions/tests/configure_pytorch_release_matrix_test.py github_actions/tests/configure_multi_arch_ci_test.py Tests: pre-commit run --files Assisted-by: Codex --- .github/workflows/multi_arch_ci_linux.yml | 19 +- .github/workflows/multi_arch_ci_windows.yml | 19 +- .../workflows/multi_arch_release_linux.yml | 2 +- ...ulti_arch_release_linux_pytorch_wheels.yml | 2 + .../workflows/multi_arch_release_windows.yml | 2 +- ...ti_arch_release_windows_pytorch_wheels.yml | 2 + .../github_actions/configure_multi_arch_ci.py | 22 +- .../configure_multi_arch_ci_summary.py | 30 +++ .../configure_pytorch_release_matrix.py | 209 +++++++++++++----- .../tests/configure_multi_arch_ci_test.py | 58 +++++ .../configure_pytorch_release_matrix_test.py | 140 ++++++++++++ 11 files changed, 434 insertions(+), 71 deletions(-) create mode 100644 build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py diff --git a/.github/workflows/multi_arch_ci_linux.yml b/.github/workflows/multi_arch_ci_linux.yml index 744a77e8a0f..7c651fb5021 100644 --- a/.github/workflows/multi_arch_ci_linux.yml +++ b/.github/workflows/multi_arch_ci_linux.yml @@ -14,6 +14,7 @@ on: build_variant_label, build_variant_cmake_preset, build_variant_suffix, build_pytorch, build_native_linux, test_python_packages_matrix, + pytorch_build_matrix, prebuilt_stages, baseline_run_id. test_labels: type: string @@ -289,15 +290,25 @@ jobs: build_pytorch_wheel_fat: needs: [build_python_packages] name: Build PyTorch (fat + split) - if: ${{ !failure() && !cancelled() && fromJSON(inputs.build_config).build_pytorch == true }} + if: >- + ${{ + !failure() && + !cancelled() && + fromJSON(inputs.build_config).build_pytorch == true && + toJSON(fromJSON(inputs.build_config).pytorch_build_matrix) != '[]' + }} + strategy: + fail-fast: false + matrix: + include: ${{ fromJSON(inputs.build_config).pytorch_build_matrix }} uses: ./.github/workflows/multi_arch_build_portable_linux_pytorch_wheels_ci.yml with: artifact_group: ${{ fromJSON(inputs.build_config).artifact_group }} - python_version: "3.12" - pytorch_git_ref: "release/2.10" + python_version: ${{ matrix.python_version }} + pytorch_git_ref: ${{ matrix.pytorch_git_ref }} # The reusable workflow expands this to gfx targets via # cmake/therock_amdgpu_targets.cmake. - amdgpu_families: ${{ fromJSON(inputs.build_config).dist_amdgpu_families }} + amdgpu_families: ${{ matrix.amdgpu_families }} kpack_split: ${{ needs.build_python_packages.outputs.kpack_split }} rocm_package_find_links_url: ${{ needs.build_python_packages.outputs.package_find_links_url }} rocm_version: ${{ inputs.rocm_package_version }} diff --git a/.github/workflows/multi_arch_ci_windows.yml b/.github/workflows/multi_arch_ci_windows.yml index 53948afa83a..5982401b271 100644 --- a/.github/workflows/multi_arch_ci_windows.yml +++ b/.github/workflows/multi_arch_ci_windows.yml @@ -14,6 +14,7 @@ on: build_variant_label, build_variant_cmake_preset, build_variant_suffix, build_pytorch, build_native_linux, test_python_packages_matrix, + pytorch_build_matrix, prebuilt_stages, baseline_run_id. test_labels: type: string @@ -206,15 +207,25 @@ jobs: build_pytorch_wheel_fat: needs: [build_python_packages] name: Build PyTorch (fat + split) - if: ${{ !failure() && !cancelled() && fromJSON(inputs.build_config).build_pytorch == true }} + if: >- + ${{ + !failure() && + !cancelled() && + fromJSON(inputs.build_config).build_pytorch == true && + toJSON(fromJSON(inputs.build_config).pytorch_build_matrix) != '[]' + }} + strategy: + fail-fast: false + matrix: + include: ${{ fromJSON(inputs.build_config).pytorch_build_matrix }} uses: ./.github/workflows/multi_arch_build_windows_pytorch_wheels_ci.yml with: artifact_group: ${{ fromJSON(inputs.build_config).artifact_group }} - python_version: "3.12" - pytorch_git_ref: "release/2.10" + python_version: ${{ matrix.python_version }} + pytorch_git_ref: ${{ matrix.pytorch_git_ref }} # The reusable workflow expands this to gfx targets via # cmake/therock_amdgpu_targets.cmake. - amdgpu_families: ${{ fromJSON(inputs.build_config).dist_amdgpu_families }} + amdgpu_families: ${{ matrix.amdgpu_families }} kpack_split: ${{ needs.build_python_packages.outputs.kpack_split }} rocm_package_find_links_url: ${{ needs.build_python_packages.outputs.package_find_links_url }} rocm_version: ${{ inputs.rocm_package_version }} diff --git a/.github/workflows/multi_arch_release_linux.yml b/.github/workflows/multi_arch_release_linux.yml index 2f064a43c71..6dc5ecf3760 100644 --- a/.github/workflows/multi_arch_release_linux.yml +++ b/.github/workflows/multi_arch_release_linux.yml @@ -225,7 +225,7 @@ jobs: trigger_release_pytorch_wheels: needs: [build_artifacts, build_python_packages] name: Trigger Release PyTorch Wheels - if: ${{ inputs.build_pytorch != false }} + if: ${{ inputs.build_pytorch != false && fromJSON(inputs.build_config).build_pytorch == true }} runs-on: ubuntu-24.04 permissions: actions: write diff --git a/.github/workflows/multi_arch_release_linux_pytorch_wheels.yml b/.github/workflows/multi_arch_release_linux_pytorch_wheels.yml index 042ebf3a0cc..8c40d0233c2 100644 --- a/.github/workflows/multi_arch_release_linux_pytorch_wheels.yml +++ b/.github/workflows/multi_arch_release_linux_pytorch_wheels.yml @@ -123,11 +123,13 @@ jobs: python ./build_tools/github_actions/configure_pytorch_release_matrix.py \ --python-versions="${{ inputs.python_version }}" \ --platform=linux \ + --release-type="${{ inputs.release_type }}" \ --amdgpu-families="${{ inputs.amdgpu_families }}" build_pytorch_wheels: needs: setup_matrix name: Build | py ${{ matrix.python_version }} | torch ${{ matrix.pytorch_git_ref }} + if: ${{ needs.setup_matrix.outputs.pytorch_matrix != '[]' }} strategy: fail-fast: false matrix: diff --git a/.github/workflows/multi_arch_release_windows.yml b/.github/workflows/multi_arch_release_windows.yml index 0942c08562f..4e6b18d7595 100644 --- a/.github/workflows/multi_arch_release_windows.yml +++ b/.github/workflows/multi_arch_release_windows.yml @@ -156,7 +156,7 @@ jobs: trigger_release_pytorch_wheels: needs: [build_artifacts, build_python_packages] name: Trigger Release PyTorch Wheels - if: ${{ inputs.build_pytorch != false }} + if: ${{ inputs.build_pytorch != false && fromJSON(inputs.build_config).build_pytorch == true }} runs-on: ubuntu-24.04 permissions: actions: write diff --git a/.github/workflows/multi_arch_release_windows_pytorch_wheels.yml b/.github/workflows/multi_arch_release_windows_pytorch_wheels.yml index 1e5b3565f3c..8b98d4204b8 100644 --- a/.github/workflows/multi_arch_release_windows_pytorch_wheels.yml +++ b/.github/workflows/multi_arch_release_windows_pytorch_wheels.yml @@ -115,11 +115,13 @@ jobs: python ./build_tools/github_actions/configure_pytorch_release_matrix.py \ --python-versions="${{ inputs.python_version }}" \ --platform=windows \ + --release-type="${{ inputs.release_type }}" \ --amdgpu-families="${{ inputs.amdgpu_families }}" build_pytorch_wheels: needs: setup_matrix name: Build | py ${{ matrix.python_version }} | torch ${{ matrix.pytorch_git_ref }} + if: ${{ needs.setup_matrix.outputs.pytorch_matrix != '[]' }} strategy: fail-fast: false matrix: diff --git a/build_tools/github_actions/configure_multi_arch_ci.py b/build_tools/github_actions/configure_multi_arch_ci.py index 582b9946355..740a598ebd3 100755 --- a/build_tools/github_actions/configure_multi_arch_ci.py +++ b/build_tools/github_actions/configure_multi_arch_ci.py @@ -65,6 +65,7 @@ get_git_submodule_paths, is_ci_run_required, ) +from configure_pytorch_release_matrix import generate_pytorch_matrix_for_release_type from configure_rocm_python_test_matrix import build_rocm_python_test_matrix from github_actions_api import ( gha_append_step_summary, @@ -429,6 +430,7 @@ class BuildConfig: build_native_linux: bool build_pytorch: bool test_python_packages_matrix: list[dict[str, str]] = field(default_factory=list) + pytorch_build_matrix: list[dict[str, str]] = field(default_factory=list) # Build runner label for this platform/variant combination build_runs_on: str = "" # Prebuilt stage configuration — set by configure() from JobDecisions. @@ -823,6 +825,7 @@ def _expand_build_config_for_platform( pr_labels: list[str], is_schedule: bool, is_workflow_dispatch: bool, + release_type: str, git_context: GitContext, prebuilt_stages: list[str] | None = None, baseline_run_id: str = "", @@ -953,11 +956,24 @@ def _expand_build_config_for_platform( return None family_names = [f["amdgpu_family"] for f in per_family_info] + dist_amdgpu_families = ";".join(family_names) suffix = variant_config.get("build_variant_suffix", "") # Select build runner using weighted distribution build_runs_on = select_build_runner(platform, build_variant) + build_pytorch = suffix != "asan" + pytorch_build_matrix: list[dict[str, str]] = [] + if build_pytorch: + pytorch_build_matrix = generate_pytorch_matrix_for_release_type( + release_type=release_type, + python_versions=None, + pytorch_git_refs=None, + amdgpu_families=dist_amdgpu_families, + platform=platform, + ) + build_pytorch = bool(pytorch_build_matrix) + test_python_packages_matrix = build_rocm_python_test_matrix( per_family_info=per_family_info, platform=platform, @@ -968,13 +984,14 @@ def _expand_build_config_for_platform( return BuildConfig( per_family_info=per_family_info, - dist_amdgpu_families=";".join(family_names), + dist_amdgpu_families=dist_amdgpu_families, artifact_group=f"multi-arch-{suffix or 'release'}", build_variant_label=variant_config["build_variant_label"], build_variant_suffix=suffix, build_variant_cmake_preset=variant_config["build_variant_cmake_preset"], build_native_linux=(suffix != "asan"), - build_pytorch=(suffix != "asan"), + build_pytorch=build_pytorch, + pytorch_build_matrix=pytorch_build_matrix, build_runs_on=build_runs_on, test_python_packages_matrix=test_python_packages_matrix, prebuilt_stages=prebuilt_stages or [], @@ -1027,6 +1044,7 @@ def expand_build_configs( pr_labels=ci_inputs.pr_labels, is_schedule=ci_inputs.is_schedule, is_workflow_dispatch=ci_inputs.is_workflow_dispatch, + release_type=ci_inputs.release_type, prebuilt_stages=prebuilt_stages, baseline_run_id=baseline_run_id, git_context=git_context, diff --git a/build_tools/github_actions/configure_multi_arch_ci_summary.py b/build_tools/github_actions/configure_multi_arch_ci_summary.py index eb714ba117c..ba3858b99c3 100644 --- a/build_tools/github_actions/configure_multi_arch_ci_summary.py +++ b/build_tools/github_actions/configure_multi_arch_ci_summary.py @@ -68,6 +68,10 @@ def format_summary( lines.append("") _append_test_rocm(lines, outputs) + lines.append("### build-pytorch") + lines.append("") + _append_build_pytorch(lines, outputs) + return "\n".join(lines) @@ -199,6 +203,32 @@ def _append_build_rocm( ) +def _append_build_pytorch(lines: list[str], outputs: CIOutputs) -> None: + lines.append("| Platform | Python | PyTorch ref | Families |") + lines.append("|----------|--------|-------------|----------|") + + rows = 0 + for platform, config in [ + ("Linux", outputs.builds.linux), + ("Windows", outputs.builds.windows), + ]: + if config is None: + continue + for row in config.pytorch_build_matrix: + families = ", ".join( + f"`{family}`" for family in row["amdgpu_families"].split(";") + ) + lines.append( + f"| {platform} | `{row['python_version']}` | " + f"`{row['pytorch_git_ref']}` | {families} |" + ) + rows += 1 + + if rows == 0: + lines.append("| — | — | — | — |") + lines.append("") + + def _append_test_rocm(lines: list[str], outputs: CIOutputs) -> None: # Note: this assumes that the test_rocm job is never skipped. # We may decide to skip it under certain conditions in the future diff --git a/build_tools/github_actions/configure_pytorch_release_matrix.py b/build_tools/github_actions/configure_pytorch_release_matrix.py index a6308188533..759605f6997 100644 --- a/build_tools/github_actions/configure_pytorch_release_matrix.py +++ b/build_tools/github_actions/configure_pytorch_release_matrix.py @@ -2,7 +2,7 @@ # Copyright Advanced Micro Devices, Inc. # SPDX-License-Identifier: MIT -"""Generate PyTorch release build matrix for workflows.""" +"""Generate PyTorch build matrices for CI and release workflows.""" import argparse import json @@ -15,50 +15,44 @@ from github_actions.github_actions_api import gha_set_output -PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +RELEASE_TYPES = ["ci", "dev", "nightly", "prerelease"] -# PyTorch git refs per platform. -# Each ref may optionally carry an `exclude_amdgpu_families` set: GPU families -# that should be omitted for this ref (e.g. because upstream support is not yet -# merged). When `exclude_amdgpu_families` is absent the ref inherits whatever -# families are passed in via --amdgpu-families. -# -# Format: list of dicts with keys: -# pytorch_git_ref – git branch/tag passed to the build job -# exclude_amdgpu_families – (optional) set[str] of family names to drop +RELEASE_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +CI_PYTHON_VERSIONS = { + "linux": ["3.12"], + "windows": ["3.12"], +} -PYTORCH_REFS_LINUX: list[dict] = [ +GFX125X_FAMILY = "gfx125X-dcgpu" +GFX125X_UNSUPPORTED = {GFX125X_FAMILY} + +# Known PyTorch refs per platform. Each ref may carry canonical AMDGPU +# families that should be omitted while support is not available. +PYTORCH_REFS_LINUX: list[dict[str, object]] = [ { "pytorch_git_ref": "release/2.9", - # gfx125x not supported for PyTorch 2.9. - "exclude_amdgpu_families": {"gfx125x"}, + "exclude_amdgpu_families": GFX125X_UNSUPPORTED, }, { "pytorch_git_ref": "release/2.10", - # gfx125x not supported for PyTorch 2.10. - "exclude_amdgpu_families": {"gfx125x"}, + "exclude_amdgpu_families": GFX125X_UNSUPPORTED, }, { "pytorch_git_ref": "release/2.11", - # gfx125x not yet upstreamed to pytorch/pytorch. - # See https://github.com/ROCm/TheRock/issues/5833. - "exclude_amdgpu_families": {"gfx125x"}, + "exclude_amdgpu_families": GFX125X_UNSUPPORTED, }, { "pytorch_git_ref": "release/2.12", - # No exclusion — trigger manually with release/2.12_gfx1250 branch - # to include gfx1250 until upstreamed. See issue #5833. + "exclude_amdgpu_families": GFX125X_UNSUPPORTED, }, { "pytorch_git_ref": "nightly", - # gfx125x not yet upstreamed to pytorch/pytorch. - # See https://github.com/ROCm/TheRock/issues/5833. - "exclude_amdgpu_families": {"gfx125x"}, + "exclude_amdgpu_families": GFX125X_UNSUPPORTED, }, ] -# gfx125x is Linux-only; no exclusion needed for Windows. -PYTORCH_REFS_WINDOWS: list[dict] = [ +# gfx125X-dcgpu is Linux-only, so Windows currently needs no exclusions. +PYTORCH_REFS_WINDOWS: list[dict[str, object]] = [ {"pytorch_git_ref": "release/2.9"}, {"pytorch_git_ref": "release/2.10"}, {"pytorch_git_ref": "release/2.11"}, @@ -66,41 +60,119 @@ {"pytorch_git_ref": "nightly"}, ] +CI_PYTORCH_REFS = { + "linux": ["release/2.10", "release/2.11", "release/2.12"], + "windows": ["release/2.10"], +} + + +def _split_values(raw: str) -> list[str]: + """Split comma, semicolon, or whitespace-separated workflow input values.""" + return [ + value.strip() + for value in raw.replace(",", " ").replace(";", " ").split() + if value.strip() + ] + + +def _split_families(raw: str) -> list[str]: + return [family.strip() for family in raw.split(";") if family.strip()] + + +def _default_python_versions(*, release_type: str, platform: str) -> list[str]: + if release_type == "ci": + return list(CI_PYTHON_VERSIONS[platform]) + return list(RELEASE_PYTHON_VERSIONS) + + +def _ref_configs_for_platform(platform: str) -> list[dict[str, object]]: + if platform == "windows": + return PYTORCH_REFS_WINDOWS + return PYTORCH_REFS_LINUX -def _filter_families(families_str: str, exclude: set[str]) -> str: - """Remove excluded family names from a semicolon-separated families string. - Family names are matched case-insensitively against the exclude set so that - e.g. ``gfx125x`` matches ``gfx125X-dcgpu`` style entries. - """ +def _default_ref_configs( + *, release_type: str, platform: str +) -> list[dict[str, object]]: + known_configs = _ref_configs_for_platform(platform) + if release_type != "ci": + return list(known_configs) + + ci_refs = set(CI_PYTORCH_REFS[platform]) + return [ + config for config in known_configs if str(config["pytorch_git_ref"]) in ci_refs + ] + + +def _ref_config_for_ref(*, platform: str, pytorch_git_ref: str) -> dict[str, object]: + for config in _ref_configs_for_platform(platform): + if config["pytorch_git_ref"] == pytorch_git_ref: + return config + return {"pytorch_git_ref": pytorch_git_ref} + + +def _filter_families(families_str: str, exclude: set[str]) -> str: + """Remove excluded canonical family names from a semicolon-separated list.""" if not exclude: - return families_str - result = [] - for fam in families_str.split(";"): - fam = fam.strip() - if not fam: - continue - # Match by checking whether any excluded name is a case-insensitive - # prefix/substring of the family token (e.g. "gfx125x" in "gfx125X-dcgpu"). - skip = any(exc.lower() in fam.lower() for exc in exclude) - if not skip: - result.append(fam) - return ";".join(result) + return ";".join(_split_families(families_str)) + + exclude_lower = {family.lower() for family in exclude} + return ";".join( + family + for family in _split_families(families_str) + if family.lower() not in exclude_lower + ) def generate_pytorch_matrix( + *, python_versions: list[str] | None, + pytorch_git_refs: list[str] | None, amdgpu_families: str, platform: str = "linux", -) -> list[dict]: - versions = python_versions if python_versions else PYTHON_VERSIONS - pytorch_refs = PYTORCH_REFS_WINDOWS if platform == "windows" else PYTORCH_REFS_LINUX - matrix = [] +) -> list[dict[str, str]]: + return generate_pytorch_matrix_for_release_type( + release_type="dev", + python_versions=python_versions, + pytorch_git_refs=pytorch_git_refs, + amdgpu_families=amdgpu_families, + platform=platform, + ) + + +def generate_pytorch_matrix_for_release_type( + *, + release_type: str, + python_versions: list[str] | None, + pytorch_git_refs: list[str] | None, + amdgpu_families: str, + platform: str, +) -> list[dict[str, str]]: + if release_type not in RELEASE_TYPES: + raise ValueError(f"Unknown release_type: {release_type!r}") + if platform not in ["linux", "windows"]: + raise ValueError(f"Unknown platform: {platform!r}") + + versions = python_versions or _default_python_versions( + release_type=release_type, platform=platform + ) + ref_configs = ( + [ + _ref_config_for_ref(platform=platform, pytorch_git_ref=ref) + for ref in pytorch_git_refs + ] + if pytorch_git_refs + else _default_ref_configs(release_type=release_type, platform=platform) + ) + + matrix: list[dict[str, str]] = [] for py in versions: - for ref_cfg in pytorch_refs: - ref = ref_cfg["pytorch_git_ref"] - exclude = ref_cfg.get("exclude_amdgpu_families", set()) + for ref_cfg in ref_configs: + ref = str(ref_cfg["pytorch_git_ref"]) + exclude = set(ref_cfg.get("exclude_amdgpu_families", set())) families = _filter_families(amdgpu_families, exclude) + if not families: + continue row: dict = { "python_version": py, "pytorch_git_ref": ref, @@ -118,7 +190,19 @@ def main(argv: list[str] | None = None) -> int: "--python-versions", type=str, default="", - help="Comma or semicolon separated list of Python versions (default: all)", + help=( + "Comma, semicolon, or whitespace separated list of Python versions " + "(default depends on --release-type)" + ), + ) + parser.add_argument( + "--pytorch-git-refs", + type=str, + default="", + help=( + "Comma, semicolon, or whitespace separated list of PyTorch refs " + "(default depends on --release-type and --platform)" + ), ) parser.add_argument( "--platform", @@ -127,6 +211,13 @@ def main(argv: list[str] | None = None) -> int: choices=["linux", "windows"], help="Platform to generate matrix for (default: current system)", ) + parser.add_argument( + "--release-type", + type=str, + default="dev", + choices=RELEASE_TYPES, + help="Release type selecting default PyTorch/Python matrix (default: dev)", + ) parser.add_argument( "--amdgpu-families", type=str, @@ -139,15 +230,15 @@ def main(argv: list[str] | None = None) -> int: ) args = parser.parse_args(argv) - python_versions = None - if args.python_versions: - sep = ";" if ";" in args.python_versions else "," - python_versions = [ - v.strip() for v in args.python_versions.split(sep) if v.strip() - ] + python_versions = _split_values(args.python_versions) or None + pytorch_git_refs = _split_values(args.pytorch_git_refs) or None - matrix = generate_pytorch_matrix( - python_versions, args.amdgpu_families, args.platform + matrix = generate_pytorch_matrix_for_release_type( + release_type=args.release_type, + python_versions=python_versions, + pytorch_git_refs=pytorch_git_refs, + amdgpu_families=args.amdgpu_families, + platform=args.platform, ) gha_set_output({"pytorch_matrix": json.dumps(matrix)}) return 0 diff --git a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py index a9cd6476a82..46da926e0e3 100644 --- a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py +++ b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py @@ -934,6 +934,64 @@ def test_build_config_includes_python_package_test_matrix(self): ], ) + def test_build_config_includes_pytorch_build_matrix(self): + targets = cm.TargetSelection( + linux_families=["gfx94x"], + windows_families=["gfx110x"], + ) + result = cm.expand_build_configs( + targets=targets, + ci_inputs=self._inputs(), + test_type="quick", + git_context=cm.GitContext(), + ) + + self.assertEqual( + result.linux.pytorch_build_matrix, + [ + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.10", + "amdgpu_families": "gfx94X-dcgpu", + }, + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.11", + "amdgpu_families": "gfx94X-dcgpu", + }, + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.12", + "amdgpu_families": "gfx94X-dcgpu", + }, + ], + ) + self.assertEqual( + result.windows.pytorch_build_matrix, + [ + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.10", + "amdgpu_families": "gfx110X-all", + } + ], + ) + + def test_build_config_disables_pytorch_when_all_families_are_filtered(self): + targets = cm.TargetSelection( + linux_families=["gfx125x"], + windows_families=[], + ) + result = cm.expand_build_configs( + targets=targets, + ci_inputs=self._inputs(), + test_type="quick", + git_context=cm.GitContext(), + ) + + self.assertFalse(result.linux.build_pytorch) + self.assertEqual(result.linux.pytorch_build_matrix, []) + def test_variant_filters_by_platform_and_family_support(self): """ASAN: only gfx94x on linux supports it, gfx110x doesn't, windows has no ASAN config.""" # gfx94x supports asan, gfx110x is release-only, windows has no asan variant. diff --git a/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py new file mode 100644 index 00000000000..3bff3b7399e --- /dev/null +++ b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py @@ -0,0 +1,140 @@ +# Copyright Advanced Micro Devices, Inc. +# SPDX-License-Identifier: MIT + +import os +import sys +import unittest +from pathlib import Path + +sys.path.insert(0, os.fspath(Path(__file__).parent.parent)) + +import configure_pytorch_release_matrix as m + + +class ConfigurePytorchReleaseMatrixTest(unittest.TestCase): + def test_ci_linux_uses_reduced_matrix(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="ci", + python_versions=None, + pytorch_git_refs=None, + amdgpu_families="gfx94X-dcgpu", + platform="linux", + ) + + self.assertEqual( + matrix, + [ + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.10", + "amdgpu_families": "gfx94X-dcgpu", + }, + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.11", + "amdgpu_families": "gfx94X-dcgpu", + }, + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.12", + "amdgpu_families": "gfx94X-dcgpu", + }, + ], + ) + + def test_ci_windows_uses_reduced_matrix(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="ci", + python_versions=None, + pytorch_git_refs=None, + amdgpu_families="gfx110X-all", + platform="windows", + ) + + self.assertEqual( + matrix, + [ + { + "python_version": "3.12", + "pytorch_git_ref": "release/2.10", + "amdgpu_families": "gfx110X-all", + }, + ], + ) + + def test_explicit_versions_and_refs_narrow_matrix(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="nightly", + python_versions=["3.13"], + pytorch_git_refs=["nightly"], + amdgpu_families="gfx94X-dcgpu", + platform="linux", + ) + + self.assertEqual( + matrix, + [ + { + "python_version": "3.13", + "pytorch_git_ref": "nightly", + "amdgpu_families": "gfx94X-dcgpu", + } + ], + ) + + def test_filters_exact_unsupported_canonical_family(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="dev", + python_versions=["3.12"], + pytorch_git_refs=["release/2.10"], + amdgpu_families="gfx94X-dcgpu;gfx125X-dcgpu", + platform="linux", + ) + + self.assertEqual(matrix[0]["amdgpu_families"], "gfx94X-dcgpu") + + def test_filter_does_not_use_substring_matching(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="dev", + python_versions=["3.12"], + pytorch_git_refs=["release/2.10"], + amdgpu_families="gfx125X-dcgpu-experimental", + platform="linux", + ) + + self.assertEqual(matrix[0]["amdgpu_families"], "gfx125X-dcgpu-experimental") + + def test_rows_with_no_supported_families_are_omitted(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="dev", + python_versions=["3.12"], + pytorch_git_refs=["release/2.10"], + amdgpu_families="gfx125X-dcgpu", + platform="linux", + ) + + self.assertEqual(matrix, []) + + def test_unknown_explicit_ref_keeps_families(self): + matrix = m.generate_pytorch_matrix_for_release_type( + release_type="dev", + python_versions=["3.12"], + pytorch_git_refs=["users/alice/gfx125x-bringup"], + amdgpu_families="gfx125X-dcgpu", + platform="linux", + ) + + self.assertEqual( + matrix, + [ + { + "python_version": "3.12", + "pytorch_git_ref": "users/alice/gfx125x-bringup", + "amdgpu_families": "gfx125X-dcgpu", + } + ], + ) + + +if __name__ == "__main__": + unittest.main() From a9251613604fa016a0d713da8c340bf4845fc570 Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Tue, 23 Jun 2026 14:14:41 -0700 Subject: [PATCH 2/6] Simplify PyTorch matrix policy Replace the per-ref dict configuration with explicit release/CI ref lists and an unsupported-family map. Remove the unused matrix wrapper so callers use a single entry point with defaulted optional overrides. Testing: - D:/projects/TheRock/.venv/Scripts/python.exe -m pytest github_actions/tests/configure_pytorch_release_matrix_test.py github_actions/tests/configure_multi_arch_ci_test.py - pre-commit run --files build_tools/github_actions/configure_pytorch_release_matrix.py build_tools/github_actions/configure_multi_arch_ci.py build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py Assisted-by: Codex --- .../github_actions/configure_multi_arch_ci.py | 2 - .../configure_pytorch_release_matrix.py | 159 ++++++++---------- .../configure_pytorch_release_matrix_test.py | 4 - 3 files changed, 70 insertions(+), 95 deletions(-) diff --git a/build_tools/github_actions/configure_multi_arch_ci.py b/build_tools/github_actions/configure_multi_arch_ci.py index 740a598ebd3..092443c8fdd 100755 --- a/build_tools/github_actions/configure_multi_arch_ci.py +++ b/build_tools/github_actions/configure_multi_arch_ci.py @@ -967,8 +967,6 @@ def _expand_build_config_for_platform( if build_pytorch: pytorch_build_matrix = generate_pytorch_matrix_for_release_type( release_type=release_type, - python_versions=None, - pytorch_git_refs=None, amdgpu_families=dist_amdgpu_families, platform=platform, ) diff --git a/build_tools/github_actions/configure_pytorch_release_matrix.py b/build_tools/github_actions/configure_pytorch_release_matrix.py index 759605f6997..a3ed895ebe2 100644 --- a/build_tools/github_actions/configure_pytorch_release_matrix.py +++ b/build_tools/github_actions/configure_pytorch_release_matrix.py @@ -17,54 +17,57 @@ RELEASE_TYPES = ["ci", "dev", "nightly", "prerelease"] +# TODO: add opt-ins for CI runs to use python versions and pytorch refs normally +# only included in release runs + RELEASE_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] CI_PYTHON_VERSIONS = { "linux": ["3.12"], "windows": ["3.12"], } -GFX125X_FAMILY = "gfx125X-dcgpu" -GFX125X_UNSUPPORTED = {GFX125X_FAMILY} - -# Known PyTorch refs per platform. Each ref may carry canonical AMDGPU -# families that should be omitted while support is not available. -PYTORCH_REFS_LINUX: list[dict[str, object]] = [ - { - "pytorch_git_ref": "release/2.9", - "exclude_amdgpu_families": GFX125X_UNSUPPORTED, - }, - { - "pytorch_git_ref": "release/2.10", - "exclude_amdgpu_families": GFX125X_UNSUPPORTED, - }, - { - "pytorch_git_ref": "release/2.11", - "exclude_amdgpu_families": GFX125X_UNSUPPORTED, - }, - { - "pytorch_git_ref": "release/2.12", - "exclude_amdgpu_families": GFX125X_UNSUPPORTED, - }, - { - "pytorch_git_ref": "nightly", - "exclude_amdgpu_families": GFX125X_UNSUPPORTED, - }, -] - -# gfx125X-dcgpu is Linux-only, so Windows currently needs no exclusions. -PYTORCH_REFS_WINDOWS: list[dict[str, object]] = [ - {"pytorch_git_ref": "release/2.9"}, - {"pytorch_git_ref": "release/2.10"}, - {"pytorch_git_ref": "release/2.11"}, - {"pytorch_git_ref": "release/2.12"}, - {"pytorch_git_ref": "nightly"}, -] +# TODO: separate out "nightly" pytorch refs from "prerelease" pytorch refs? +# That would let us: +# 1. choose to not build the "nightly" pytorch branch for prerelease builds, +# saving some CI resources and possibly simplifying package promotion +# scripts. +# 2. filter out some AMDGPU families from prereleases if we only want them +# built for nightly but not published to stable. +RELEASE_PYTORCH_REFS = { + "linux": [ + "release/2.9", + "release/2.10", + "release/2.11", + "release/2.12", + "nightly", + ], + "windows": [ + "release/2.9", + "release/2.10", + "release/2.11", + "release/2.12", + "nightly", + ], +} CI_PYTORCH_REFS = { "linux": ["release/2.10", "release/2.11", "release/2.12"], "windows": ["release/2.10"], } +# Unknown explicit refs are left unfiltered so bring-up branches can opt into +# new GPU families before the default PyTorch refs support them. +UNSUPPORTED_AMDGPU_FAMILIES = { + "linux": { + "release/2.9": {"gfx125X-dcgpu"}, + "release/2.10": {"gfx125X-dcgpu"}, + "release/2.11": {"gfx125X-dcgpu"}, + "release/2.12": {"gfx125X-dcgpu"}, + "nightly": {"gfx125X-dcgpu"}, + }, + "windows": {}, +} + def _split_values(raw: str) -> list[str]: """Split comma, semicolon, or whitespace-separated workflow input values.""" @@ -85,30 +88,10 @@ def _default_python_versions(*, release_type: str, platform: str) -> list[str]: return list(RELEASE_PYTHON_VERSIONS) -def _ref_configs_for_platform(platform: str) -> list[dict[str, object]]: - if platform == "windows": - return PYTORCH_REFS_WINDOWS - return PYTORCH_REFS_LINUX - - -def _default_ref_configs( - *, release_type: str, platform: str -) -> list[dict[str, object]]: - known_configs = _ref_configs_for_platform(platform) - if release_type != "ci": - return list(known_configs) - - ci_refs = set(CI_PYTORCH_REFS[platform]) - return [ - config for config in known_configs if str(config["pytorch_git_ref"]) in ci_refs - ] - - -def _ref_config_for_ref(*, platform: str, pytorch_git_ref: str) -> dict[str, object]: - for config in _ref_configs_for_platform(platform): - if config["pytorch_git_ref"] == pytorch_git_ref: - return config - return {"pytorch_git_ref": pytorch_git_ref} +def _default_pytorch_git_refs(*, release_type: str, platform: str) -> list[str]: + if release_type == "ci": + return list(CI_PYTORCH_REFS[platform]) + return list(RELEASE_PYTORCH_REFS[platform]) def _filter_families(families_str: str, exclude: set[str]) -> str: @@ -124,29 +107,13 @@ def _filter_families(families_str: str, exclude: set[str]) -> str: ) -def generate_pytorch_matrix( - *, - python_versions: list[str] | None, - pytorch_git_refs: list[str] | None, - amdgpu_families: str, - platform: str = "linux", -) -> list[dict[str, str]]: - return generate_pytorch_matrix_for_release_type( - release_type="dev", - python_versions=python_versions, - pytorch_git_refs=pytorch_git_refs, - amdgpu_families=amdgpu_families, - platform=platform, - ) - - def generate_pytorch_matrix_for_release_type( *, release_type: str, - python_versions: list[str] | None, - pytorch_git_refs: list[str] | None, amdgpu_families: str, platform: str, + python_versions: list[str] | None = None, + pytorch_git_refs: list[str] | None = None, ) -> list[dict[str, str]]: if release_type not in RELEASE_TYPES: raise ValueError(f"Unknown release_type: {release_type!r}") @@ -156,24 +123,38 @@ def generate_pytorch_matrix_for_release_type( versions = python_versions or _default_python_versions( release_type=release_type, platform=platform ) - ref_configs = ( - [ - _ref_config_for_ref(platform=platform, pytorch_git_ref=ref) - for ref in pytorch_git_refs - ] - if pytorch_git_refs - else _default_ref_configs(release_type=release_type, platform=platform) + refs = pytorch_git_refs or _default_pytorch_git_refs( + release_type=release_type, platform=platform ) + # Build one matrix row per requested Python version and PyTorch ref. Each + # row carries the AMDGPU families that the child build workflow should use + # for that ref after filtering out families that are not supported yet. + # + # Example Linux output for release_type="dev" and + # amdgpu_families="gfx94X-dcgpu;gfx125X-dcgpu": + # + # [ + # { + # "python_version": "3.10", + # "pytorch_git_ref": "release/2.9", + # "amdgpu_families": "gfx94X-dcgpu" + # }, + # ... + # { + # "python_version": "3.14", + # "pytorch_git_ref": "nightly", + # "amdgpu_families": "gfx94X-dcgpu" + # } + # ] matrix: list[dict[str, str]] = [] for py in versions: - for ref_cfg in ref_configs: - ref = str(ref_cfg["pytorch_git_ref"]) - exclude = set(ref_cfg.get("exclude_amdgpu_families", set())) + for ref in refs: + exclude = UNSUPPORTED_AMDGPU_FAMILIES[platform].get(ref, set()) families = _filter_families(amdgpu_families, exclude) if not families: continue - row: dict = { + row: dict[str, str] = { "python_version": py, "pytorch_git_ref": ref, "amdgpu_families": families, diff --git a/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py index 3bff3b7399e..3a3c50e8238 100644 --- a/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py +++ b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py @@ -15,8 +15,6 @@ class ConfigurePytorchReleaseMatrixTest(unittest.TestCase): def test_ci_linux_uses_reduced_matrix(self): matrix = m.generate_pytorch_matrix_for_release_type( release_type="ci", - python_versions=None, - pytorch_git_refs=None, amdgpu_families="gfx94X-dcgpu", platform="linux", ) @@ -45,8 +43,6 @@ def test_ci_linux_uses_reduced_matrix(self): def test_ci_windows_uses_reduced_matrix(self): matrix = m.generate_pytorch_matrix_for_release_type( release_type="ci", - python_versions=None, - pytorch_git_refs=None, amdgpu_families="gfx110X-all", platform="windows", ) From 403b4b9277bfe93076fc4d166d04a9fd45279ef6 Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Wed, 24 Jun 2026 17:29:42 -0700 Subject: [PATCH 3/6] Thread PyTorch matrix inputs through setup Pass the PyTorch build toggle and release Python version into the multi-arch setup workflow so setup-generated build configs match the release workflows that consume them. Also let manually triggered multi_arch_ci.yml runs skip PyTorch builds, and keep ASAN setup callers opted out explicitly. Assisted-by: Codex --- .github/workflows/multi_arch_ci.yml | 5 ++ .github/workflows/multi_arch_ci_asan.yml | 1 + .github/workflows/multi_arch_release.yml | 2 + .github/workflows/multi_arch_release_asan.yml | 2 + .github/workflows/setup_multi_arch.yml | 10 ++++ .../github_actions/configure_multi_arch_ci.py | 20 ++++++-- .../tests/configure_multi_arch_ci_test.py | 49 +++++++++++++++++++ 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/.github/workflows/multi_arch_ci.yml b/.github/workflows/multi_arch_ci.yml index defdc47ab34..0693a973430 100644 --- a/.github/workflows/multi_arch_ci.yml +++ b/.github/workflows/multi_arch_ci.yml @@ -46,6 +46,10 @@ on: type: string default: "" description: "Comma-separated list of changed projects to filter tests (empty = run all tests)" + build_pytorch: + type: boolean + default: true + description: "Build PyTorch wheels" pull_request: types: - labeled @@ -78,6 +82,7 @@ jobs: windows_test_labels: ${{ inputs.windows_test_labels || '' }} prebuilt_stages: ${{ inputs.prebuilt_stages || '' }} baseline_run_id: ${{ inputs.baseline_run_id || '' }} + build_pytorch: ${{ github.event_name != 'workflow_dispatch' || inputs.build_pytorch }} linux_build_and_test: name: Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} diff --git a/.github/workflows/multi_arch_ci_asan.yml b/.github/workflows/multi_arch_ci_asan.yml index dab0030c3cb..e293959f4fe 100644 --- a/.github/workflows/multi_arch_ci_asan.yml +++ b/.github/workflows/multi_arch_ci_asan.yml @@ -58,6 +58,7 @@ jobs: linux_test_labels: ${{ inputs.linux_test_labels || '' }} prebuilt_stages: ${{ inputs.prebuilt_stages || '' }} baseline_run_id: ${{ inputs.baseline_run_id || '' }} + build_pytorch: false linux_build_and_test: name: Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} diff --git a/.github/workflows/multi_arch_release.yml b/.github/workflows/multi_arch_release.yml index 5612ec64812..1b02d78ce20 100644 --- a/.github/workflows/multi_arch_release.yml +++ b/.github/workflows/multi_arch_release.yml @@ -105,6 +105,8 @@ jobs: build_variant: "release" release_type: ${{ inputs.release_type }} prerelease_version: ${{ inputs.prerelease_version }} + build_pytorch: ${{ inputs.build_pytorch }} + python_version: ${{ inputs.python_version }} linux_amdgpu_families: ${{ inputs.linux_amdgpu_families }} windows_amdgpu_families: ${{ inputs.windows_amdgpu_families }} repository: ${{ inputs.repository || github.repository }} diff --git a/.github/workflows/multi_arch_release_asan.yml b/.github/workflows/multi_arch_release_asan.yml index a6f3ff5c9b4..f7bc20d6bd5 100644 --- a/.github/workflows/multi_arch_release_asan.yml +++ b/.github/workflows/multi_arch_release_asan.yml @@ -84,6 +84,8 @@ jobs: build_variant: "asan" release_type: ${{ inputs.release_type || 'dev' }} prerelease_version: ${{ inputs.prerelease_version }} + build_pytorch: false + python_version: ${{ inputs.python_version }} linux_amdgpu_families: ${{ inputs.linux_amdgpu_families || 'all' }} windows_amdgpu_families: "none" repository: ${{ inputs.repository || github.repository }} diff --git a/.github/workflows/setup_multi_arch.yml b/.github/workflows/setup_multi_arch.yml index 06e238b0301..5055bb0482e 100644 --- a/.github/workflows/setup_multi_arch.yml +++ b/.github/workflows/setup_multi_arch.yml @@ -15,6 +15,14 @@ on: artifact bucket selection, IAM role, and package versioning. type: string default: ci + build_pytorch: + description: "Build PyTorch wheels." + type: boolean + default: true + python_version: + description: "Single Python version for wheel builds; empty uses the default matrix." + type: string + default: "" prerelease_version: description: Prerelease version number such as '2'. This gets appended to the computed version after 'rc', like '7.10.0rc2' type: string @@ -130,6 +138,8 @@ jobs: env: BUILD_VARIANT: ${{ inputs.build_variant }} RELEASE_TYPE: ${{ inputs.release_type }} + BUILD_PYTORCH: ${{ inputs.build_pytorch }} + PYTHON_VERSION: ${{ inputs.python_version }} LINUX_AMDGPU_FAMILIES: ${{ inputs.linux_amdgpu_families }} WINDOWS_AMDGPU_FAMILIES: ${{ inputs.windows_amdgpu_families }} LINUX_TEST_LABELS: ${{ inputs.linux_test_labels }} diff --git a/build_tools/github_actions/configure_multi_arch_ci.py b/build_tools/github_actions/configure_multi_arch_ci.py index 092443c8fdd..2571d0e4ac6 100755 --- a/build_tools/github_actions/configure_multi_arch_ci.py +++ b/build_tools/github_actions/configure_multi_arch_ci.py @@ -131,6 +131,8 @@ class CIInputs: base_ref: str # Git ref for the workflow run (PR base or HEAD^1, used for diffing) build_variant: str # Build variant label, e.g. "release", "asan", "tsan" release_type: str = "ci" # "ci", or "dev", "nightly", "prerelease" for releases + build_pytorch: bool = True + python_versions: list[str] = field(default_factory=list) # PR labels (from event payload for pull_request events) pr_labels: list[str] = field(default_factory=list) @@ -182,6 +184,8 @@ def from_environ() -> "CIInputs": # push before-commit) comes from the event payload. build_variant = os.environ.get("BUILD_VARIANT", "release") release_type = os.environ.get("RELEASE_TYPE", "ci") + build_pytorch = os.environ.get("BUILD_PYTORCH", "true").lower() != "false" + python_version = os.environ.get("PYTHON_VERSION", "").strip() pr_labels: list[str] = [] base_ref = "HEAD^1" @@ -216,6 +220,8 @@ def from_environ() -> "CIInputs": base_ref=base_ref, build_variant=build_variant, release_type=release_type, + build_pytorch=build_pytorch, + python_versions=[python_version] if python_version else [], pr_labels=pr_labels, linux_amdgpu_families=_parse_comma_list( os.environ.get("LINUX_AMDGPU_FAMILIES", "") @@ -665,6 +671,8 @@ def decide_jobs( test_type_reason="ASAN tests skipped due to non-nightly trigger", ) + build_pytorch_action = JobAction.RUN if ci_inputs.build_pytorch else JobAction.SKIP + # Other jobs run unconditionally with no configuration. # TODO: job pruning: skip pytorch if only JAX has been edited, etc. @@ -672,8 +680,8 @@ def decide_jobs( build_rocm=build_rocm, test_rocm=test_rocm, build_rocm_python=JobGroupDecision(action=JobAction.RUN), - build_pytorch=JobGroupDecision(action=JobAction.RUN), - test_pytorch=JobGroupDecision(action=JobAction.RUN), + build_pytorch=JobGroupDecision(action=build_pytorch_action), + test_pytorch=JobGroupDecision(action=build_pytorch_action), ) @@ -826,6 +834,8 @@ def _expand_build_config_for_platform( is_schedule: bool, is_workflow_dispatch: bool, release_type: str, + build_pytorch: bool, + python_versions: list[str], git_context: GitContext, prebuilt_stages: list[str] | None = None, baseline_run_id: str = "", @@ -962,13 +972,13 @@ def _expand_build_config_for_platform( # Select build runner using weighted distribution build_runs_on = select_build_runner(platform, build_variant) - build_pytorch = suffix != "asan" pytorch_build_matrix: list[dict[str, str]] = [] if build_pytorch: pytorch_build_matrix = generate_pytorch_matrix_for_release_type( release_type=release_type, amdgpu_families=dist_amdgpu_families, platform=platform, + python_versions=python_versions or None, ) build_pytorch = bool(pytorch_build_matrix) @@ -1002,6 +1012,7 @@ def expand_build_configs( ci_inputs: CIInputs, test_type: str, git_context: GitContext, + build_pytorch: bool = True, prebuilt_stages: list[str] | None = None, baseline_run_id: str = "", ) -> BuildConfigs: @@ -1043,6 +1054,8 @@ def expand_build_configs( is_schedule=ci_inputs.is_schedule, is_workflow_dispatch=ci_inputs.is_workflow_dispatch, release_type=ci_inputs.release_type, + build_pytorch=build_pytorch, + python_versions=ci_inputs.python_versions, prebuilt_stages=prebuilt_stages, baseline_run_id=baseline_run_id, git_context=git_context, @@ -1149,6 +1162,7 @@ def configure(ci_inputs: CIInputs, git_context: GitContext) -> CIOutputs: targets=targets, ci_inputs=ci_inputs, test_type=jobs.test_rocm.test_type, + build_pytorch=jobs.build_pytorch.action == JobAction.RUN, prebuilt_stages=jobs.build_rocm.prebuilt_stages, baseline_run_id=jobs.build_rocm.baseline_run_id, git_context=git_context, diff --git a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py index 46da926e0e3..d7525ecec8e 100644 --- a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py +++ b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py @@ -129,12 +129,16 @@ def test_workflow_dispatch_reads_inputs_from_env(self): "WINDOWS_TEST_LABELS": "", "PREBUILT_STAGES": "compiler-runtime,runtime-tests", "BASELINE_RUN_ID": "12345", + "BUILD_PYTORCH": "false", + "PYTHON_VERSION": "3.12", }, ) self.assertEqual(inputs.linux_amdgpu_families, ["gfx94x", "gfx120x"]) self.assertEqual(inputs.linux_test_labels, ["test:rocprim"]) self.assertEqual(inputs.prebuilt_stages, "compiler-runtime,runtime-tests") self.assertEqual(inputs.baseline_run_id, "12345") + self.assertFalse(inputs.build_pytorch) + self.assertEqual(inputs.python_versions, ["3.12"]) def test_pull_request_extracts_labels(self): """PR labels are extracted from event.pull_request.labels.""" @@ -304,6 +308,15 @@ def test_all_job_groups_run(self): self.assertEqual(result.build_pytorch.action, cm.JobAction.RUN) self.assertEqual(result.test_pytorch.action, cm.JobAction.RUN) + def test_build_pytorch_input_skips_pytorch_jobs(self): + result = cm.decide_jobs( + self._inputs(build_pytorch=False), + git_context=cm.GitContext(), + ) + + self.assertEqual(result.build_pytorch.action, cm.JobAction.SKIP) + self.assertEqual(result.test_pytorch.action, cm.JobAction.SKIP) + def test_default_test_type_is_quick(self): """Default test_type for PR/push with no special conditions.""" git = cm.GitContext(changed_files=["CMakeLists.txt"]) @@ -977,6 +990,42 @@ def test_build_config_includes_pytorch_build_matrix(self): ], ) + def test_build_config_uses_requested_pytorch_python_versions(self): + targets = cm.TargetSelection( + linux_families=["gfx94x"], + windows_families=[], + ) + result = cm.expand_build_configs( + targets=targets, + ci_inputs=self._inputs( + release_type="dev", + python_versions=["3.13"], + ), + test_type="quick", + git_context=cm.GitContext(), + ) + + self.assertEqual( + {row["python_version"] for row in result.linux.pytorch_build_matrix}, + {"3.13"}, + ) + + def test_build_config_disables_pytorch_when_job_skipped(self): + targets = cm.TargetSelection( + linux_families=["gfx94x"], + windows_families=[], + ) + result = cm.expand_build_configs( + targets=targets, + ci_inputs=self._inputs(), + test_type="quick", + build_pytorch=False, + git_context=cm.GitContext(), + ) + + self.assertFalse(result.linux.build_pytorch) + self.assertEqual(result.linux.pytorch_build_matrix, []) + def test_build_config_disables_pytorch_when_all_families_are_filtered(self): targets = cm.TargetSelection( linux_families=["gfx125x"], From 8c549ca805be709aa96bd84164d8d584a20cf4e2 Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Thu, 25 Jun 2026 10:04:02 -0700 Subject: [PATCH 4/6] Cleanup tests and input ordering --- .github/workflows/setup_multi_arch.yml | 16 ++++----- .../configure_pytorch_release_matrix_test.py | 34 ++++++------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/.github/workflows/setup_multi_arch.yml b/.github/workflows/setup_multi_arch.yml index 5055bb0482e..69501bcc0ae 100644 --- a/.github/workflows/setup_multi_arch.yml +++ b/.github/workflows/setup_multi_arch.yml @@ -15,14 +15,6 @@ on: artifact bucket selection, IAM role, and package versioning. type: string default: ci - build_pytorch: - description: "Build PyTorch wheels." - type: boolean - default: true - python_version: - description: "Single Python version for wheel builds; empty uses the default matrix." - type: string - default: "" prerelease_version: description: Prerelease version number such as '2'. This gets appended to the computed version after 'rc', like '7.10.0rc2' type: string @@ -51,6 +43,14 @@ on: description: "Workflow run ID to copy prebuilt stage artifacts from." type: string default: "" + build_pytorch: + description: "Build PyTorch wheels." + type: boolean + default: true + python_version: + description: "Single Python version for wheel builds; empty uses the default matrix." + type: string + default: "" repository: description: "Repository to checkout. Defaults to github.repository." type: string diff --git a/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py index 3a3c50e8238..4cdf11cb476 100644 --- a/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py +++ b/build_tools/github_actions/tests/configure_pytorch_release_matrix_test.py @@ -19,6 +19,9 @@ def test_ci_linux_uses_reduced_matrix(self): platform="linux", ) + # Compared to releases: + # * limited to python 3.12 + # * not including "nightly" pytorch_git_ref self.assertEqual( matrix, [ @@ -47,6 +50,10 @@ def test_ci_windows_uses_reduced_matrix(self): platform="windows", ) + # Compared to releases: + # * limited to python 3.12 + # Compared to Linux: + # * limited to only a single pytorch_git_ref self.assertEqual( matrix, [ @@ -78,7 +85,7 @@ def test_explicit_versions_and_refs_narrow_matrix(self): ], ) - def test_filters_exact_unsupported_canonical_family(self): + def test_filters_exact_unsupported_family(self): matrix = m.generate_pytorch_matrix_for_release_type( release_type="dev", python_versions=["3.12"], @@ -87,29 +94,10 @@ def test_filters_exact_unsupported_canonical_family(self): platform="linux", ) + # gfx125X-dcgpu not supported on the release/2.10 ref, should filter self.assertEqual(matrix[0]["amdgpu_families"], "gfx94X-dcgpu") - - def test_filter_does_not_use_substring_matching(self): - matrix = m.generate_pytorch_matrix_for_release_type( - release_type="dev", - python_versions=["3.12"], - pytorch_git_refs=["release/2.10"], - amdgpu_families="gfx125X-dcgpu-experimental", - platform="linux", - ) - - self.assertEqual(matrix[0]["amdgpu_families"], "gfx125X-dcgpu-experimental") - - def test_rows_with_no_supported_families_are_omitted(self): - matrix = m.generate_pytorch_matrix_for_release_type( - release_type="dev", - python_versions=["3.12"], - pytorch_git_refs=["release/2.10"], - amdgpu_families="gfx125X-dcgpu", - platform="linux", - ) - - self.assertEqual(matrix, []) + matrix_families = ";".join(row["amdgpu_families"] for row in matrix) + self.assertNotIn("gfx125X", matrix_families) def test_unknown_explicit_ref_keeps_families(self): matrix = m.generate_pytorch_matrix_for_release_type( From 011d84b91d6e9584bc1a75295d45fc8850e104c4 Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Thu, 25 Jun 2026 10:08:28 -0700 Subject: [PATCH 5/6] Move inputs down in release_asan.yml --- .github/workflows/multi_arch_release_asan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/multi_arch_release_asan.yml b/.github/workflows/multi_arch_release_asan.yml index f7bc20d6bd5..746540460d9 100644 --- a/.github/workflows/multi_arch_release_asan.yml +++ b/.github/workflows/multi_arch_release_asan.yml @@ -84,10 +84,10 @@ jobs: build_variant: "asan" release_type: ${{ inputs.release_type || 'dev' }} prerelease_version: ${{ inputs.prerelease_version }} - build_pytorch: false - python_version: ${{ inputs.python_version }} linux_amdgpu_families: ${{ inputs.linux_amdgpu_families || 'all' }} windows_amdgpu_families: "none" + build_pytorch: false + python_version: ${{ inputs.python_version }} repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref }} From 5ab63abfc288f7d43f54e1efcef94ea15a5b160a Mon Sep 17 00:00:00 2001 From: Scott Todd Date: Thu, 25 Jun 2026 14:07:52 -0700 Subject: [PATCH 6/6] Stabilize PyTorch matrix empty test Avoid depending on the current real GPU-family support matrix when testing that an empty generated PyTorch matrix disables PyTorch builds. Testing: - D:/projects/TheRock/.venv/Scripts/python.exe -m pytest github_actions/tests/configure_multi_arch_ci_test.py Assisted-by: Codex --- .../tests/configure_multi_arch_ci_test.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py index c05ddf2c224..5b6acb71dad 100644 --- a/build_tools/github_actions/tests/configure_multi_arch_ci_test.py +++ b/build_tools/github_actions/tests/configure_multi_arch_ci_test.py @@ -1026,17 +1026,24 @@ def test_build_config_disables_pytorch_when_job_skipped(self): self.assertFalse(result.linux.build_pytorch) self.assertEqual(result.linux.pytorch_build_matrix, []) - def test_build_config_disables_pytorch_when_all_families_are_filtered(self): + def test_build_config_disables_pytorch_when_matrix_is_empty(self): targets = cm.TargetSelection( - linux_families=["gfx125x"], + linux_families=["gfx94x"], windows_families=[], ) - result = cm.expand_build_configs( - targets=targets, - ci_inputs=self._inputs(), - test_type="quick", - git_context=cm.GitContext(), - ) + # If the pytorch matrix is empty for some reason (such as only + # trying to build one GPU target for a pytorch version where that + # GPU target is unsupported), the build_pytorch result should be false. + with patch( + "configure_multi_arch_ci.generate_pytorch_matrix_for_release_type", + return_value=[], + ): + result = cm.expand_build_configs( + targets=targets, + ci_inputs=self._inputs(), + test_type="quick", + git_context=cm.GitContext(), + ) self.assertFalse(result.linux.build_pytorch) self.assertEqual(result.linux.pytorch_build_matrix, [])