Files
TheRock/build_tools/install_rocm_from_artifacts.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

1002 lines
33 KiB
Python

#!/usr/bin/env python
# Copyright Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
"""install_rocm_from_artifacts.py
This script helps CI workflows, developers and testing suites easily install
TheRock to their environment using artifacts. It installs TheRock to an output
directory from one of these sources:
- GitHub CI workflow run
- Release tag
- An existing installation of TheRock
Usage:
python build_tools/install_rocm_from_artifacts.py
(--artifact-group ARTIFACT_GROUP | --amdgpu_family AMDGPU_FAMILY)
[--output-dir OUTPUT_DIR]
(--run-id RUN_ID | --release RELEASE | --latest-release | --input-dir INPUT_DIR)
[--dry-run]
[--run-github-repo RUN_GITHUB_REPO]
[--aqlprofile | --no-aqlprofile]
[--blas | --no-blas]
[--debug-tools | --no-debug-tools]
[--fft | --no-fft]
[--hipdnn | --no-hipdnn]
[--hipdnn-integration-tests | --no-hipdnn-integration-tests]
[--hipdnn-samples | --no-hipdnn-samples]
[--hipfile | --no-hipfile]
[--miopen | --no-miopen]
[--miopenprovider | --no-miopenprovider]
[--hipblasltprovider | --no-hipblasltprovider]
[--hipkernelprovider | --no-hipkernelprovider]
[--prim | --no-prim]
[--rand | --no-rand]
[--rccl | --no-rccl]
[--rocshmem | --no-rocshmem]
[--rocdecode | --no-rocdecode]
[--rocjpeg | --no-rocjpeg]
[--rocjitsu | --no-rocjitsu]
[--mirage | --no-mirage]
[--rocprofiler-compute | --no-rocprofiler-compute]
[--rocprofiler-sdk | --no-rocprofiler-sdk ]
[--rocprofiler-systems | --no-rocprofiler-systems]
[--rocprofiler-systems-examples | --no-rocprofiler-systems-examples]
[--rocrtst | --no-rocrtst]
[--rocalution | --no-rocalution]
[--rocwmma | --no-rocwmma]
[--hiptensor | --no-hiptensor]
[--libhipcxx | --no-libhipcxx]
[--tests | --no-tests]
[--base-only]
Examples:
- Downloads and unpacks the gfx94X S3 artifacts from GitHub CI workflow run 14474448215
(from https://github.com/ROCm/TheRock/actions/runs/14474448215) to the
default output directory `therock-build`:
```
python build_tools/install_rocm_from_artifacts.py \
--run-id 14474448215 \
--amdgpu-family gfx94X-dcgpu \
--tests
```
- Downloads and unpacks the version `6.4.0rc20250416` gfx110X artifacts from
the multi-arch nightly tarball index to the specified output directory `build`:
```
python build_tools/install_rocm_from_artifacts.py \
--release 6.4.0rc20250416 \
--amdgpu-family gfx110X-all \
--output-dir build
```
- Downloads and unpacks the version `6.4.0.dev0+8f6cdfc0d95845f4ca5a46de59d58894972a29a9`
gfx120X artifacts from release tag `dev-tarball` to the default output directory `therock-build`:
```
python build_tools/install_rocm_from_artifacts.py \
--release 6.4.0.dev0+8f6cdfc0d95845f4ca5a46de59d58894972a29a9 \
--amdgpu-family gfx120X-all
```
- Downloads and unpacks the gfx94X S3 artifacts from GitHub CI workflow run 19644138192
(from https://github.com/ROCm/rocm-libraries/actions/runs/19644138192) in the `ROCm/rocm-libraries` repository to the
default output directory `therock-build`:
```
python build_tools/install_rocm_from_artifacts.py \
--run-id 19644138192 \
--amdgpu-family gfx94X-dcgpu \
--tests \
--run-github-repo ROCm/rocm-libraries
```
- Downloads and unpacks the latest nightly release for gfx110X:
```
python build_tools/install_rocm_from_artifacts.py \
--latest-release \
--amdgpu-family gfx110X-all
```
- Shows what would be downloaded without actually downloading (works with any mode):
```
python build_tools/install_rocm_from_artifacts.py \
--latest-release \
--amdgpu-family gfx110X-all \
--dry-run
python build_tools/install_rocm_from_artifacts.py \
--release 7.11.0a20260119 \
--amdgpu-family gfx110X-all \
--dry-run
```
You can select your AMD GPU family from therock_amdgpu_targets.cmake.
By default for CI workflow retrieval, all artifacts (excluding test artifacts)
will be downloaded. For specific artifacts, pass in the flag such as `--rand`
(RAND artifacts) For test artifacts, pass in the flag `--tests` (test artifacts).
For base artifacts only, pass in the flag `--base-only`
Note that the ARTIFACT_GROUP controls which sub-directory of the run contains
the artifacts. If not specified, it defaults to the AMDGPU_FAMILY, which was
the historic interpretation.
Note: the script will overwrite the output directory argument. If no argument
is passed, it will overwrite the default "therock-build" directory.
"""
import argparse
import boto3
from botocore import UNSIGNED
from botocore.config import Config
from datetime import datetime
from fetch_artifacts import main as fetch_artifacts_main
from _therock_utils.cmake_amdgpu_targets import amdgpu_family_map, expand_families
from _therock_utils.s3_buckets import get_release_bucket_config
from pathlib import Path
import platform
import re
import shutil
import subprocess
import sys
import tarfile
from typing import Optional
PLATFORM = platform.system().lower()
NIGHTLY_TARBALL_BUCKET = get_release_bucket_config("nightly", "tarball")
DEV_TARBALL_BUCKET = get_release_bucket_config("dev", "tarball")
MULTIARCH_TARBALL_S3_PREFIX = "v4/tarball"
s3_client = boto3.client(
"s3",
region_name=NIGHTLY_TARBALL_BUCKET.region,
config=Config(max_pool_connections=100, signature_version=UNSIGNED),
)
# A published tarball name has a structured version suffix, so this pattern
# can unambiguously separate hyphenated artifact groups from their version.
MULTIARCH_TARBALL_VERSION_PATTERN = r"\d+\.\d+\.\d+(?:(?:a|rc)\d{8}|\.dev0\+[0-9a-f]+)?"
MULTIARCH_TARBALL_NAME_PATTERN = re.compile(
r"^therock-dist-"
r"(?P<platform>linux|windows)-"
r"(?P<artifact_group>.+)-"
rf"(?P<version>{MULTIARCH_TARBALL_VERSION_PATTERN})"
r"\.tar\.gz$"
)
def parse_nightly_version(version: str) -> Optional[datetime]:
"""
Parse nightly version like '7.11.0a20251124' to extract date.
Returns datetime for sorting, None if not parseable.
"""
match = re.search(r"(\d+)\.(\d+)\.(\d+)(a|rc)(\d{4})(\d{2})(\d{2})", version)
if match:
year, month, day = int(match.group(5)), int(match.group(6)), int(match.group(7))
return datetime(year, month, day)
return None
def extract_version_from_asset_name(
asset_name: str, artifact_group: str, platform_str: str
) -> Optional[str]:
"""Extract a release version from a published multi-arch tarball name."""
match = MULTIARCH_TARBALL_NAME_PATTERN.fullmatch(asset_name)
if (
match is None
or match["platform"] != platform_str
or match["artifact_group"] != artifact_group
or match["artifact_group"].endswith("-tests")
):
return None
return match["version"]
def _multiarch_tarball_s3_key(asset_name: str) -> str:
"""Return the S3 key for a published multi-arch tarball."""
return f"{MULTIARCH_TARBALL_S3_PREFIX}/{asset_name}"
def _multiarch_tarball_asset_name(s3_key: str) -> Optional[str]:
"""Return the asset name from a published multi-arch tarball S3 key."""
key_prefix = f"{MULTIARCH_TARBALL_S3_PREFIX}/"
if not s3_key.startswith(key_prefix):
return None
return s3_key.removeprefix(key_prefix)
def _list_multiarch_nightly_tarball_objects(platform_str: str):
"""Yield nightly multi-arch tarball objects for a target platform."""
prefix = _multiarch_tarball_s3_key(f"therock-dist-{platform_str}-")
paginator = s3_client.get_paginator("list_objects_v2")
for page in paginator.paginate(Bucket=NIGHTLY_TARBALL_BUCKET.name, Prefix=prefix):
yield from page.get("Contents", [])
def list_available_nightly_gpu_families(platform_str: str = PLATFORM) -> set[str]:
"""
Query S3 to find all GPU families with multi-arch nightly releases.
Useful for error messages when an invalid GPU family is specified.
"""
families: set[str] = set()
for obj in _list_multiarch_nightly_tarball_objects(platform_str):
asset_name = _multiarch_tarball_asset_name(obj["Key"])
if asset_name is None:
continue
match = MULTIARCH_TARBALL_NAME_PATTERN.fullmatch(asset_name)
if (
match
and match["platform"] == platform_str
and not match["artifact_group"].endswith("-tests")
):
families.add(match["artifact_group"])
return families
def _fetch_and_sort_nightly_releases(
artifact_group: str,
platform_str: str = PLATFORM,
) -> list[dict]:
"""
Fetch and sort multi-arch nightly releases from S3.
Returns:
List of dicts with keys: version, asset_name, last_modified, size, parsed_date
Sorted by recency (newest first).
"""
releases: list[dict] = []
for obj in _list_multiarch_nightly_tarball_objects(platform_str):
asset_name = _multiarch_tarball_asset_name(obj["Key"])
if asset_name is None:
continue
version = extract_version_from_asset_name(
asset_name, artifact_group, platform_str
)
if version:
releases.append(
{
"version": version,
"asset_name": asset_name,
"last_modified": obj["LastModified"],
"size": obj["Size"],
"parsed_date": parse_nightly_version(version),
}
)
releases.sort(
key=lambda x: (
x["parsed_date"] if x["parsed_date"] else datetime.min,
x["last_modified"],
),
reverse=True,
)
return releases
def discover_latest_release(
artifact_group: str,
platform_str: str = PLATFORM,
) -> Optional[tuple[str, str]]:
"""
Query S3 to find the latest multi-arch nightly release for an artifact group.
Returns:
Tuple of (version_string, full_asset_name) or None if not found.
"""
releases = _fetch_and_sort_nightly_releases(artifact_group, platform_str)
if not releases:
return None
return (releases[0]["version"], releases[0]["asset_name"])
def log(*args, **kwargs):
print(*args, **kwargs)
sys.stdout.flush()
def _untar_files(output_dir: Path, destination: Path):
"""
Retrieves all tar files in the output_dir, then extracts all files to the output_dir
"""
log(f"Extracting {destination.name} to {str(output_dir)}")
with tarfile.open(destination) as extracted_tar_file:
extracted_tar_file.extractall(output_dir, filter="tar")
destination.unlink()
def _create_output_directory(output_dir: Path):
"""
If the output directory already exists, delete it and its contents.
Then, create the output directory.
"""
log(f"Creating output directory '{output_dir.resolve()}'")
if output_dir.is_dir():
log(
f"Directory '{output_dir}' already exists, removing existing directory and files"
)
shutil.rmtree(output_dir)
output_dir.mkdir(parents=True)
log(f"Created output directory '{output_dir.resolve()}'")
def _retrieve_multiarch_tarball(
release_bucket: str,
asset_name: str,
output_dir: Path,
) -> None:
"""Download a multi-arch tarball from S3, then extract it."""
s3_key = _multiarch_tarball_s3_key(asset_name)
destination = output_dir / asset_name
log(f"Downloading s3://{release_bucket}/{s3_key}")
with open(destination, "wb") as file:
s3_client.download_fileobj(release_bucket, s3_key, file)
_untar_files(output_dir, destination)
def retrieve_artifacts_by_run_id(args):
"""
If the user requested TheRock artifacts by CI (run ID), this function will retrieve those assets
"""
run_id = args.run_id
log(f"Retrieving artifacts for run ID {run_id}")
argv = [
"--run-id",
run_id,
"--artifact-group",
args.artifact_group,
"--output-dir",
str(args.output_dir),
"--flatten",
]
if args.amdgpu_targets:
argv.extend(["--amdgpu-targets", args.amdgpu_targets])
else:
# Auto-derive gfx targets from the family so a family-only install also
# fetches per-target (kpack-split) shards. In split runs the per-target
# shard carries data the family/'generic' shards lack (e.g. MIOpen
# tuning DBs under share/miopen/db); without these targets the fetch
# matches only the family literal and 'generic', silently dropping them.
derived_targets = expand_families(
[args.artifact_group], amdgpu_family_map(), strict=False
)
if derived_targets:
log(
f"Auto-deriving --amdgpu-targets from family "
f"'{args.artifact_group}': {','.join(derived_targets)}"
)
argv.extend(["--amdgpu-targets", ",".join(derived_targets)])
if args.dry_run:
argv.append("--dry-run")
if args.run_github_repo:
argv.extend(["--run-github-repo", args.run_github_repo])
# These artifacts are the "base" requirements for running tests.
base_artifact_patterns = [
"core-hipinfo_run",
"core-runtime_run",
"core-runtime_lib",
"rocjitsu-hotswap_lib",
"sysdeps_lib",
"base_run",
"base_lib",
"amd-llvm_run",
"amd-llvm_lib",
"core-amdsmi_run",
"core-amdsmi_lib",
"core-hip_lib",
"core-hip_dev",
"core-kpack_lib",
"core-ocl_lib",
"core-ocl_dev",
"rocprofiler-sdk_lib",
"host-suite-sparse_lib",
]
if args.base_only:
argv.extend(base_artifact_patterns)
elif any(
[
args.aqlprofile,
args.blas,
args.debug_tools,
args.fft,
args.hipdnn,
args.hipdnn_integration_tests,
args.hipdnn_samples,
args.hipfile,
args.miopen,
args.miopenprovider,
args.hiptensor,
args.hipblasltprovider,
args.hipkernelprovider,
args.prim,
args.mpi,
args.rand,
args.rccl,
args.rocshmem,
args.rocdecode,
args.rocjpeg,
args.rocjitsu,
args.mirage,
args.rocprofiler_compute,
args.rocprofiler_sdk,
args.rocprofiler_systems,
args.rocprofiler_systems_examples,
args.rocrtst,
args.rocalution,
args.rocwmma,
args.libhipcxx,
]
):
argv.extend(base_artifact_patterns)
extra_artifacts = []
if args.aqlprofile:
extra_artifacts.append("aqlprofile")
if args.blas:
extra_artifacts.append("blas")
if args.debug_tools:
extra_artifacts.append("amd-dbgapi")
extra_artifacts.append("rocgdb")
extra_artifacts.append("rocr-debug-agent")
extra_artifacts.append("rocr-debug-agent-tests")
# Contains the rocgdb executable.
argv.append("rocgdb_run")
# Libraries rocgdb depends on.
extra_artifacts.append("gmp")
extra_artifacts.append("mpfr")
extra_artifacts.append("expat")
extra_artifacts.append("ncurses")
# rocgdb tests require amd-llvm_dev for compiler headers/tools.
argv.append("amd-llvm_dev")
if args.fft:
extra_artifacts.append("fft")
extra_artifacts.append("fftw3")
if args.hipdnn:
extra_artifacts.append("hipdnn")
if args.hipdnn_integration_tests:
extra_artifacts.append("hipdnn-integration-tests")
# The main test binary `hipdnn_integration_tests` is in the artifact's
# _run component (per ml-libs/artifact-hipdnn-integration-tests.toml).
# Provider cross-provider integration suites (e.g. miopenprovider's
# external-integration-check) invoke it with --test-article and
# --test-engine; without _run, ctest finds the entry but errors with
# "Unable to find executable: ../hipdnn_integration_tests".
argv.append("hipdnn-integration-tests_run")
if args.hipdnn_samples:
extra_artifacts.append("hipdnn-samples")
if args.hipfile:
extra_artifacts.append("hipfile")
extra_artifacts.append("sysdeps-util-linux")
if args.miopen:
extra_artifacts.append("miopen")
# Contains bin/MIOpenDriver executable for tests.
argv.append("miopen_run")
# Also need these for runtime kernel compilation (rocrand includes).
argv.append("rand_dev")
if args.miopenprovider:
extra_artifacts.append("miopenprovider")
if args.hipkernelprovider:
extra_artifacts.append("hipkernelprovider")
if args.hiptensor:
extra_artifacts.append("hiptensor")
if args.rocdecode:
extra_artifacts.append("sysdeps-amd-mesa")
extra_artifacts.append("rocdecode")
argv.append("rocdecode_dev")
argv.append("rocdecode_test")
argv.append("base_dev")
argv.append("amd-llvm_dev")
if args.mpi:
extra_artifacts.append("openmpi")
# Ensure binaries like mpiexec are installed
argv.append("openmpi_run")
# Optional but useful (headers, dev libs)
argv.append("openmpi_dev")
if args.rocjpeg:
extra_artifacts.append("sysdeps-amd-mesa")
extra_artifacts.append("rocjpeg")
argv.append("rocjpeg_dev")
argv.append("rocjpeg_test")
argv.append("base_dev")
argv.append("amd-llvm_dev")
if args.rocjitsu:
extra_artifacts.append("rocjitsu")
argv.append("rocjitsu_run")
if args.mirage:
extra_artifacts.append("mirage")
argv.append("mirage_run")
if args.hipblasltprovider:
extra_artifacts.append("hipblasltprovider")
if args.prim:
extra_artifacts.append("prim")
if args.rand:
extra_artifacts.append("rand")
if args.rccl:
extra_artifacts.append("rccl")
if args.rocshmem:
extra_artifacts.append("rocshmem")
# The functional test binary (bin/rocshmem_functional_tests) and
# bin/rocshmem_info live in the _run component; the install-tree
# CTestTestfile.cmake references them via relative paths.
argv.append("rocshmem_run")
# rocSHMEM tests launch via mpirun and link against TheRock's
# vendored OpenMPI, so pull it (with its run component for mpiexec).
extra_artifacts.append("openmpi")
argv.append("openmpi_run")
if args.rocprofiler_sdk:
extra_artifacts.append("rocprofiler-sdk")
extra_artifacts.append("aqlprofile")
# Contains rocprofiler-sdk-rocpd
argv.append("rocprofiler-sdk_run")
if args.rocprofiler_compute:
extra_artifacts.append("rocprofiler-compute")
# Contains the rocprof-compute CLI executable.
argv.append("rocprofiler-compute_run")
if args.rocprofiler_systems:
extra_artifacts.append("rocprofiler-systems")
# Contains executables (rocprof-sys-run, rocprof-sys-instrument, etc.)
argv.append("rocprofiler-systems_run")
if args.tests:
# Tests need version.h for rocprofiler-sdk version detection.
argv.append("rocprofiler-sdk_dev")
if args.rocprofiler_systems_examples:
# Only a _test artifact is produced
argv.append("rocprofiler-systems-examples_test")
if args.rocrtst:
extra_artifacts.append("rocrtst")
# rocrtst depends on sysdeps-hwloc (which depends on sysdeps-libpciaccess)
extra_artifacts.append("sysdeps-hwloc")
extra_artifacts.append("sysdeps-libpciaccess")
if args.rocalution:
extra_artifacts.append("rocalution")
argv.append("rocalution_dev")
if args.rocwmma:
extra_artifacts.append("rocwmma")
argv.append("rocwmma_dev")
if args.libhipcxx:
extra_artifacts.append("libhipcxx")
argv.append("amd-llvm_dev")
argv.append("amd-llvm_lib")
argv.append("base_dev_generic")
# Fetch _lib (always) and _test (when --tests) for each artifact.
# Some projects have self-contained _test archives (just test
# binaries), while others may also need executables or data from
# _run. Add those explicitly above via argv.append("<name>_run").
extra_artifact_patterns = [f"{a}_lib" for a in extra_artifacts]
if args.tests:
extra_artifact_patterns.extend([f"{a}_test" for a in extra_artifacts])
argv.extend(extra_artifact_patterns)
else:
# No include (or exclude) patterns, so all artifacts will be fetched.
pass
log(f"\nCalling fetch_artifacts_main with args:\n {' '.join(argv)}\n")
fetch_artifacts_main(argv)
log(f"Retrieved artifacts for run ID {run_id}")
def retrieve_artifacts_by_release(args):
"""
If the user requested TheRock artifacts by release version, this function will retrieve those assets
"""
output_dir = args.output_dir
artifact_group = args.artifact_group
nightly_regex_expression = r"\d+\.\d+\.\d+(?:a|rc)\d{8}"
dev_regex_expression = r"\d+\.\d+\.\d+\.dev0\+[0-9a-f]+"
nightly_release = re.fullmatch(nightly_regex_expression, args.release) is not None
dev_release = re.fullmatch(dev_regex_expression, args.release) is not None
if not nightly_release and not dev_release:
log("This script requires a nightly or dev release version.")
log("Please retrieve the correct release version from:")
log(
"\t - https://rocm.nightlies.amd.com/tarball-multi-arch/ (nightly examples: 6.4.0rc20250416, 7.10.0a20251024)"
)
log(
"\t - https://rocm.devreleases.amd.com/tarball-multi-arch/ (dev-tarball example: 6.4.0.dev0+8f6cdfc0d95845f4ca5a46de59d58894972a29a9)"
)
log("Exiting...")
return
release_version = args.release
asset_name = f"therock-dist-{PLATFORM}-{artifact_group}-{release_version}.tar.gz"
release_bucket = NIGHTLY_TARBALL_BUCKET if nightly_release else DEV_TARBALL_BUCKET
release_kind = "nightly" if nightly_release else "dev"
log(
f"Retrieving {release_kind} multi-arch artifacts from "
f"s3://{release_bucket.name}/{MULTIARCH_TARBALL_S3_PREFIX}/"
)
if args.dry_run:
log(
f"[DRY RUN] Would download: s3://{release_bucket.name}/"
f"{_multiarch_tarball_s3_key(asset_name)} "
f"(asset {asset_name}, version {release_version})"
)
return
_retrieve_multiarch_tarball(release_bucket.name, asset_name, output_dir)
def retrieve_artifacts_by_input_dir(args):
input_dir = args.input_dir
output_dir = args.output_dir
log(f"Retrieving artifacts from input dir {input_dir}")
if args.dry_run:
log(f"[DRY RUN] Would rsync from {input_dir} to {output_dir}")
return
# Check to make sure rsync exists
if not shutil.which("rsync"):
log("Error: rsync command not found.")
if platform.system() == "Windows":
log("Please install rsync via MSYS2 or WSL to your Windows system")
return
cmd = [
"rsync",
"-azP", # archive, compress and progress indicator
input_dir,
output_dir,
]
try:
subprocess.run(cmd, check=True)
log(f"Retrieved artifacts from input dir {input_dir} to {output_dir}")
except Exception as ex:
# rsync is not available
log(f"Error when running [{cmd}]")
log(str(ex))
def retrieve_artifacts_by_latest_release(args):
"""
Find and retrieve the latest multi-arch nightly release from S3.
"""
log(f"Finding latest nightly release for {args.artifact_group}...")
result = discover_latest_release(artifact_group=args.artifact_group)
if result is None:
log(f"ERROR: No nightly release found for '{args.artifact_group}'")
log("")
log("Available GPU families in the multi-arch nightly bucket:")
available = list_available_nightly_gpu_families()
for family in sorted(available):
log(f" - {family}")
sys.exit(1)
version, asset_name = result
log(f"Found latest release: {version}")
if args.dry_run:
log(f"[DRY RUN] Would download: {asset_name} (version {version})")
return
_retrieve_multiarch_tarball(
NIGHTLY_TARBALL_BUCKET.name,
asset_name,
args.output_dir,
)
def run(args):
log("### Installing TheRock using artifacts ###")
# Skip directory creation for dry-run
if not args.dry_run:
_create_output_directory(args.output_dir)
if args.run_id:
retrieve_artifacts_by_run_id(args)
elif args.release:
retrieve_artifacts_by_release(args)
elif args.latest_release:
retrieve_artifacts_by_latest_release(args)
if args.input_dir:
retrieve_artifacts_by_input_dir(args)
def main(argv):
parser = argparse.ArgumentParser(prog="provision")
parser.add_argument(
"--output-dir",
type=Path,
default="./therock-build",
help="Path of the output directory for TheRock",
)
artifact_group_parser = parser.add_mutually_exclusive_group(required=True)
artifact_group_parser.add_argument(
"--artifact-group",
dest="artifact_group",
type=str,
help="Explicit artifact group to install",
)
artifact_group_parser.add_argument(
"--amdgpu-family",
dest="artifact_group",
type=str,
help="AMD GPU family to install (please refer to this: https://github.com/ROCm/TheRock/blob/59c324a759e8ccdfe5a56e0ebe72a13ffbc04c1f/cmake/therock_amdgpu_targets.cmake#L44-L81 for family choices)",
)
# This mutually exclusive group will ensure that only one argument is present
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--run-id", type=str, help="GitHub run ID of TheRock to install")
group.add_argument(
"--release",
type=str,
help="Release version of TheRock to install, from the multi-arch nightly tarball index (X.Y.ZrcYYYYMMDD) or dev-tarball (X.Y.Z.dev0+{hash})",
)
group.add_argument(
"--latest-release",
action="store_true",
help="Install the latest nightly release (built daily from main branch)",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Show what would be downloaded/copied without actually doing it",
)
artifacts_group = parser.add_argument_group("artifacts_group")
artifacts_group.add_argument(
"--aqlprofile",
default=False,
help="Include 'aqlprofile' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--blas",
default=False,
help="Include 'blas' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--debug-tools",
default=False,
help="Include ROCm debugging tools (amd-dbgapi, rocgdb and rocr_debug_agent) artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--fft",
default=False,
help="Include 'fft' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipdnn",
default=False,
help="Include 'hipdnn' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipdnn-integration-tests",
default=False,
help="Include 'hipdnn-integration-tests' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipdnn-samples",
default=False,
help="Include 'hipdnn-samples' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipfile",
default=False,
help="Include 'hipfile' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--miopen",
default=False,
help="Include 'miopen' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--miopenprovider",
default=False,
help="Include 'miopenprovider' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipkernelprovider",
default=False,
help="Include 'hipkernelprovider' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hiptensor",
default=False,
help="Include 'hiptensor' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocdecode",
default=False,
help="Include 'rocdecode' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocjpeg",
default=False,
help="Include 'rocjpeg' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocjitsu",
default=False,
help="Include 'rocjitsu' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--mirage",
default=False,
help="Include 'mirage' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--hipblasltprovider",
default=False,
help="Include 'hipblasltprovider' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--prim",
default=False,
help="Include 'prim' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rand",
default=False,
help="Include 'rand' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rccl",
default=False,
help="Include 'rccl' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocshmem",
default=False,
help="Include 'rocshmem' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--mpi",
default=False,
help="Include OpenMPI (vendored by TheRock build)",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocprofiler-compute",
default=False,
help="Include 'rocprofiler-compute' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocprofiler-sdk",
default=False,
help="Include 'rocprofiler-sdk' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocprofiler-systems",
default=False,
help="Include 'rocprofiler-systems' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocprofiler-systems-examples",
default=False,
help="Include 'rocprofiler-systems-examples' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocrtst",
default=False,
help="Include 'rocrtst' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocalution",
default=False,
help="Include 'rocalution' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--rocwmma",
default=False,
help="Include 'rocwmma' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--libhipcxx",
default=False,
help="Include 'libhipcxx' artifacts",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--tests",
default=False,
help="Include all test artifacts for enabled libraries",
action=argparse.BooleanOptionalAction,
)
artifacts_group.add_argument(
"--base-only", help="Include only base artifacts", action="store_true"
)
group.add_argument(
"--input-dir",
type=str,
help="Pass in an existing directory of TheRock to provision and test",
)
parser.add_argument(
"--amdgpu-targets",
type=str,
default="",
help="Comma-separated individual GPU targets for fetching split artifacts (e.g. 'gfx942')",
)
parser.add_argument(
"--run-github-repo",
type=str,
help="GitHub repository for --run-id in 'owner/repo' format (e.g. 'ROCm/TheRock'). Defaults to GITHUB_REPOSITORY env var or 'ROCm/TheRock'",
)
args = parser.parse_args(argv)
if not args.artifact_group:
raise argparse.ArgumentTypeError(
"Either --amdgpu-family or --artifact-group must be specified"
)
run(args)
if __name__ == "__main__":
main(sys.argv[1:])