ci: self-hosted reliability — case-opt timeout/clean, monitor crash, compiler labels#1643
Merged
sbryngelson merged 5 commits intoJul 13, 2026
Merged
Conversation
The frontier_amd case-optimization pre-build timed out at the ~2h batch walltime: AMD flang case-opt sim builds run ~30 min/case, and the 2-way shard put 4 cases (~120 min) on the heavy shard. The pre-build also globbed all 7 benchmarks/*/case.py while the run only tests 5, wasting two builds. Make the 5 run-tested cases a single source of truth (new case-optimization-benchmarks.sh, sourced by both scripts) so pre-built binaries and run cases never drift, and shard both the pre-build and the run 3-way (heavy shard ~2 cases, ~60 min). Unsharded clusters are unaffected (shard helper is inert when job_shard is empty).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts the case-optimization CI on frontier_amd to avoid SLURM batch walltime timeouts by (1) sharding the workload 3-way and (2) ensuring the pre-build and run steps iterate an identical benchmark list so they cannot drift.
Changes:
- Introduces a shared benchmark list + sharding helpers in
.github/scripts/case-optimization-benchmarks.sh, sourced by both pre-build and run scripts. - Updates
prebuild-case-optimization.shandrun_case_optimization.shto filter cases by an optionaljob_shard(i/N) consistently. - Updates
.github/workflows/test.ymlto runfrontier_amdpre-build and run steps as three concurrent shard jobs; adjusts log printing and artifact globs to be shard-agnostic.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| .github/workflows/test.yml | Shards frontier_amd pre-build and run steps 3-way; updates log/archive globs for shard outputs. |
| .github/scripts/run_case_optimization.sh | Sources shared benchmark list and applies shard filtering during build/run loops. |
| .github/scripts/prebuild-case-optimization.sh | Sources shared benchmark list, parses shard, and uses shard filtering for dry-run prebuilds. |
| .github/scripts/case-optimization-benchmarks.sh | New single source of truth for benchmark list and shard parsing/filter helpers. |
The non-AMD Frontier lanes in test.yml run the CCE (Cray) compiler (cpe/25.03, default PrgEnv-cray) — the matrix comment says so — but displayed as bare 'Oak Ridge | Frontier' while their AMD sibling is tagged '(AMD)' and bench.yml already names the same lane 'Oak Ridge | Frontier (CCE)'. Tag them '(CCE)' so the check name matches the compiler and is consistent across workflows. Display-only; the CPU lane genuinely uses CCE too.
Phoenix is split by device: p-gpu loads nvhpc/24.5 (nvfortran) while p-cpu loads gcc/12.3.0 (toolchain/modules). The lanes were displayed as bare 'Georgia Tech | Phoenix', and bench.yml's Phoenix CPU benchmark was tagged '(NVHPC)' though it actually builds with GNU. Tag each lane by the compiler it runs -- GPU '(NVHPC)', CPU '(GNU)' -- matching the Frontier (CCE)/(AMD) convention and fixing the bench.yml CPU mislabel. Display-only.
The stale-staging cleanup used -regex '.*/[0-9a-f]+', which matches only
pure-hex names, but MFC staging slugs are '<prefix>-<hash>' with prefix in
{gpu-acc, gpu-mp, cpu} (+ optional -debug/-chem/... ), e.g.
'gpu-mp-b86d2efce8' (build.py get_slug). So the clean matched nothing and
removed no staging at all.
Consequence on self-hosted runners: a prior case-opt build that was killed
mid-configure (e.g. the frontier_amd pre-build hitting its walltime) leaves a
corrupt staging dir that the clean fails to remove; the next run reuses it and
CMake configure fails deterministically ('CMAKE_Fortran_COMPILER not set' in
FindOpenMP try_compile, + 'Directory not empty' on the leftover CMakeFiles).
Observed across all 3 sbatch retries of run 29198726737.
Match '<prefix>-*' instead so target staging/install dirs are removed while
dependency dirs (fftw, hipfort, hdf5, silo, lapack) are preserved. Verified
the new regex removes every prefix variant and keeps the deps. All 6 sites
(prebuild, run, workflow x staging+install).
…ocsub The monitor streamed job output with 'read -t 1' over a 'tail -f' process substitution (fd 3). When that pipe broke, bash could crash in the read builtin's alarm/longjmp unwind path (SIGSEGV 139, 'unwind_frame_run: read_builtin: frame not found'); the EXIT trap then scancel'd a still-RUNNING, healthy job, producing a red X that mimics a real test failure (observed on a Phoenix lane at test 341/596, all golden-matching). Replace it with a plain backgrounded 'tail -f' streaming straight to the step log, plus the existing status poll loop (state was already polled separately, so nothing is lost). The final 'cat "$output_file"' still reprints the whole file, so output is complete even if tail is killed mid-flush. Removes the crash-prone construct entirely; behavior-preserving otherwise.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1643 +/- ##
=======================================
Coverage 60.95% 60.95%
=======================================
Files 83 83
Lines 20003 20003
Branches 2983 2983
=======================================
Hits 12193 12193
Misses 5782 5782
Partials 2028 2028 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
fahnab666
pushed a commit
to fahnab666/mfc-nabid
that referenced
this pull request
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CI-infrastructure only — no solver or toolchain code touched. Four commits, each independent.
1. frontier_amd case-opt timeout (commit
4fcaaac6)The
frontier_amdcase-optimization Pre-Build times out at the Frontier batch partition's01:59:00(~2h) cap, even 2-way sharded (dies ~120 min, run 29198726737).Root cause, from the job log:
5eq_hllc= 32 min).benchmarks/*/case.py, but the run only tests 5 — two built for nothing.Fix: new
.github/scripts/case-optimization-benchmarks.sh(the 5 run-tested cases as a single source of truth + shared shard helpers, sourced by both scripts so binaries and run cases can't drift); pre-build and run both shard 3-way (heavy shard ≈2 cases ≈60 min);phoenixunsharded; log/archive globs shard-agnostic.2. Dead staging-clean regex (commit
04b06882) — reliability fixThe stale-staging cleanup used
-regex '.*/[0-9a-f]+', matching pure-hex names only. But MFC staging slugs are<prefix>-<hash>with prefix ∈ {gpu-acc,gpu-mp,cpu} (+ optional-debug/-chem/…), e.g.gpu-mp-b86d2efce8(build.pyget_slug). So the clean matched nothing and removed no staging at all (all 6 sites: prebuild/run/workflow × staging+install).Consequence: when a case-opt build is killed mid-configure (e.g. the pre-build hitting its walltime), it leaves a corrupt staging dir the clean fails to remove; the next run on that self-hosted runner reuses it and CMake configure fails deterministically —
CMAKE_Fortran_COMPILER not setin FindOpenMP'stry_compile, plusDirectory not emptyon the leftoverCMakeFiles. This is exactly the failure seen on the retry of run 29198726737 (identical across all 3 sbatch attempts — not a race). Now matches<prefix>-*, removing target dirs while preserving dep dirs (fftw,hipfort, …).3–4. Correct compiler labels on self-hosted lanes (commits
d36d8add,81fcad99)Check names didn't match the compiler they run; verified each against
toolchain/modules:cpe/25.03) but displayed bareOak Ridge | Frontierwhile its AMD sibling was(AMD)andbench.ymlalready used(CCE). Now(CCE).p-gpu= nvfortran,p-cpu= gcc/12.3.0. Lanes were bare, andbench.yml's Phoenix CPU benchmark was mistagged(NVHPC)though it builds with GNU. Now tagged per lane: GPU(NVHPC), CPU(GNU).Validation
<prefix>-<hash>variant, preserves dep dirs.bash -n, both workflows parse,precheckgreen on every commit.5. SLURM monitor crash (commit
b958ca4b) — shared harnessmonitor_slurm_job.shstreamed job output withread -t 1over atail -fprocess substitution. When that pipe broke, bash could crash in the read-builtin's alarm/longjmp unwind path (SIGSEGV 139,unwind_frame_run: read_builtin: frame not found), and theEXITtrap would thenscancela still-RUNNING, healthy job — a red X that mimics a real test failure (hit on a Phoenix lane mid-suite at 341/596, all golden-matching). Replaced with a plain backgroundedtail -f+ the existing status poll (state was already polled separately); the finalcatstill reprints the whole file, so output stays complete. Removes the crash-prone construct; behavior-preserving otherwise.Blast radius: this is the monitor used by every self-hosted lane (all Frontier + Phoenix), so it is the one change here that is not case-opt-scoped. It cannot be fully exercised without real SLURM; the change is minimal and behavior-preserving, and this PR run is the live test.