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
171 lines
6.3 KiB
Bash
Executable File
171 lines
6.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run the RCCL device-API benchmark suite (symmetric memory / LSA device kernels
|
|
# / GIN proxy) against the freshly built rccl-tests tree. Mirrors the legacy
|
|
# rocJenkins "device-api" testCommand.
|
|
#
|
|
# Consumes ROCM_PATH (rocm.env), MPI_HOME (ompi.env), the in-tree RCCL build at
|
|
# projects/rccl/build/release, and rccl-tests/build. ROCM_PATH / MPI_HOME come
|
|
# from the environment (device-api.sbatch exports them) or, when run standalone,
|
|
# from $WORKDIR/.ci-out/{rocm,ompi}.env.
|
|
#
|
|
# Each bench is wrapped in `timeout` so a hung mpirun/driver can't wedge the job;
|
|
# failures are collected and surfaced at the end (exit non-zero iff any failed).
|
|
#
|
|
# Test matrix lives in lib/device-api-tests.json; RCCL_CI_DEBUG=1 adds its
|
|
# debug_env to every run.
|
|
#
|
|
# Environment overrides:
|
|
# ROCM_PATH / MPI_HOME Else read from .ci-out/{rocm,ompi}.env
|
|
# NP MPI ranks per run (default: 8)
|
|
# BENCH_ARGS Common bench args (default: from JSON bench_args)
|
|
# BENCH_TIMEOUT Per-bench wall-clock cap (default: 600s)
|
|
# BENCH_KILL_AFTER SIGKILL grace after BENCH_TIMEOUT (default: 30s)
|
|
# CONFIG Test-matrix JSON (default: lib/device-api-tests.json)
|
|
# RCCL_CI_DEBUG Set to 1 to add debug_env to every run
|
|
# RCCL_CI_DEBUG_DIR Dir for NCCL_DEBUG_FILE output when RCCL_CI_DEBUG=1
|
|
# (default: ${SLURM_SUBMIT_DIR:-$PWD}/nccl-debug)
|
|
|
|
set -euo pipefail
|
|
|
|
NP="${NP:-8}"
|
|
BENCH_TIMEOUT="${BENCH_TIMEOUT:-600s}"
|
|
BENCH_KILL_AFTER="${BENCH_KILL_AFTER:-30s}"
|
|
|
|
script_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
RCCL_DIR="$(cd "${script_dir}/../.." && pwd)"
|
|
WORKDIR="$(cd "${RCCL_DIR}/../.." && pwd)"
|
|
|
|
RCCL_LIB_DIR="${WORKDIR}/projects/rccl/build/release"
|
|
RCCL_TESTS_DIR="${WORKDIR}/projects/rccl-tests"
|
|
CONFIG="${CONFIG:-${script_dir}/lib/device-api-tests.json}"
|
|
|
|
# Prefer the build stages' env fragments over any ambient ROCM_PATH / MPI_HOME.
|
|
# shellcheck source=/dev/null # runtime fragment written by fetch-rocm.sh
|
|
[[ -f "${WORKDIR}/.ci-out/rocm.env" ]] && source "${WORKDIR}/.ci-out/rocm.env"
|
|
# shellcheck source=/dev/null # runtime fragment written by build-ompi.sh
|
|
[[ -f "${WORKDIR}/.ci-out/ompi.env" ]] && source "${WORKDIR}/.ci-out/ompi.env"
|
|
|
|
: "${ROCM_PATH:?run-device-api-ci.sh: ROCM_PATH unset (run fetch-rocm.sh / via sbatch)}"
|
|
: "${MPI_HOME:?run-device-api-ci.sh: MPI_HOME unset (run build-ompi.sh / via sbatch)}"
|
|
|
|
if [[ ! -x "${ROCM_PATH}/bin/hipcc" ]]; then
|
|
echo "ERROR: ROCM_PATH=${ROCM_PATH} does not look like a ROCm tree (no bin/hipcc)" >&2
|
|
exit 1
|
|
fi
|
|
if [[ ! -f "${MPI_HOME}/lib/libmpi.so" ]]; then
|
|
echo "ERROR: no libmpi.so at ${MPI_HOME}/lib (did build-ompi.sh run?)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> ROCM_PATH = ${ROCM_PATH}"
|
|
echo "==> MPI_HOME = ${MPI_HOME}"
|
|
echo "==> RCCL libs = ${RCCL_LIB_DIR}"
|
|
|
|
if [[ ! -f "${RCCL_LIB_DIR}/librccl.so" && ! -f "${RCCL_LIB_DIR}/librccl.so.1" ]]; then
|
|
echo "librccl.so not found under ${RCCL_LIB_DIR}"
|
|
ls -la "${RCCL_LIB_DIR}" 2>/dev/null || echo "(directory missing)"
|
|
exit 1
|
|
fi
|
|
|
|
cd "${RCCL_TESTS_DIR}"
|
|
|
|
export PATH="${MPI_HOME}/bin:${ROCM_PATH}/bin:${PATH}"
|
|
export LD_LIBRARY_PATH="${RCCL_LIB_DIR}:${MPI_HOME}/lib:${ROCM_PATH}/lib:${LD_LIBRARY_PATH:-}"
|
|
|
|
PERF_DIR=build
|
|
if [[ ! -d "${PERF_DIR}" || ! -f "${PERF_DIR}/all_reduce_perf" ]]; then
|
|
echo "rccl-tests perf binaries not found under ${PERF_DIR}"
|
|
ls -la
|
|
exit 1
|
|
fi
|
|
|
|
PARSER="${script_dir}/lib/parse_device_api_config.py"
|
|
[[ -f "${CONFIG}" ]] || { echo "ERROR: test-matrix config not found: ${CONFIG}" >&2; exit 1; }
|
|
[[ -f "${PARSER}" ]] || { echo "ERROR: config parser not found: ${PARSER}" >&2; exit 1; }
|
|
echo "==> test matrix = ${CONFIG}"
|
|
|
|
# Capture to a var (not `mapfile < <(...)`) so a parser failure aborts the job.
|
|
CONFIG_TSV="$(python3 "${PARSER}" "${CONFIG}")" || {
|
|
echo "ERROR: failed to parse test matrix ${CONFIG}" >&2
|
|
exit 1
|
|
}
|
|
mapfile -t CONFIG_RECORDS <<< "${CONFIG_TSV}"
|
|
|
|
CFG_BENCH_ARGS=""
|
|
DEBUG_ENV=""
|
|
SUITE_NAMES=() SUITE_ENVS=() SUITE_ARGS=() SUITE_BINS=()
|
|
for rec in "${CONFIG_RECORDS[@]}"; do
|
|
IFS=$'\t' read -r kind f1 f2 f3 f4 <<< "${rec}"
|
|
case "${kind}" in
|
|
bench_args) CFG_BENCH_ARGS="${f1}" ;;
|
|
debug_env) DEBUG_ENV="${f1}" ;;
|
|
suite) SUITE_NAMES+=("${f1}"); SUITE_ENVS+=("${f2}"); SUITE_ARGS+=("${f3}"); SUITE_BINS+=("${f4}") ;;
|
|
esac
|
|
done
|
|
|
|
if [[ ${#SUITE_NAMES[@]} -eq 0 ]]; then
|
|
echo "ERROR: no suites parsed from ${CONFIG}; refusing to report success" >&2
|
|
exit 1
|
|
fi
|
|
echo "==> ${#SUITE_NAMES[@]} suites to run: ${SUITE_NAMES[*]}"
|
|
|
|
# In debug mode, expand {LOGDIR} in debug_env to a real per-job dir so
|
|
# NCCL_DEBUG_FILE writes per-rank logs there (keeping stdout readable).
|
|
if [[ -n "${RCCL_CI_DEBUG:-}" && -n "${DEBUG_ENV}" ]]; then
|
|
RCCL_CI_DEBUG_DIR="${RCCL_CI_DEBUG_DIR:-${SLURM_SUBMIT_DIR:-$(pwd)}/nccl-debug}"
|
|
mkdir -p "${RCCL_CI_DEBUG_DIR}"
|
|
DEBUG_ENV="${DEBUG_ENV//\{LOGDIR\}/${RCCL_CI_DEBUG_DIR}}"
|
|
echo "==> RCCL_CI_DEBUG=1: NCCL debug logs -> ${RCCL_CI_DEBUG_DIR}/nccl-debug.<host>.<pid>.log"
|
|
fi
|
|
|
|
BENCH_ARGS="${BENCH_ARGS:-${CFG_BENCH_ARGS}}"
|
|
|
|
FAILED_RUNS=()
|
|
|
|
# Word-splitting on the flag vars below is intentional.
|
|
# shellcheck disable=SC2086
|
|
run_bench() {
|
|
local mode="$1"
|
|
local bin="$2"
|
|
local env_flags="$3"
|
|
shift 3
|
|
local extra_args="$*"
|
|
echo "=== ${mode}: ${bin} ${extra_args} ==="
|
|
set +e
|
|
timeout --kill-after="${BENCH_KILL_AFTER}" "${BENCH_TIMEOUT}" \
|
|
mpirun -np "${NP}" ${env_flags} -x LD_LIBRARY_PATH \
|
|
"./${PERF_DIR}/${bin}" ${BENCH_ARGS} ${extra_args}
|
|
local rc=$?
|
|
set -e
|
|
if [[ ${rc} -ne 0 ]]; then
|
|
# timeout(1): rc=124 = SIGTERM after BENCH_TIMEOUT, rc=137 = SIGKILL after BENCH_KILL_AFTER.
|
|
if [[ ${rc} -eq 124 || ${rc} -eq 137 ]]; then
|
|
FAILED_RUNS+=("${mode}:${bin} (TIMEOUT >${BENCH_TIMEOUT}, rc=${rc})")
|
|
else
|
|
FAILED_RUNS+=("${mode}:${bin} (rc=${rc})")
|
|
fi
|
|
fi
|
|
}
|
|
|
|
for i in "${!SUITE_NAMES[@]}"; do
|
|
mode="${SUITE_NAMES[$i]}"
|
|
env_flags="${SUITE_ENVS[$i]}"
|
|
extra_args="${SUITE_ARGS[$i]}"
|
|
if [[ -n "${RCCL_CI_DEBUG:-}" && -n "${DEBUG_ENV}" ]]; then
|
|
env_flags="${env_flags} ${DEBUG_ENV}"
|
|
fi
|
|
echo "=== suite: ${mode} ==="
|
|
# shellcheck disable=SC2086 # intentional word-splitting
|
|
for bin in ${SUITE_BINS[$i]}; do
|
|
run_bench "${mode}" "${bin}" "${env_flags}" ${extra_args}
|
|
done
|
|
done
|
|
|
|
if [[ ${#FAILED_RUNS[@]} -ne 0 ]]; then
|
|
echo "=== FAILED RUNS (${#FAILED_RUNS[@]}) ==="
|
|
printf ' %s\n' "${FAILED_RUNS[@]}"
|
|
exit 1
|
|
fi
|
|
|
|
echo "All device-api benchmark runs succeeded."
|