| #!/usr/bin/env bash |
| |
| # Copyright 2026 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| # Reconfigures a regular IREE build for one or more ROCm test targets and runs |
| # its HIP e2e tests under rocjitsu. Expects to be run from the root of the IREE |
| # repository after build_tools/cmake/build_all.sh has populated BUILD_DIR. |
| # |
| # Requires an initialized ROCm SDK containing rocjitsu. Install the |
| # SDK separately and set ROCM_ROOT; this script does not install dependencies. |
| # Set IREE_ROCM_TEST_TARGET_CHIP to the first target when running build_all.sh |
| # to include its test modules in the initial build. |
| |
| set -euo pipefail |
| |
| SOURCE_DIR="$(pwd)" |
| BUILD_DIR="${1:-${IREE_BUILD_DIR:-build}}" |
| if (($#)); then |
| shift |
| fi |
| |
| if [[ ! -f "${SOURCE_DIR}/CMakeLists.txt" || |
| ! -x "${SOURCE_DIR}/build_tools/cmake/build_all.sh" ]]; then |
| echo "error: run this script from the root of the IREE repository" >&2 |
| exit 2 |
| fi |
| |
| readonly -a ALL_TARGETS=(gfx942 gfx950 gfx1100 gfx1201 gfx1250) |
| declare -Ar ROCJITSU_CONFIGS=( |
| [gfx942]="gfx942_cdna3.json" |
| [gfx950]="gfx950_mi355x.json" |
| [gfx1100]="gfx1100_w7900.json" |
| [gfx1201]="gfx1201_r9700.json" |
| [gfx1250]="gfx1250_mi455x.json" |
| ) |
| declare -Ar INCOMPATIBLE_GPU_LABELS=( |
| [gfx942]='^requires-gpu-(cdna4|rdna3|rdna4|gfx1250)$' |
| [gfx950]='^requires-gpu-(cdna3|rdna3|rdna4|gfx1250)$' |
| [gfx1100]='^requires-gpu-(cdna3|cdna4|rdna4|gfx1250)$' |
| [gfx1201]='^requires-gpu-(cdna3|cdna4|rdna3|gfx1250)$' |
| [gfx1250]='^requires-gpu-(cdna3|cdna4|rdna3|rdna4|wave64)$' |
| ) |
| |
| usage() { |
| cat <<'EOF' |
| Usage: build_tools/cmake/test_rocm_targets_with_rocjitsu.sh [BUILD_DIR] [TARGET ...] |
| |
| Reconfigures an existing regular IREE build and runs its ROCm e2e tests under |
| rocjitsu. Supported targets: |
| gfx942 gfx950 gfx1100 gfx1201 gfx1250 |
| |
| BUILD_DIR defaults to IREE_BUILD_DIR or "build". With no target arguments, all |
| supported targets are built and tested sequentially in the same build tree. |
| |
| Requires an initialized ROCm SDK containing rocjitsu. Install the |
| SDK separately, run rocm-sdk init, and set ROCM_ROOT to its root directory. |
| Set IREE_ROCM_TEST_TARGET_CHIP to the first target when running build_all.sh |
| to include its test modules in the initial build. |
| |
| Runs one parallel CTest invocation per target. CTest prints test progress and |
| output on failure; the target's log directory contains the log and JUnit report. |
| Each test process uses an independent simulator so concurrent tests do not |
| contend for a shared emulated GPU. |
| |
| Configuration: |
| IREE_ROCJITSU_WORK_DIR Logs and simulator runtime state. |
| IREE_ROCJITSU_RUN_ID Override the log and simulator runtime run ID. |
| ROCM_ROOT Required: root of an initialized ROCm SDK. |
| ROCJITSU_BIN Override the rocjitsu CLI executable. |
| ROCJITSU_CONFIG_DIR Override the rocjitsu config directory. |
| CTEST_PARALLEL_LEVEL Test concurrency (default: 8). |
| IREE_ROCJITSU_TEST_TIMEOUT Default timeout in seconds for tests without an |
| explicit CMake TIMEOUT value (default: 180). |
| IREE_ROCJITSU_SESSION_TIMEOUT |
| Whole-session watchdog in seconds (default: 1800). |
| IREE_ROCJITSU_TESTS_REGEX Include only tests matching this CTest regex. |
| IREE_ROCJITSU_EXCLUDE_TESTS_REGEX |
| Exclude tests matching this CTest regex. |
| IREE_ROCJITSU_EXCLUDE_LABEL_REGEX |
| Exclude tests with labels matching this regex |
| (default: ^very-expensive$; use ^$ to disable). |
| |
| Examples: |
| export ROCM_ROOT="$(rocm-sdk path --root)" |
| build_tools/cmake/test_rocm_targets_with_rocjitsu.sh build gfx1250 |
| build_tools/cmake/test_rocm_targets_with_rocjitsu.sh build |
| ROCM_ROOT=/path/to/rocm-sdk \ |
| build_tools/cmake/test_rocm_targets_with_rocjitsu.sh build gfx942 gfx950 |
| EOF |
| } |
| |
| if [[ "${BUILD_DIR}" == "--help" || "${BUILD_DIR}" == "-h" ]]; then |
| usage |
| exit 0 |
| fi |
| |
| if [[ -z "${ROCM_ROOT:-}" ]]; then |
| echo "error: set ROCM_ROOT to an initialized ROCm SDK containing rocjitsu" >&2 |
| exit 2 |
| fi |
| |
| if [[ ! -f "${BUILD_DIR}/CMakeCache.txt" ]]; then |
| echo "error: ${BUILD_DIR} is not a configured IREE build directory" >&2 |
| echo "Run build_tools/cmake/build_all.sh ${BUILD_DIR} first." >&2 |
| exit 2 |
| fi |
| BUILD_DIR="$(realpath "${BUILD_DIR}")" |
| |
| WORK_DIR="${IREE_ROCJITSU_WORK_DIR:-${BUILD_DIR}/rocjitsu}" |
| CTEST_PARALLEL_LEVEL="${CTEST_PARALLEL_LEVEL:-8}" |
| TEST_TIMEOUT="${IREE_ROCJITSU_TEST_TIMEOUT:-180}" |
| SESSION_TIMEOUT="${IREE_ROCJITSU_SESSION_TIMEOUT:-1800}" |
| EXCLUDE_LABEL_REGEX="${IREE_ROCJITSU_EXCLUDE_LABEL_REGEX:-^very-expensive$}" |
| RUN_ID="${IREE_ROCJITSU_RUN_ID:-$(date +%Y%m%d-%H%M%S)-$$}" |
| |
| if (($#)); then |
| TARGETS=("$@") |
| else |
| TARGETS=("${ALL_TARGETS[@]}") |
| fi |
| |
| for target in "${TARGETS[@]}"; do |
| if [[ -z "${ROCJITSU_CONFIGS[${target}]+x}" ]]; then |
| echo "error: unsupported target '${target}'" >&2 |
| usage >&2 |
| exit 2 |
| fi |
| done |
| |
| declare -a CTEST_BASE_FILTER_ARGS=( |
| -L '^driver=hip$' |
| -L '^iree/tests/e2e/' |
| ) |
| if [[ -n "${IREE_ROCJITSU_TESTS_REGEX:-}" ]]; then |
| CTEST_BASE_FILTER_ARGS+=(-R "${IREE_ROCJITSU_TESTS_REGEX}") |
| fi |
| if [[ -n "${IREE_ROCJITSU_EXCLUDE_TESTS_REGEX:-}" ]]; then |
| CTEST_BASE_FILTER_ARGS+=(-E "${IREE_ROCJITSU_EXCLUDE_TESTS_REGEX}") |
| fi |
| |
| require_cache_setting() { |
| local setting="$1" |
| if ! grep -q "^${setting}:BOOL=ON$" "${BUILD_DIR}/CMakeCache.txt"; then |
| echo "error: regular build must have ${setting}=ON" >&2 |
| exit 2 |
| fi |
| } |
| |
| require_cache_setting IREE_BUILD_TESTS |
| require_cache_setting IREE_BUILD_COMPILER |
| require_cache_setting IREE_HAL_DRIVER_HIP |
| require_cache_setting IREE_TARGET_BACKEND_ROCM |
| if ! grep -q '^CMAKE_GENERATOR:INTERNAL=Ninja$' "${BUILD_DIR}/CMakeCache.txt"; then |
| echo "error: this script expects the regular CI Ninja build" >&2 |
| exit 2 |
| fi |
| |
| mkdir -p "${WORK_DIR}" |
| |
| ROCM_ROOT="$(realpath "${ROCM_ROOT}")" |
| export ROCM_ROOT |
| |
| if [[ -z "${ROCJITSU_BIN:-}" ]]; then |
| if [[ -x "${ROCM_ROOT}/bin/rocjitsu" ]]; then |
| ROCJITSU_BIN="${ROCM_ROOT}/bin/rocjitsu" |
| else |
| ROCJITSU_BIN="${ROCM_ROOT}/bin/mirage" |
| fi |
| fi |
| ROCJITSU_CONFIG_DIR="${ROCJITSU_CONFIG_DIR:-${ROCM_ROOT}/share/rocjitsu/configs}" |
| if [[ ! -x "${ROCJITSU_BIN}" ]]; then |
| echo "error: rocjitsu CLI not found at ${ROCJITSU_BIN}" >&2 |
| echo "Install a nightly that includes a simulator CLI or set ROCJITSU_BIN." >&2 |
| exit 2 |
| fi |
| case "$(basename "${ROCJITSU_BIN}")" in |
| mirage) ROCJITSU_CLI_KIND="session" ;; |
| *) ROCJITSU_CLI_KIND="legacy" ;; |
| esac |
| if [[ ! -f "${ROCM_ROOT}/lib/libamdhip64.so" ]]; then |
| echo "error: HIP runtime not found under ${ROCM_ROOT}/lib" >&2 |
| exit 2 |
| fi |
| |
| echo "IREE build: ${BUILD_DIR}" |
| echo "ROCm SDK root: ${ROCM_ROOT}" |
| echo "Simulator CLI: ${ROCJITSU_BIN} ($("${ROCJITSU_BIN}" --version))" |
| echo "Targets: ${TARGETS[*]}" |
| |
| declare -a passed_targets=() |
| declare -a build_failed_targets=() |
| declare -a test_failed_targets=() |
| |
| for target in "${TARGETS[@]}"; do |
| config_path="${ROCJITSU_CONFIG_DIR}/${ROCJITSU_CONFIGS[${target}]}" |
| runtime_dir="${WORK_DIR}/runtime/${RUN_ID}/${target}" |
| log_dir="${WORK_DIR}/logs/${RUN_ID}/${target}" |
| mkdir -p "${runtime_dir}" "${log_dir}" |
| |
| label_exclude_regex="${INCOMPATIBLE_GPU_LABELS[${target}]}" |
| if [[ -n "${EXCLUDE_LABEL_REGEX}" ]]; then |
| label_exclude_regex="(${label_exclude_regex})|(${EXCLUDE_LABEL_REGEX})" |
| fi |
| target_ctest_filter_args=( |
| "${CTEST_BASE_FILTER_ARGS[@]}" |
| -LE "${label_exclude_regex}" |
| ) |
| |
| if [[ ! -f "${config_path}" ]]; then |
| echo "error: rocjitsu config not found: ${config_path}" >&2 |
| build_failed_targets+=("${target} (missing config)") |
| continue |
| fi |
| |
| echo |
| echo "=== Retargeting regular IREE build for ${target} ===" |
| # Bash disables errexit inside conditional subshells, so propagate failures |
| # explicitly instead of letting the final CTest listing mask a failed build. |
| if ( |
| cmake \ |
| -S "${SOURCE_DIR}" \ |
| -B "${BUILD_DIR}" \ |
| "-DIREE_NATIVE_TEST_TIMEOUT_DEFAULT=${TEST_TIMEOUT}" \ |
| "-DIREE_ROCM_TEST_TARGET_CHIP=${target}" || exit 1 |
| cmake --build "${BUILD_DIR}" --target iree-test-deps -- -k 0 || exit 1 |
| ctest \ |
| --test-dir "${BUILD_DIR}" \ |
| --show-only=human \ |
| "${target_ctest_filter_args[@]}" |
| ) 2>&1 | tee "${log_dir}/build.log"; then |
| echo "Built ${target} ROCm test dependencies" |
| else |
| build_failed_targets+=("${target}") |
| continue |
| fi |
| |
| echo |
| if ( |
| export IREE_HIP_DYLIB_PATH="${ROCM_ROOT}/lib" |
| export LD_LIBRARY_PATH="${ROCM_ROOT}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" |
| ctest_bin="$(command -v ctest)" || exit 1 |
| ctest_command=( |
| "${ctest_bin}" |
| --test-dir "${BUILD_DIR}" |
| --parallel "${CTEST_PARALLEL_LEVEL}" |
| --timeout "${TEST_TIMEOUT}" |
| --output-on-failure |
| --no-tests=error |
| --output-junit "${log_dir}/ctest.xml" |
| "${target_ctest_filter_args[@]}" |
| ) |
| if [[ "${ROCJITSU_CLI_KIND}" == "session" ]]; then |
| session_runtime_dir="$(mktemp -d "${TMPDIR:-/tmp}/iree-rocjitsu-${target}.XXXXXX")" || exit 1 |
| cleanup_session_runtime() { |
| rm -rf -- "${session_runtime_dir}" || exit 1 |
| } |
| trap cleanup_session_runtime EXIT |
| export MIRAGE_RUNTIME="${session_runtime_dir}" |
| # Independent tests need no shared GPU state. Give each CTest child its |
| # own simulator instead of contending for a single daemon's workers. |
| timeout \ |
| --signal=TERM \ |
| --kill-after=30 \ |
| "${SESSION_TIMEOUT}" \ |
| "${ROCJITSU_BIN}" run \ |
| --in-process \ |
| --config "${config_path}" \ |
| --workdir "${BUILD_DIR}" \ |
| --env "IREE_HIP_DYLIB_PATH=${IREE_HIP_DYLIB_PATH}" \ |
| --env "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" \ |
| -- "${ctest_command[@]}" |
| else |
| export ROCJITSU_RUNTIME_DIR="${runtime_dir}" |
| "${ROCJITSU_BIN}" --config "${config_path}" -- "${ctest_command[@]}" |
| fi |
| ) 2>&1 | tee "${log_dir}/ctest.log"; then |
| passed_targets+=("${target}") |
| else |
| test_failed_targets+=("${target}") |
| fi |
| done |
| |
| echo |
| echo "=== Rocjitsu ROCm e2e summary ===" |
| echo "Passed: ${passed_targets[*]:-none}" |
| echo "Build failed: ${build_failed_targets[*]:-none}" |
| echo "Test failed: ${test_failed_targets[*]:-none}" |
| echo "Logs: ${WORK_DIR}/logs/${RUN_ID}" |
| |
| if ((${#build_failed_targets[@]} || ${#test_failed_targets[@]})); then |
| exit 1 |
| fi |