From 075b9019cfc893774b70df743c1b7cb159185434 Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Sun, 13 Sep 2026 10:52:18 -0400 Subject: [PATCH] ci: use two-pass IPO for OpenMP offload as well The NVHPC two-pass IPO (-Mextract/-Minline) was applied to OpenACC and skipped wholesale for OpenMP offload, so the OpenMP lane gave up cross-file inlining entirely. The reason turns out to be a single compiler bug rather than anything structural: nvfortran-Fatal-.../tools/fort2 TERMINATED by signal 11 gmake[3]: *** [.../m_data_output.fpp.f90.o] Error 2 fort2 segfaults inlining into m_data_output under OpenMP offload; OpenACC compiles the same file cleanly. This is the same failure class as the existing m_start_up/m_cbc exclusions -- OpenMP offload just reaches it in one more place -- so it gets the same treatment, scoped with MFC_OpenMP so the OpenACC build is unaffected. With that one exclusion the OpenMP build completes with no crashes (all four targets), and on A100 / NVHPC 25.11 a 1D sweep gives 175 passed and zero tolerance mismatches. The six cases that the OpenACC IPO bug corrupted all pass here. Worth weighing before merging: OpenMP offload has been the one NVHPC GPU path not subject to this pass, and that independence is exactly what identified the OpenACC miscompile -- omp passing 713/713 where acc failed 23 is what ruled out the physics. Enabling IPO here buys inlining on that lane at the cost of that cross-check, on a pass with a track record of three separate defects, one of them silent. Reasonable either way, but it should be a deliberate call and not a side effect. Depends on nothing, but touches the same block as the m_pressure_relaxation exclusion; whichever lands second needs a one-line rebase. Claude-Session: https://claude.ai/code/session_017zrZooJPhZtZYgg9fJiYhg --- cmake/MFCTargets.cmake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/MFCTargets.cmake b/cmake/MFCTargets.cmake index 1668adbb0..7faac8c2f 100644 --- a/cmake/MFCTargets.cmake +++ b/cmake/MFCTargets.cmake @@ -23,7 +23,7 @@ function(MFC_SETUP_TARGET) set(IPO_TARGETS ${ARGS_TARGET}) # Here we need to split into "library" and "executable" to perform IPO on the NVIDIA compiler. # A little hacky, but it *is* an edge-case for *one* compiler. - if (NVHPC_USE_TWO_PASS_IPO AND NOT(MFC_OpenMP AND ARGS_OpenMP)) + if (NVHPC_USE_TWO_PASS_IPO) # nvfortran -Mextract does not produce .o files, only inline library # data. An OBJECT library with -Mextract causes CMake to rebuild # everything on every build because the expected .o outputs never @@ -61,7 +61,14 @@ exit 0 # initialization/boundary code that trigger NVHPC 25.x fort2 ICE when # too many functions are cross-inlined into them. GPU hot-path files # (m_rhs, m_riemann_solvers, m_viscous, m_weno, etc.) keep full IPO. - foreach(_no_inline_file m_start_up m_cbc) + set(_no_inline_files m_start_up m_cbc) + # OpenMP offload additionally segfaults fort2 (signal 11) inlining into + # m_data_output, which OpenACC compiles cleanly. Scoped so the OpenACC + # build keeps full inlining there. + if (MFC_OpenMP AND ARGS_OpenMP) + list(APPEND _no_inline_files m_data_output) + endif() + foreach(_no_inline_file ${_no_inline_files}) set_source_files_properties( "${CMAKE_BINARY_DIR}/fypp/${ARGS_TARGET}/${_no_inline_file}.fpp.f90" TARGET_DIRECTORY ${ARGS_TARGET}