Skip to content

Commit 0819b0e

Browse files
sbryngelsonclaude
andcommitted
Merge upstream/master: CCE 19.0.0 workaround, cache/build improvements
Merged f95b2c4 (Work around CCE 19.0.0 compiler bugs for Cray+OpenACC builds) with the following conflict resolutions: - run_monitored_slurm_job.sh: kept ours (superset with id_file writing and UNKNOWN fallback) - phoenix/submit.sh: kept ours (thin wrapper calling submit-job.sh) - phoenix/bench.sh: kept our 64-job cap + took upstream RETRY_CLEAN_CMD - frontier/submit.sh: took upstream (job_type detection block) - CMakeLists.txt: took upstream (CCE IPA workaround for m_bubbles_EL and m_phase_change, comment fix) - test.yml: took upstream github job changes (simplified cache key, Python 3.14, updated build/test commands); kept our clean: false and Submit/Monitor split steps for Phoenix self and case-optimization jobs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 parents 8f298d1 + f95b2c4 commit 0819b0e

10 files changed

Lines changed: 153 additions & 44 deletions

File tree

.github/workflows/frontier/submit.sh

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ else
2525
exit 1
2626
fi
2727

28+
# Detect job type from submitted script basename
29+
script_basename="$(basename "$1" .sh)"
30+
case "$script_basename" in
31+
bench*) job_type="bench" ;;
32+
*) job_type="test" ;;
33+
esac
34+
2835
if [ "$2" = "cpu" ]; then
2936
sbatch_device_opts="\
3037
#SBATCH -n 32 # Number of cores required"
@@ -37,10 +44,17 @@ else
3744
fi
3845

3946
# Select SBATCH params based on job type
40-
sbatch_account="#SBATCH -A CFD154"
41-
sbatch_time="#SBATCH -t 01:59:00"
42-
sbatch_partition="#SBATCH -p batch"
43-
sbatch_extra="#SBATCH --qos=normal"
47+
if [ "$job_type" = "bench" ]; then
48+
sbatch_account="#SBATCH -A CFD154"
49+
sbatch_time="#SBATCH -t 01:59:00"
50+
sbatch_partition="#SBATCH -p batch"
51+
sbatch_extra="#SBATCH --qos=normal"
52+
else
53+
sbatch_account="#SBATCH -A CFD154"
54+
sbatch_time="#SBATCH -t 01:59:00"
55+
sbatch_partition="#SBATCH -p batch"
56+
sbatch_extra="#SBATCH --qos=normal"
57+
fi
4458

4559
shard_suffix=""
4660
if [ -n "$4" ]; then

.github/workflows/phoenix/bench.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fi
2222
rm -rf build
2323

2424
source .github/scripts/retry-build.sh
25-
retry_build ./mfc.sh build -j $n_jobs $build_opts || exit 1
25+
RETRY_CLEAN_CMD="./mfc.sh clean" retry_build ./mfc.sh build -j $n_jobs $build_opts || exit 1
2626

2727
./mfc.sh bench $bench_opts -j $n_jobs -o "$job_slug.yaml" -- -c phoenix-bench $device_opts -n $n_ranks
2828

.github/workflows/test.yml

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ jobs:
9898
- name: Clone
9999
uses: actions/checkout@v4
100100

101+
- name: Restore Build Cache
102+
uses: actions/cache@v4
103+
with:
104+
path: build
105+
key: mfc-build-${{ matrix.os }}-${{ matrix.mpi }}-${{ matrix.debug }}-${{ matrix.precision }}-${{ matrix.intel }}-${{ hashFiles('CMakeLists.txt', 'toolchain/dependencies/**', 'toolchain/cmake/**', 'src/**/*.fpp', 'src/**/*.f90') }}
106+
101107
- name: Setup MacOS
102108
if: matrix.os == 'macos'
103109
run: |
@@ -131,32 +137,20 @@ jobs:
131137
printenv | sort > /tmp/env_after
132138
diff /tmp/env_before /tmp/env_after | grep '^>' | sed 's/^> //' >> $GITHUB_ENV
133139
134-
- name: Get system info for cache key
135-
id: sys-info
136-
run: |
137-
{
138-
uname -m
139-
cat /proc/cpuinfo 2>/dev/null | grep 'model name' | head -1 || sysctl -n machdep.cpu.brand_string 2>/dev/null || true
140-
if command -v ifx &>/dev/null; then ifx --version 2>/dev/null | head -1; else ${FC:-gfortran} --version 2>/dev/null | head -1 || true; fi
141-
${CC:-gcc} --version 2>/dev/null | head -1 || true
142-
} | (sha256sum 2>/dev/null || shasum -a 256) | cut -c1-16 > /tmp/sys-hash
143-
echo "sys-hash=$(cat /tmp/sys-hash)" >> "$GITHUB_OUTPUT"
144-
145-
- name: Restore Build Cache
146-
uses: actions/cache@v4
140+
- name: Set up Python 3.14
141+
uses: actions/setup-python@v5
147142
with:
148-
path: build
149-
key: mfc-build-${{ matrix.os }}-${{ matrix.mpi }}-${{ matrix.debug }}-${{ matrix.precision }}-${{ matrix.intel }}-${{ steps.sys-info.outputs.sys-hash }}-${{ hashFiles('CMakeLists.txt', 'toolchain/dependencies/**', 'toolchain/cmake/**', 'src/**/*.fpp', 'src/**/*.f90') }}
143+
python-version: '3.14'
150144

151145
- name: Build
152146
run: |
153-
/bin/bash mfc.sh test -v --dry-run -j "$(nproc)" --${{ matrix.debug }} --${{ matrix.mpi }} $PRECISION $TEST_ALL
147+
/bin/bash mfc.sh test -v --dry-run -j $(nproc) --${{ matrix.debug }} --${{ matrix.mpi }} --${{ matrix.precision }} $TEST_ALL
154148
env:
155149
TEST_ALL: ${{ matrix.mpi == 'mpi' && '--test-all' || '' }}
156-
PRECISION: ${{ matrix.precision != '' && format('--{0}', matrix.precision) || '' }}
157150

158151
- name: Test
159-
run: bash .github/scripts/run-tests-with-retry.sh -v --max-attempts 3 -j "$(nproc)" $TEST_ALL $TEST_PCT
152+
run: |
153+
/bin/bash mfc.sh test -v --max-attempts 3 -j $(nproc) $TEST_ALL $TEST_PCT
160154
env:
161155
TEST_ALL: ${{ matrix.mpi == 'mpi' && '--test-all' || '' }}
162156
TEST_PCT: ${{ matrix.debug == 'debug' && '-% 20' || '' }}
@@ -186,7 +180,7 @@ jobs:
186180
cluster_name: 'Georgia Tech | Phoenix'
187181
device: 'cpu'
188182
interface: 'none'
189-
# Frontier (ORNL) — build on login node, GPU tests sharded for batch partition
183+
# Frontier (ORNL) — CCE
190184
- runner: 'frontier'
191185
cluster: 'frontier'
192186
cluster_name: 'Oak Ridge | Frontier'

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,8 @@ benchmarks/*.png
105105
*.avi
106106

107107
**isolation_rules/
108-
**.supercode/
108+
**.supercode/
109+
# CCE stress-test log directories (local testing artifacts)
110+
cce_*/
111+
cce_*.log
112+
run_cce_*.sh

CMakeLists.txt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
230230
CHECK_FORTRAN_COMPILER_FLAG("-march=native" SUPPORTS_MARCH_NATIVE)
231231
if (SUPPORTS_MARCH_NATIVE)
232232
add_compile_options($<$<COMPILE_LANGUAGE:Fortran>:-march=native>)
233-
# Disable AVX-512 FP16: gfortran 12 emits vmovw instructions on
233+
# Disable AVX-512 FP16: gfortran >=12 emits vmovw instructions on
234234
# Granite Rapids CPUs, but binutils <2.38 cannot assemble them.
235235
# FP16 is unused in MFC's double-precision computations.
236236
CHECK_FORTRAN_COMPILER_FLAG("-mno-avx512fp16" SUPPORTS_MNO_AVX512FP16)
@@ -408,6 +408,7 @@ HANDLE_SOURCES(simulation ON)
408408
HANDLE_SOURCES(post_process ON)
409409
HANDLE_SOURCES(syscheck OFF)
410410

411+
411412
# MFC_SETUP_TARGET: Given a target (herein <target>), this macro creates a new
412413
# executable <target> with the appropriate sources, compiler definitions, and
413414
# linked libraries (assuming HANDLE_SOURCES was called on <target>).
@@ -644,6 +645,23 @@ if (MFC_SIMULATION)
644645
MFC_SETUP_TARGET(TARGET simulation
645646
SOURCES "${simulation_SRCs}"
646647
MPI FFTW OpenACC OpenMP)
648+
# CCE 19.0.0 IPA workaround: two files trigger IPA crashes:
649+
# m_bubbles_EL: castIsValid assertion (InstCombine/foldIntegerTypedPHI)
650+
# m_phase_change: bring_routine_resident SIGSEGV
651+
# Disabling IPA per-file avoids the crashes while preserving IPA for
652+
# the rest of simulation (needed for thermochem INLINEALWAYS inlining).
653+
# Applied to Cray+OpenACC and Cray CPU, but NOT Cray+OpenMP: on OpenMP,
654+
# m_thermochem uses !DIR$ INLINEALWAYS (requires IPA), so disabling IPA
655+
# for these files breaks thermochem on-device calls. On OpenACC the
656+
# pyrometheus patch emits !$acc routine seq instead (no IPA needed).
657+
# See PR #1286.
658+
if (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray" AND NOT MFC_OpenMP)
659+
set_source_files_properties(
660+
"${CMAKE_BINARY_DIR}/fypp/simulation/m_bubbles_EL.fpp.f90"
661+
"${CMAKE_BINARY_DIR}/fypp/simulation/m_phase_change.fpp.f90"
662+
PROPERTIES COMPILE_OPTIONS "-Oipa0"
663+
)
664+
endif()
647665
endif()
648666

649667
if (MFC_POST_PROCESS)

src/common/include/parallel_macros.fpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,46 @@
4848

4949
#:enddef
5050

51-
#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, extraAccArgs=None, extraOmpArgs=None)
51+
#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, cray_noinline=False, extraAccArgs=None, extraOmpArgs=None)
5252
#:assert isinstance(cray_inline, bool)
53+
#:assert isinstance(cray_noinline, bool)
54+
#:assert not (cray_inline and cray_noinline), "cray_inline and cray_noinline are mutually exclusive"
5355
#:set acc_directive = ACC_ROUTINE(function_name=function_name, parallelism=parallelism, nohost=nohost, extraAccArgs=extraAccArgs)
5456
#:set omp_directive = OMP_ROUTINE(function_name=function_name, nohost=nohost, extraOmpArgs=extraOmpArgs)
5557

56-
#:if cray_inline == True
58+
#:if cray_noinline == True
59+
#:if not isinstance(function_name, str)
60+
#:stop "When using cray_noinline, function name must be given and given as a string"
61+
#:endif
62+
#:set cray_noinline_directive = ('!DIR$ NOINLINE ' + function_name).strip('\n')
63+
#ifdef _CRAYFTN
64+
#if MFC_OpenACC
65+
$:acc_directive
66+
#elif MFC_OpenMP
67+
$:omp_directive
68+
#else
69+
$:cray_noinline_directive
70+
#endif
71+
#! On non-Cray CPU builds (no _CRAYFTN, no MFC_OpenACC, no MFC_OpenMP), nothing is
72+
#! emitted — intentional, since !DIR$ NOINLINE is a Cray-specific directive.
73+
#elif MFC_OpenACC
74+
$:acc_directive
75+
#elif MFC_OpenMP
76+
$:omp_directive
77+
#endif
78+
#:elif cray_inline == True
5779
#:if not isinstance(function_name, str)
5880
#:stop "When inlining for Cray Compiler, function name must be given and given as a string"
5981
#:endif
6082
#:set cray_directive = ('!DIR$ INLINEALWAYS ' + function_name).strip('\n')
6183
#ifdef _CRAYFTN
84+
#if MFC_OpenACC
85+
$:acc_directive
86+
#elif MFC_OpenMP
87+
$:omp_directive
88+
#else
6289
$:cray_directive
90+
#endif
6391
#elif MFC_OpenACC
6492
$:acc_directive
6593
#elif MFC_OpenMP

src/common/m_phase_change.fpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ contains
104104
!< Generic loop iterators
105105
integer :: i, j, k, l
106106

107+
#ifdef _CRAYFTN
108+
#ifdef MFC_OpenACC
109+
! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV
110+
!DIR$ NOINLINE s_infinite_pt_relaxation_k
111+
!DIR$ NOINLINE s_infinite_ptg_relaxation_k
112+
!DIR$ NOINLINE s_correct_partial_densities
113+
!DIR$ NOINLINE s_TSat
114+
#endif
115+
#endif
116+
107117
! starting equilibrium solver
108118
$:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok,pS, pSOV, pSSL, TS, TSOV, TSatOV, TSatSL, TSSL, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF]')
109119
do j = 0, m
@@ -296,7 +306,7 @@ contains
296306
!! @param TS equilibrium temperature at the interface
297307
subroutine s_infinite_pt_relaxation_k(j, k, l, MFL, pS, p_infpT, q_cons_vf, rhoe, TS)
298308
$:GPU_ROUTINE(function_name='s_infinite_pt_relaxation_k', &
299-
& parallelism='[seq]', cray_inline=True)
309+
& parallelism='[seq]', cray_noinline=True)
300310

301311
! initializing variables
302312
integer, intent(in) :: j, k, l, MFL
@@ -411,7 +421,7 @@ contains
411421
!! @param TS equilibrium temperature at the interface
412422
subroutine s_infinite_ptg_relaxation_k(j, k, l, pS, p_infpT, rhoe, q_cons_vf, TS)
413423
$:GPU_ROUTINE(function_name='s_infinite_ptg_relaxation_k', &
414-
& parallelism='[seq]', cray_inline=True)
424+
& parallelism='[seq]', cray_noinline=True)
415425

416426
integer, intent(in) :: j, k, l
417427
real(wp), intent(inout) :: pS
@@ -579,7 +589,8 @@ contains
579589
InvJac = InvJac/(Jac(1, 1)*Jac(2, 2) - Jac(1, 2)*Jac(2, 1))
580590

581591
! calculating correction array for Newton's method
582-
DeltamP = -1.0_wp*(matmul(InvJac, R2D))
592+
DeltamP(1) = -1.0_wp*(InvJac(1, 1)*R2D(1) + InvJac(1, 2)*R2D(2))
593+
DeltamP(2) = -1.0_wp*(InvJac(2, 1)*R2D(1) + InvJac(2, 2)*R2D(2))
583594
584595
! updating two reacting 'masses'. Recall that inert 'masses' do not change during the phase change
585596
! liquid
@@ -638,7 +649,7 @@ contains
638649
!! @param l generic loop iterator for z direction
639650
subroutine s_correct_partial_densities(MCT, q_cons_vf, rM, j, k, l)
640651
$:GPU_ROUTINE(function_name='s_correct_partial_densities', &
641-
& parallelism='[seq]', cray_inline=True)
652+
& parallelism='[seq]', cray_noinline=True)
642653
643654
!> @name variables for the correction of the reacting partial densities
644655
!> @{
@@ -689,7 +700,7 @@ contains
689700
!! @param TSIn equilibrium Temperature
690701
elemental subroutine s_TSat(pSat, TSat, TSIn)
691702
$:GPU_ROUTINE(function_name='s_TSat',parallelism='[seq]', &
692-
& cray_inline=True)
703+
& cray_noinline=True)
693704
694705
real(wp), intent(in) :: pSat
695706
real(wp), intent(out) :: TSat
@@ -716,6 +727,12 @@ contains
716727

717728
! underrelaxation factor
718729
Om = 1.0e-3_wp
730+
731+
! FT must be initialized before the do while condition is evaluated.
732+
! Fortran .or. is not short-circuit: abs(FT) is always evaluated even
733+
! when ns == 0, so FT must have a defined value here.
734+
FT = huge(1.0_wp)
735+
719736
do while ((abs(FT) > ptgalpha_eps) .or. (ns == 0))
720737
! increasing counter
721738
ns = ns + 1

src/common/m_variables_conversion.fpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ contains
116116
!! @param pres_mag Magnetic pressure (optional)
117117
subroutine s_compute_pressure(energy, alf, dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, stress, mom, G, pres_mag)
118118
$:GPU_ROUTINE(function_name='s_compute_pressure',parallelism='[seq]', &
119-
& cray_inline=True)
119+
& cray_noinline=True)
120120

121121
real(stp), intent(in) :: energy, alf
122122
real(wp), intent(in) :: dyn_p
@@ -326,7 +326,7 @@ contains
326326
alpha_K, alpha_rho_K, Re_K, &
327327
G_K, G)
328328
$:GPU_ROUTINE(function_name='s_convert_species_to_mixture_variables_acc', &
329-
& parallelism='[seq]', cray_inline=True)
329+
& parallelism='[seq]', cray_noinline=True)
330330

331331
real(wp), intent(out) :: rho_K, gamma_K, pi_inf_K, qv_K
332332
#:if not MFC_CASE_OPTIMIZATION and USING_AMD
@@ -1335,7 +1335,7 @@ contains
13351335
!> This subroutine computes partial densities and volume fractions
13361336
subroutine s_compute_species_fraction(q_vf, k, l, r, alpha_rho_K, alpha_K)
13371337
$:GPU_ROUTINE(function_name='s_compute_species_fraction', &
1338-
& parallelism='[seq]', cray_inline=True)
1338+
& parallelism='[seq]', cray_noinline=True)
13391339
type(scalar_field), dimension(sys_size), intent(in) :: q_vf
13401340
integer, intent(in) :: k, l, r
13411341
#:if not MFC_CASE_OPTIMIZATION and USING_AMD
@@ -1480,7 +1480,7 @@ contains
14801480
!> @brief Computes the fast magnetosonic wave speed from the sound speed, density, and magnetic field components.
14811481
subroutine s_compute_fast_magnetosonic_speed(rho, c, B, norm, c_fast, h)
14821482
$:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', &
1483-
& parallelism='[seq]', cray_inline=True)
1483+
& parallelism='[seq]', cray_noinline=True)
14841484

14851485
real(wp), intent(in) :: B(3), rho, c
14861486
real(wp), intent(in) :: h ! only used for relativity

src/simulation/m_bubbles_EL.fpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,8 +1532,7 @@ contains
15321532
integer(KIND=MPI_OFFSET_KIND) :: disp
15331533
integer :: view
15341534
integer, dimension(2) :: gsizes, lsizes, start_idx_part
1535-
integer, dimension(num_procs) :: part_order, part_ord_mpi
1536-
integer, dimension(num_procs) :: proc_bubble_counts
1535+
integer, allocatable :: proc_bubble_counts(:)
15371536
real(wp), dimension(1:1, 1:lag_io_vars) :: dummy
15381537
dummy = 0._wp
15391538

@@ -1548,6 +1547,8 @@ contains
15481547

15491548
if (.not. parallel_io) return
15501549

1550+
allocate (proc_bubble_counts(num_procs))
1551+
15511552
lsizes(1) = bub_id
15521553
lsizes(2) = lag_io_vars
15531554

@@ -1659,6 +1660,8 @@ contains
16591660
call MPI_FILE_CLOSE(ifile, ierr)
16601661
end if
16611662
1663+
deallocate (proc_bubble_counts)
1664+
16621665
#endif
16631666
16641667
end subroutine s_write_restart_lag_bubbles

toolchain/mfc/run/input.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,44 @@ def generate_fpp(self, target) -> None:
9090
directive_str = None
9191

9292
# Write the generated Fortran code to the m_thermochem.f90 file with the chosen precision
93+
sol = self.get_cantera_solution()
94+
95+
thermochem_code = pyro.FortranCodeGenerator().generate(
96+
"m_thermochem",
97+
sol,
98+
pyro.CodeGenerationOptions(scalar_type = real_type, directive_offload = directive_str)
99+
)
100+
101+
# CCE 19.0.0 workaround: pyrometheus generates !DIR$ INLINEALWAYS for Cray+ACC
102+
# but omits !$acc routine seq, so thermochem routines are not registered as
103+
# OpenACC device routines. Replace with plain !$acc routine seq (no INLINEALWAYS).
104+
# This patch can be removed once pyrometheus upstream correctly emits !$acc routine seq
105+
# for Cray+OpenACC (the broken macro originates in pyrometheus's code generator).
106+
if directive_str == 'acc':
107+
old_macro = (
108+
"#ifdef _CRAYFTN\n#define GPU_ROUTINE(name) !DIR$ INLINEALWAYS name\n"
109+
"#else\n#define GPU_ROUTINE(name) !$acc routine seq\n#endif"
110+
)
111+
new_macro = "#define GPU_ROUTINE(name) !$acc routine seq"
112+
patched = thermochem_code.replace(old_macro, new_macro)
113+
if patched == thermochem_code:
114+
if new_macro in thermochem_code:
115+
pass # pyrometheus already emits the correct form; no patch needed
116+
else:
117+
raise common.MFCException(
118+
"CCE 19.0.0 workaround: pyrometheus output format changed — "
119+
"Cray+ACC GPU_ROUTINE macro patch did not apply. "
120+
"Update the pattern in toolchain/mfc/run/input.py."
121+
)
122+
else:
123+
cons.print("[yellow]Warning: Applied CCE 19.0.0 workaround patch to pyrometheus-generated "
124+
"m_thermochem.f90 (replaced _CRAYFTN GPU_ROUTINE macro with !$acc routine seq). "
125+
"Remove this patch once pyrometheus emits correct Cray+ACC directives upstream.[/yellow]")
126+
thermochem_code = patched
127+
93128
common.file_write(
94129
os.path.join(modules_dir, "m_thermochem.f90"),
95-
pyro.FortranCodeGenerator().generate(
96-
"m_thermochem",
97-
self.get_cantera_solution(),
98-
pyro.CodeGenerationOptions(scalar_type = real_type, directive_offload = directive_str)
99-
),
130+
thermochem_code,
100131
True
101132
)
102133

0 commit comments

Comments
 (0)