From 6f5ab354c3e76115078d6d0f361c4e5b40621716 Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Sun, 13 Sep 2026 10:50:18 -0400 Subject: [PATCH 1/3] fix: stop NVHPC IPO silently miscompiling the six-equation relaxation kernel NVHPC's two-pass IPO (-Mextract/-Minline) miscompiles m_pressure_relaxation in OpenACC device code: inlining the equation-of-state chain into the six-equation relaxation kernel drops the internal-energy update entirely. It emits no diagnostic -- the build succeeds and the answer is wrong. The result is a conserved state where alpha and alpha_rho are correct and int_en is not. The smallest reproducer is one fluid, plain stiffened gas, model_eqns=3 (test 2F35A1FE), where internal energy comes out as exactly 0.0 instead of 2.5 while every other conserved variable matches its golden value. This has failed 23 model_eqns=3 tests on the NVHPC OpenACC lane since #1811, and because the failure is inherited from master it landed on every PR branched after it -- including PRs that only touched a shell script or documentation, which is what made it look spurious. The lane split is what identifies the cause: OpenMP offload skips this IPO pass (MFCTargets.cmake:26) and passes 713/713 on the same commits, Frontier CCE is not NVHPC and passes, and a CPU build of the same source on the same machine and compiler passes. Rebuilding OpenACC with IPO disabled makes all six reproducible 1D failures pass, and the targeted exclusion here does the same while keeping full IPO on the hot-path files. This is the third workaround for this pass, after the -Minline except: list and the existing m_start_up/m_cbc exclusions, and the first where it produced a wrong answer rather than a compile error. Verified on A100 / NVHPC 25.11, which reproduces the Phoenix V100 / NVHPC 25.5 failure bit for bit (0.80999999999592 vs a golden 0.80999999998385). Six of six reproducers pass, and a full 1D sweep goes from six tolerance failures to zero with no new ones. Note: verification here is 1D. The remaining failures in CI are 2D and 3D (axisymmetric, capillary, viscous IBM, recovering_sphere) and want a Phoenix run to confirm. Claude-Session: https://claude.ai/code/session_017zrZooJPhZtZYgg9fJiYhg --- cmake/MFCTargets.cmake | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/cmake/MFCTargets.cmake b/cmake/MFCTargets.cmake index 1668adbb0..20b1a2dfd 100644 --- a/cmake/MFCTargets.cmake +++ b/cmake/MFCTargets.cmake @@ -57,11 +57,20 @@ exit 0 add_dependencies(${ARGS_TARGET} ${ARGS_TARGET}_lib) target_compile_options(${ARGS_TARGET} PRIVATE -Minline=lib:${ARGS_TARGET}_lib,except:f_is_default,except:s_compute_dt,except:my_inquire,except:s_mpi_abort,except:s_mpi_barrier,except:s_prohibit_abort,except:s_int_to_str,except:s_associate_cbc_coefficients_pointers) - # Exclude m_start_up and m_cbc from cross-file inlining: these are - # initialization/boundary code that trigger NVHPC 25.x fort2 ICE when - # too many functions are cross-inlined into them. GPU hot-path files + # Exclude these files from cross-file inlining. 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) + # + # m_start_up, m_cbc initialization/boundary code that trigger + # NVHPC 25.x fort2 ICEs when too many functions + # are cross-inlined into them. + # m_pressure_relaxation worse than an ICE, because it compiles: inlining + # the equation-of-state chain (s_phase_coefficients + # -> s_eos_coefficients -> s_reference_curve, + # s_phase_internal_energy, f_pressure) into the + # six-equation relaxation kernel silently drops the + # internal-energy update, leaving alpha and + # alpha_rho correct and int_en zero. + foreach(_no_inline_file m_start_up m_cbc m_pressure_relaxation) set_source_files_properties( "${CMAKE_BINARY_DIR}/fypp/${ARGS_TARGET}/${_no_inline_file}.fpp.f90" TARGET_DIRECTORY ${ARGS_TARGET} From e9a3d79b71be1a49885d227d96f431a1e724f7dd Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Sun, 13 Sep 2026 13:19:48 -0500 Subject: [PATCH 2/3] Fix typo in module m_cbc brief comment --- src/simulation/m_cbc.fpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation/m_cbc.fpp b/src/simulation/m_cbc.fpp index 0e1a4dc7b..f9dde4f5a 100644 --- a/src/simulation/m_cbc.fpp +++ b/src/simulation/m_cbc.fpp @@ -2,7 +2,7 @@ !! @file !! @brief Contains module m_cbc -!> @brief Characteristic boundary conditions (CBC) for slip walls, non-reflecting subsonic inflow/outflow, and supersonic boundaries +!> @brief Characteristic boundary conditions (CBCs) for slip walls, non-reflecting subsonic inflow/outflow, and supersonic boundaries #:include 'case.fpp' #:include 'macros.fpp' From 4cd194786d00da028fa6d593f0d52e61ee7d907e Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Sun, 13 Sep 2026 14:27:37 -0400 Subject: [PATCH 3/3] style: wrap the m_cbc brief comment the typo fix pushed over the limit "CBC" -> "CBCs" took the line to 133 characters, one past the 132 the formatter enforces, so the Formatting check failed on a file this branch does not otherwise touch. --- src/simulation/m_cbc.fpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/simulation/m_cbc.fpp b/src/simulation/m_cbc.fpp index f9dde4f5a..09146f2dc 100644 --- a/src/simulation/m_cbc.fpp +++ b/src/simulation/m_cbc.fpp @@ -2,7 +2,8 @@ !! @file !! @brief Contains module m_cbc -!> @brief Characteristic boundary conditions (CBCs) for slip walls, non-reflecting subsonic inflow/outflow, and supersonic boundaries +!> @brief Characteristic boundary conditions (CBCs) for slip walls, non-reflecting subsonic inflow/outflow, and supersonic +!! boundaries #:include 'case.fpp' #:include 'macros.fpp'