Every night AORTA installs the freshly built wheel on a reference MI350 runner and replays representative PyTorch workloads — training, inference, and distributed correctness checks — comparing each result against a blessed baseline when one exists.
Run of 2026-09-05 11:17 UTC · commit 4b4553e · workflow run · amd_aorta-0.3.1rc20260905-py3-none-any.whl
Worst verdict in each area from tonight's run. Click a tile to jump to workloads.
and 2 more metrics past 10%
Each card is one nightly release (newest first). Overall health summarises that night's graded verdicts; workload chips wrap instead of scrolling sideways. Active workloads link to reproduction steps below. Retired workloads (no longer in the latest matrix) are plain text. Glyphs: ✓ pass · ✗ fail · ◆ record · ○ skip.
Reference step_time_p50 from the latest nightly. Recipes use the same per-rank batch at 2 and 8 GPUs (weak scaling), so ideal step time is flat. Efficiency is p50_2 / p50_8 as a percentage.
| strategy | 2 GPU p50 | 8 GPU p50 | slowdown | efficiency |
|---|---|---|---|---|
| DDP | 1.1 ms | 1.3 ms | 1.10× | 91% |
| FSDP | 5.4 ms | 5.7 ms | 1.06× | 94% |
Workloads are grouped by use case below. Each card shows tonight's recipe variants; expand Reproduce this workload locally for a full step-by-step guide, or Detailed metrics for additional summary values.
ROCm and PyTorch load and execute on GPU.
Verifies the ROCm/PyTorch stack loads and runs on GPU.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=1, f'need 1 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"aorta sweep run --recipe recipes/ci/gpu-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
aorta sweep run --recipe recipes/ci/gpu-smoke.yaml --output-dir triage_results/repro/gpu_smoke --strict
RUN_DIR="$(find triage_results/repro/gpu_smoke -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
Rank 0 prints `Wrote matrix to ...`. matrix.md shows every cell completed; mean_step_time_ms is recorded in perf.md. Nightly gates pass/fail against the blessed gpu_smoke::baseline-local baseline; step time is recorded but not performance-thresholded.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/ci/gpu-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/ci/gpu-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| expected | tracked only (not gated) | 8 | |
| n | tracked only (not gated) | 8 | |
| sum | tracked only (not gated) | 8 |
Offline LLM prefill/decode latency and throughput.
Validates prefill/decode latency, throughput, and logits checksum.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=1, f'need 1 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"aorta sweep run --recipe recipes/inference/example-inference-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
aorta sweep run --recipe recipes/inference/example-inference-smoke.yaml --output-dir triage_results/repro/inference_offline --strict
RUN_DIR="$(find triage_results/repro/inference_offline -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 10 -E "tokens_per_sec|prefill|decode|checksum" "$RUN_DIR/perf.md" 2>/dev/null || python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(json.dumps(d.get(\"cells\",[]), indent=2)[:2000])" "$RUN_DIR/matrix.json"
Recipe completes with --strict. logits_checksum is the active correctness gate in regression_baselines.yaml; latency and throughput are recorded on the dashboard but not perf-gated yet.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/inference/example-inference-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/inference/example-inference-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| batch_size | tracked only (not gated) | 4 | |
| decode_latency_ms | tracked only (not gated) | 1.143 ms | |
| decoded_tokens | tracked only (not gated) | 496 | |
| generate_tokens | tracked only (not gated) | 32 | |
| logits_checksum | must match baseline | 33,904,201 | |
| prefill_latency_ms | tracked only (not gated) | 1.121 ms | |
| prompt_len | tracked only (not gated) | 128 | |
| step_time_p50 | tracked only (not gated) | 40.76 ms | |
| step_time_p99 | tracked only (not gated) | 47.89 ms | |
| tokens_per_sec | tracked only (not gated) | 3500 tok/s |
PyTorch DDP and FSDP training step times.
Distributed data parallel training step time on two GPUs.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=2, f'need 2 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/training/example-training-ddp-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=2 $(which aorta) sweep run --recipe recipes/training/example-training-ddp-smoke.yaml --output-dir triage_results/repro/training_ddp --strict
RUN_DIR="$(find triage_results/repro/training_ddp -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 10 -E "step_time_p50|step_time_p99" "$RUN_DIR/perf.md" 2>/dev/null || python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(json.dumps(d.get(\"cells\",[]), indent=2)[:2000])" "$RUN_DIR/matrix.json"
All ranks complete without error. step_time_p50/p99 appear in perf.md. Nightly currently records training cells (passed/recording only); step-time thresholds are not perf-gated in regression_baselines.yaml yet.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/training/example-training-ddp-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/training/example-training-ddp-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| final_loss | tracked only (not gated) | 6.937 | |
| step_time_p50 | tracked only (not gated) | 1.139 ms | |
| step_time_p99 | tracked only (not gated) | 46.43 ms |
Distributed data parallel training step time on eight GPUs.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=8, f'need 8 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/training/example-training-ddp-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=8 $(which aorta) sweep run --recipe recipes/training/example-training-ddp-smoke.yaml --output-dir triage_results/repro/training_ddp_8gpu --strict
RUN_DIR="$(find triage_results/repro/training_ddp_8gpu -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 10 -E "step_time_p50" "$RUN_DIR/perf.md" 2>/dev/null || python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(json.dumps(d.get(\"cells\",[]), indent=2)[:2000])" "$RUN_DIR/matrix.json"
All ranks complete without error. step_time_p50/p99 appear in perf.md. Nightly currently records training cells (passed/recording only); step-time thresholds are not perf-gated in regression_baselines.yaml yet. Compare 2-GPU vs 8-GPU step_time_p50 in the dashboard scaling section.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/training/example-training-ddp-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/training/example-training-ddp-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| final_loss | tracked only (not gated) | 6.937 | |
| step_time_p50 | tracked only (not gated) | 1.258 ms | |
| step_time_p99 | tracked only (not gated) | 58.04 ms |
Fully sharded data parallel training on two GPUs.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=2, f'need 2 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/training/example-training-fsdp-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=2 $(which aorta) sweep run --recipe recipes/training/example-training-fsdp-smoke.yaml --output-dir triage_results/repro/training_fsdp --strict
RUN_DIR="$(find triage_results/repro/training_fsdp -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 10 -E "step_time_p50|step_time_p99" "$RUN_DIR/perf.md" 2>/dev/null || python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(json.dumps(d.get(\"cells\",[]), indent=2)[:2000])" "$RUN_DIR/matrix.json"
All ranks complete without error. step_time_p50/p99 appear in perf.md. Nightly currently records training cells (passed/recording only); step-time thresholds are not perf-gated in regression_baselines.yaml yet.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/training/example-training-fsdp-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/training/example-training-fsdp-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| final_loss | tracked only (not gated) | 254.4 | |
| step_time_p50 | tracked only (not gated) | 5.375 ms | |
| step_time_p99 | tracked only (not gated) | 7.404 ms |
Fully sharded data parallel training on eight GPUs.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=8, f'need 8 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/training/example-training-fsdp-smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=8 $(which aorta) sweep run --recipe recipes/training/example-training-fsdp-smoke.yaml --output-dir triage_results/repro/training_fsdp_8gpu --strict
RUN_DIR="$(find triage_results/repro/training_fsdp_8gpu -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 10 -E "step_time_p50" "$RUN_DIR/perf.md" 2>/dev/null || python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(json.dumps(d.get(\"cells\",[]), indent=2)[:2000])" "$RUN_DIR/matrix.json"
All ranks complete without error. step_time_p50/p99 appear in perf.md. Nightly currently records training cells (passed/recording only); step-time thresholds are not perf-gated in regression_baselines.yaml yet. Use the dashboard scaling table to compare 2-GPU vs 8-GPU FSDP efficiency.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/training/example-training-fsdp-smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/training/example-training-fsdp-smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| final_loss | tracked only (not gated) | 254.4 | |
| step_time_p50 | tracked only (not gated) | 5.692 ms | |
| step_time_p99 | tracked only (not gated) | 59.07 ms |
Numerical determinism and distributed race detection.
Bit-exact repeatability across ranks; divergence indicates silent corruption.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=2, f'need 2 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/llm-determinism/example-llm-determinism.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=2 $(which aorta) sweep run --recipe recipes/llm-determinism/example-llm-determinism.yaml --output-dir triage_results/repro/llm_determinism --strict
RUN_DIR="$(find triage_results/repro/llm_determinism -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 5 -E "ranks_with_divergence|diverge" "$RUN_DIR/perf.md" 2>/dev/null || true
python3 - "$RUN_DIR" <<'PY'
import json
from pathlib import Path
import sys
run = Path(sys.argv[1])
doc = json.loads((run / 'matrix.json').read_text(encoding='utf-8'))
out = {}
for cell in doc.get('cells') or []:
values = []
for raw in cell.get('trial_paths') or []:
path = Path(raw)
if not path.is_absolute() and not path.exists():
path = run / path
if path.is_dir():
path = path / 'result.json'
if not path.is_file():
continue
trial = json.loads(path.read_text(encoding='utf-8'))
metrics = (trial.get('result') or {}).get('metrics') or {}
if 'ranks_with_divergence' in metrics:
values.append(metrics['ranks_with_divergence'])
out[cell.get('name', '?')] = values or None
print(json.dumps(out, indent=2))
PYranks_with_divergence must be 0 for a pass. Any non-zero value means silent numerical corruption between ranks and should fail nightly CI.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/llm-determinism/example-llm-determinism.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 24 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 12 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 4 | |
| num_layers | tracked only (not gated) | 12 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 24 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Bit-exact repeatability at full-node scale.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=8, f'need 8 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
aorta sweep run --recipe recipes/llm-determinism/example-llm-determinism.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=8 $(which aorta) sweep run --recipe recipes/llm-determinism/example-llm-determinism.yaml --output-dir triage_results/repro/llm_determinism_8gpu --strict
RUN_DIR="$(find triage_results/repro/llm_determinism_8gpu -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 5 -E "ranks_with_divergence|diverge" "$RUN_DIR/perf.md" 2>/dev/null || true
python3 - "$RUN_DIR" <<'PY'
import json
from pathlib import Path
import sys
run = Path(sys.argv[1])
doc = json.loads((run / 'matrix.json').read_text(encoding='utf-8'))
out = {}
for cell in doc.get('cells') or []:
values = []
for raw in cell.get('trial_paths') or []:
path = Path(raw)
if not path.is_absolute() and not path.exists():
path = run / path
if path.is_dir():
path = path / 'result.json'
if not path.is_file():
continue
trial = json.loads(path.read_text(encoding='utf-8'))
metrics = (trial.get('result') or {}).get('metrics') or {}
if 'ranks_with_divergence' in metrics:
values.append(metrics['ranks_with_divergence'])
out[cell.get('name', '?')] = values or None
print(json.dumps(out, indent=2))
PYranks_with_divergence == 0 on every cell. This is a correctness gate, not a performance benchmark.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/llm-determinism/example-llm-determinism.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 24 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 12 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 4 | |
| num_layers | tracked only (not gated) | 12 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/llm-determinism/example-llm-determinism.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| corruption_details_omitted | tracked only (not gated) | 0 | |
| num_experts | tracked only (not gated) | 1 | |
| num_layers | tracked only (not gated) | 24 | |
| ranks_with_divergence | tracked only (not gated) | 0 |
Detects timing races and silent data corruption in distributed layers.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=2, f'need 2 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
export AORTA_TRIAL_MASTER_PORT_BASE=30000
# Required for srun / static torchrun without elastic agent store
aorta sweep run --recipe recipes/race/race_smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=2 $(which aorta) sweep run --recipe recipes/race/race_smoke.yaml --output-dir triage_results/repro/race --strict
RUN_DIR="$(find triage_results/repro/race -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 5 -E "layer_checksum_mismatch" "$RUN_DIR/perf.md" 2>/dev/null || true
python3 - "$RUN_DIR" <<'PY'
import json
from pathlib import Path
import sys
run = Path(sys.argv[1])
doc = json.loads((run / 'matrix.json').read_text(encoding='utf-8'))
out = {}
for cell in doc.get('cells') or []:
values = []
for raw in cell.get('trial_paths') or []:
path = Path(raw)
if not path.is_absolute() and not path.exists():
path = run / path
if path.is_dir():
path = path / 'result.json'
if not path.is_file():
continue
trial = json.loads(path.read_text(encoding='utf-8'))
metrics = (trial.get('result') or {}).get('metrics') or {}
if 'layer_checksum_mismatches' in metrics:
values.append(metrics['layer_checksum_mismatches'])
out[cell.get('name', '?')] = values or None
print(json.dumps(out, indent=2))
PYlayer_checksum_mismatches must be 0. Non-zero values indicate detected races or silent corruption in distributed layers.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/race/race_smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/race/race_smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| avg_step_time_ms | tracked only (not gated) | 1498 | |
| corruption_details_omitted | tracked only (not gated) | 0 | |
| declared_h2d_tensor_size | tracked only (not gated) | 1,000,000 | |
| eff_batch_size | tracked only (not gated) | 1 | |
| eff_ffn_size | tracked only (not gated) | 2,048 | |
| eff_num_heads | tracked only (not gated) | 4 | |
| eff_seq_len | tracked only (not gated) | 512 | |
| effective_h2d_tensor_size | tracked only (not gated) | 1,000,000 | |
| layer_checksum_mismatches | tracked only (not gated) | 0 | |
| layers_verified | tracked only (not gated) | 15 |
Race detection at full-node scale.
git clone https://github.com/ROCm/aorta.git
cd aorta
git checkout 4b4553ef14af08e7ee2d68a888b68cd6a88803f7
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade --pre 'amd-aorta[hw-queue]==0.3.1rc20260905' -f https://github.com/ROCm/aorta/releases/expanded_assets/dev-wheels
# If that exact wheel is unavailable, pick the closest dev-wheel build
# and compare `aorta --version` with the dashboard header before reproducing.
aorta --help
python3 -c "import torch; n=torch.cuda.device_count(); assert torch.cuda.is_available() and n>0, 'no CUDA/HIP devices'; assert n>=8, f'need 8 GPU(s), have {n}'; print(f'{n} GPU(s), HIP', torch.version.hip)"export NCCL_DEBUG=WARN # optional, for troubleshooting
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
# Slurm / multi-node: see recipes/README-running-recipes.md
export AORTA_TRIAL_MASTER_PORT_BASE=30000
aorta sweep run --recipe recipes/race/race_smoke.yaml --dry-run
Run from the repository root after setup completes. A standalone --strict sweep only fails cells that error or never run. Dashboard pass/record/fail comes separately from nightly_eval.py comparing matrix.json against config/ci/regression_baselines.yaml; run that harness to apply the dashboard gates.
torchrun --standalone --nproc_per_node=8 $(which aorta) sweep run --recipe recipes/race/race_smoke.yaml --output-dir triage_results/repro/race_8gpu --strict
RUN_DIR="$(find triage_results/repro/race_8gpu -mindepth 3 -maxdepth 3 -type d -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)"
if [ -z "$RUN_DIR" ] || [ ! -d "$RUN_DIR" ]; then echo "No run directory found"; exit 1; fi
echo "Using run directory: $RUN_DIR"
cat "$RUN_DIR/matrix.md"
python3 -m json.tool "$RUN_DIR/matrix.json" | head -80
if [ -f "$RUN_DIR/perf.md" ]; then head -60 "$RUN_DIR/perf.md"; else echo "(no perf.md)"; fi
# Standalone --strict only catches errored or not-run cells; dashboard pass/record/fail comes from nightly_eval.py separately comparing matrix.json to config/ci/regression_baselines.yaml
grep -m 5 -E "layer_checksum_mismatch" "$RUN_DIR/perf.md" 2>/dev/null || true
python3 - "$RUN_DIR" <<'PY'
import json
from pathlib import Path
import sys
run = Path(sys.argv[1])
doc = json.loads((run / 'matrix.json').read_text(encoding='utf-8'))
out = {}
for cell in doc.get('cells') or []:
values = []
for raw in cell.get('trial_paths') or []:
path = Path(raw)
if not path.is_absolute() and not path.exists():
path = run / path
if path.is_dir():
path = path / 'result.json'
if not path.is_file():
continue
trial = json.loads(path.read_text(encoding='utf-8'))
metrics = (trial.get('result') or {}).get('metrics') or {}
if 'layer_checksum_mismatches' in metrics:
values.append(metrics['layer_checksum_mismatches'])
out[cell.get('name', '?')] = values or None
print(json.dumps(out, indent=2))
PYlayer_checksum_mismatches == 0 for every cell. Any failure warrants inspecting per-trial JSON under cells/.
Match the aorta, PyTorch, ROCm, and HIP versions shown in the dashboard header when comparing numbers. Small differences on different hardware are expected; regressions vs the blessed baseline are what nightly CI flags.
Recipe YAML: recipes/race/race_smoke.yaml · Multi-node launcher guide
Additional summary metrics for this recipe variant. Grading rule is how nightly CI compares the value; this run is tonight; history is recent nights (when available).
recipe recipes/race/race_smoke.yaml · 1 trial
| metric | grading rule | this run | history |
|---|---|---|---|
| avg_step_time_ms | tracked only (not gated) | 1780 | |
| corruption_details_omitted | tracked only (not gated) | 0 | |
| declared_h2d_tensor_size | tracked only (not gated) | 1,000,000 | |
| eff_batch_size | tracked only (not gated) | 1 | |
| eff_ffn_size | tracked only (not gated) | 2,048 | |
| eff_num_heads | tracked only (not gated) | 4 | |
| eff_seq_len | tracked only (not gated) | 512 | |
| effective_h2d_tensor_size | tracked only (not gated) | 1,000,000 | |
| layer_checksum_mismatches | tracked only (not gated) | 0 | |
| layers_verified | tracked only (not gated) | 15 |
Results: pass/fail = compared against a blessed baseline · record = baseline not set yet · skip = not enough GPUs. Expand cards for reproduction steps or optional detailed metrics.
Tracks rocm/pytorch:latest, resolved to a concrete digest per run. Not a gate: these rows never affect the status above, the pass-rate trend, or any required check -- the merge gate stays on the digest pinned in docker/Dockerfile.ci-gpu. A change here says a new ROCm release moved something, which is a question to investigate, not a regression on this branch.
| date | ROCm | torch | HIP | base image | passed/graded | note |
|---|---|---|---|---|---|---|
| 2026-08-26 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-08-27 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-08-28 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-08-29 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-08-30 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-08-31 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-09-01 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-09-02 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-09-03 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-09-04 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |
| 2026-09-05 | 7.14.0 | 2.13.0+rocm7.14.0 | 7.14.60850 | sha256:a3867e22ca44 | 15/16 | — |