diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 00ece4de3..87163fe37 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -306,6 +306,30 @@ jobs: /bin/bash mfc.sh test -v --dry-run -j 2 --test-all --gpu mp ' + # Case-optimized build guard. + # + # --case-optimization hard-codes case parameters into the generated + # sources, which sharply increases cross-file inlining pressure in the + # -Mextract/-Minline IPO pass (cmake/MFCTargets.cmake). That pass is + # where NVHPC fort2 has historically hit internal compiler errors, and + # the jobs above cannot see them: they never pass --case-optimization, + # and the self-hosted case-opt jobs run a single pinned NVHPC. NVHPC + # 25.5 shipped an ICE that was invisible to CI for exactly that reason. + # + # One 3D case is enough: the failure is at compile time, so nothing is + # run. 3D specifically, because m_sim_helpers.fpp guards its 3D block + # with "#:if not MFC_CASE_OPTIMIZATION or num_dims > 2" -- a + # case-optimized 2D build elides that code entirely. OpenACC only, + # since the two-pass IPO is disabled for OpenMP offload. + - name: Build (NVHPC GPU, case-optimized) + if: matrix.nvhpc && matrix.target == 'gpu' + run: | + docker exec nvhpc bash -c ' + source /etc/nvhpc-env.sh + /bin/bash mfc.sh build -v -j 2 --gpu acc -t simulation \ + -i examples/3D_sphbubcollapse/case.py --case-optimization + ' + - name: Test (NVHPC) if: matrix.nvhpc && matrix.target == 'cpu' run: | diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index d0a59c4de..e50b4eed2 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -41,34 +41,6 @@ contains end function f_compute_filtered_dtheta - !> Computes inviscid CFL terms for multi-dimensional cases (2D/3D only) - function f_compute_multidim_cfl_terms(vel, c, j, k, l) result(cfl_terms) - - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c - integer, intent(in) :: j, k, l - real(wp) :: cfl_terms - real(wp) :: fltr_dtheta - - fltr_dtheta = f_compute_filtered_dtheta(k, l) - - if (p > 0) then - ! 3D - #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (grid_geometry == 3) then - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), fltr_dtheta/(abs(vel(3)) + c)) - else - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), dz(l)/(abs(vel(3)) + c)) - end if - #:endif - else - ! 2D - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c)) - end if - - end function f_compute_multidim_cfl_terms - !> Computes enthalpy subroutine s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) @@ -145,8 +117,21 @@ contains real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then - icfl = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) + ! The multi-dimensional CFL terms are written out here rather than + ! obtained from a shared helper procedure: NVHPC 25.5's fort2 segfaults + ! when a routine containing a call to that helper is cross-file inlined + ! by -Minline (the IPO setup in cmake/MFCTargets.cmake). + if (p > 0) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (grid_geometry == 3) then + fltr_dtheta = f_compute_filtered_dtheta(k, l) + icfl = dt/min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), fltr_dtheta/(abs(vel(3)) + c)) + else + icfl = dt/min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), dz(l)/(abs(vel(3)) + c)) + end if + #:endif + else if (n > 0) then + icfl = dt/min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c)) else icfl = (dt/dx(j))*(abs(vel(1)) + c) end if @@ -206,8 +191,21 @@ contains real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then - max_dt = cfl_target*f_compute_multidim_cfl_terms(vel, c, j, k, l) + ! The multi-dimensional CFL terms are written out here rather than + ! obtained from a shared helper procedure: NVHPC 25.5's fort2 segfaults + ! when a routine containing a call to that helper is cross-file inlined + ! by -Minline (the IPO setup in cmake/MFCTargets.cmake). + if (p > 0) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (grid_geometry == 3) then + fltr_dtheta = f_compute_filtered_dtheta(k, l) + max_dt = cfl_target*min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), fltr_dtheta/(abs(vel(3)) + c)) + else + max_dt = cfl_target*min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), dz(l)/(abs(vel(3)) + c)) + end if + #:endif + else if (n > 0) then + max_dt = cfl_target*min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c)) else max_dt = cfl_target*(dx(j)/(abs(vel(1)) + c)) end if