Files
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

99 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Train a tiny MLP with PyTorch DistributedDataParallel (DDP) on *emulated*
# MI350X GPUs through mirage, launched with `torchrun`. No physical GPU is
# required: rocjitsu emulates the devices.
#
# How it maps onto mirage:
# * `mirage run --gpus-per-node N` makes the emulated node expose N GPUs
# (rocjitsu synthesizes N KFD device nodes), so `torch.cuda.device_count()`
# is N inside the workload.
# * mirage exports `MASTER_ADDR`/`MASTER_PORT` on every node, so
# `torchrun`'s rendezvous (and `torch.distributed`'s `env://`) work with no
# extra wiring. For a single node, `torchrun --standalone` is enough.
# * mirage runs the emulator as a separate daemon process by default, so the
# rank processes share GPU memory through it. Pass `mirage run --in-process`
# to give each process its own in-process emulator (no shared GPU memory).
# * The fixture `ddp_mlp.py` is launched once per rank by torchrun; each rank
# pins itself to GPU `LOCAL_RANK`, wraps an MLP in DDP, and trains. Gradients
# are all-reduced with NCCL (RCCL on ROCm).
#
# What this does:
# 1. Create/reuse a venv populated from the gfx950-dcgpu (MI350) ROCm nightly.
# 2. `mirage run --gpus-per-node $NPROC -- torchrun --standalone
# --nproc_per_node=$NPROC ddp_mlp.py`, asserting rank 0 prints
# `ddp_mlp_ok`.
#
# Env knobs:
# VENV venv location (default: <mirage>/.venv-mi350)
# INDEX_URL pip index (default: gfx950-dcgpu nightly)
# SKIP_INSTALL set to 1 to reuse an already-populated venv
# PROFILE mirage profile (default: mi350x)
# NPROC GPUs / ranks per node, i.e. torchrun --nproc_per_node (default: 2)
# STEPS optimizer steps the MLP trains for (default: 50)
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MIRAGE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
FIXTURE="$MIRAGE_DIR/tests/fixtures/ml/ddp_mlp.py"
PROFILE="${PROFILE:-mi350x}"
NPROC="${NPROC:-2}"
STEPS="${STEPS:-50}"
VENV="${VENV:-$MIRAGE_DIR/.venv-mi350}"
INDEX_URL="${INDEX_URL:-https://rocm.nightlies.amd.com/v2/gfx950-dcgpu/}"
log() { printf '==> %s\n' "$*"; }
fail() { printf 'FAIL: %s\n' "$*" >&2; exit 1; }
[[ -f "$FIXTURE" ]] || fail "fixture not found: $FIXTURE"
# 1. Create the venv (idempotent).
if [[ ! -x "$VENV/bin/python3" ]]; then
log "creating venv at $VENV"
python3 -m venv "$VENV"
fi
# shellcheck disable=SC1091
source "$VENV/bin/activate"
VENV_PY="$VENV/bin/python3"
TORCHRUN="$VENV/bin/torchrun"
# 2. Install the gfx950-dcgpu nightly (torch + ROCm SDK, which carries rocjitsu).
if [[ "${SKIP_INSTALL:-0}" != "1" ]]; then
log "installing torch + ROCm SDK from $INDEX_URL"
"$VENV_PY" -m pip install --upgrade pip
"$VENV_PY" -m pip install --index-url "$INDEX_URL" "rocm[libraries,devel]" torch numpy
else
log "SKIP_INSTALL=1: reusing existing venv packages"
fi
# 2b. Expand the devel package so librocjitsu.so + configs appear under
# site-packages/_rocm_sdk_devel. Safe to re-run.
if [[ -x "$VENV/bin/rocm-sdk" ]]; then
log "expanding ROCm devel contents (rocm-sdk init)"
"$VENV/bin/rocm-sdk" init
fi
[[ -x "$TORCHRUN" ]] || fail "torchrun not found in venv: $TORCHRUN"
# 3. Run DDP training through mirage on the emulated node. Build & run mirage
# from the workspace (cargo run) so its rocjitsu KMD discovery/preload work;
# the first `--` ends cargo's args, the second ends mirage's.
cd "$MIRAGE_DIR"
log "training MLP with DDP via torchrun --nproc_per_node=$NPROC on emulated $PROFILE (nccl)"
set +e
OUTPUT="$(cargo run --quiet -- run \
--profile "$PROFILE" \
--gpus-per-node "$NPROC" \
--env "DDP_STEPS=$STEPS" \
-- "$TORCHRUN" --standalone --nproc_per_node="$NPROC" "$FIXTURE" 2>&1)"
STATUS=$?
set -e
printf '%s\n' "$OUTPUT"
# 4. Assert success.
[[ $STATUS -eq 0 ]] || fail "mirage run exited with status $STATUS"
grep -q 'ddp_mlp_ok' <<<"$OUTPUT" || fail "ddp_mlp.py did not report success"
log "PASS: DDP MLP trained on $NPROC emulated $PROFILE GPUs via torchrun"