Skip to content

Commit 32ed376

Browse files
committed
Resolve the state-dependent EOS switch at build time under case optimization
A kernel is allocated registers for the worst path through its call graph, so the state-dependent EOS chain costs occupancy in every kernel that can reach it even when the runtime branch is never taken. On gfx90a that took the HLLC kernel from 142 to 250 VGPRs, three waves per SIMD down to two, and cost 17 to 27 percent grind on the Riemann-solver benchmarks with no such EOS in the case. Baking any_state_dependent_eos lets the compiler drop the chain outright: case-optimized, the kernel registers are now identical to master. Generic builds are unchanged, since a generic binary must still carry every family. fluid_pp%eos stays in the namelist while the flag is baked, so the initializer checks the two agree rather than silently running the wrong branch.
1 parent 10beffb commit 32ed376

4 files changed

Lines changed: 30 additions & 7 deletions

File tree

src/common/m_global_parameters_common.fpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,13 @@ module m_global_parameters_common
6262
real(wp), allocatable, dimension(:) :: mg_mu_maxs !< Compression at which a cubic Hugoniot fit turns over
6363
real(wp), allocatable, dimension(:) :: jwl_as, jwl_bs, jwl_r1s, jwl_r2s
6464
real(wp), allocatable, dimension(:) :: vinet_k0s, vinet_k0ps
65-
logical :: any_state_dependent_eos !< True when some fluid's coefficients vary with density; set at init
65+
!> any_state_dependent_eos is declared with the case-optimization block above: a parameter when the case is baked in, so the
66+
!! compiler drops the whole state-dependent chain from kernels that never need it.
6667
$:GPU_DECLARE(create='[eoss, rho0s, t0s, gruneisen0s, gruneisen_as, mg_c0s, mg_ss, mg_s2s, mg_s3s, mg_mu_maxs, jwl_as, &
67-
& jwl_bs, jwl_r1s, jwl_r2s, vinet_k0s, vinet_k0ps, any_state_dependent_eos]')
68+
& jwl_bs, jwl_r1s, jwl_r2s, vinet_k0s, vinet_k0ps]')
69+
#:if not MFC_CASE_OPTIMIZATION
70+
$:GPU_DECLARE(create='[any_state_dependent_eos]')
71+
#:endif
6872
!> @}
6973

7074
!> @name Fluids participating in shear and bulk viscosity

src/common/m_variables_conversion.fpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ contains
254254
logical, optional, intent(in) :: enforce_density_floor, preserve_qbmm_number
255255
integer, optional, intent(in) :: lagrange_beta_index
256256
logical :: allocate_mixture_fields
257+
logical :: state_dependent !< Whether this case's fluids need a density-dependent EOS
257258
258259
allocate_mixture_fields = .false.
259260
if (present(store_mixture_fields)) allocate_mixture_fields = store_mixture_fields
@@ -280,7 +281,7 @@ contains
280281
@:ALLOCATE(qvps (1:num_fluids))
281282
@:ALLOCATE(Gs_vc (1:num_fluids))
282283
283-
any_state_dependent_eos = .false.
284+
state_dependent = .false.
284285
do i = 1, num_fluids
285286
gammas(i) = fluid_pp(i)%gamma
286287
isentrope_n(i) = f_isentrope_exponent(gammas(i))
@@ -335,11 +336,21 @@ contains
335336
gruneisen0s(i) = fluid_pp(i)%vinet_gruneisen
336337
gruneisen_as(i) = fluid_pp(i)%vinet_gruneisen_a
337338
end select
338-
if (f_is_state_dependent(i)) any_state_dependent_eos = .true.
339+
if (f_is_state_dependent(i)) state_dependent = .true.
339340
end do
341+
#:if MFC_CASE_OPTIMIZATION
342+
! Baked in at build time, so a case that changed its EOS family since the build would silently
343+
! run the wrong branch. The namelist still carries fluid_pp%eos, so check the two agree.
344+
@:PROHIBIT(state_dependent .neqv. any_state_dependent_eos, &
345+
& "This case's equations of state do not match the ones this case-optimized binary was built for. Rebuild.")
346+
#:else
347+
any_state_dependent_eos = state_dependent
348+
#:endif
340349
$:GPU_UPDATE(device='[gammas, isentrope_n, pi_infs, isentrope_B, cvs, qvs, qvps, Gs_vc, eoss, rho0s, t0s, gruneisen0s, &
341-
& gruneisen_as, mg_c0s, mg_ss, mg_s2s, mg_s3s, mg_mu_maxs, jwl_as, jwl_bs, jwl_r1s, jwl_r2s, vinet_k0s, &
342-
& vinet_k0ps, any_state_dependent_eos]')
350+
& gruneisen_as, mg_c0s, mg_ss, mg_s2s, mg_s3s, mg_mu_maxs, jwl_as, jwl_bs, jwl_r1s, jwl_r2s, vinet_k0s, vinet_k0ps]')
351+
#:if not MFC_CASE_OPTIMIZATION
352+
$:GPU_UPDATE(device='[any_state_dependent_eos]')
353+
#:endif
343354
344355
@:ALLOCATE(Res_vc(1:2, 1:max(1, Re_size_max)))
345356
Res_vc = dflt_real

toolchain/mfc/case.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ def __get_sim_fpp(self, print: bool) -> str:
371371
else:
372372
num_vels = num_dims
373373

374+
# Baking this lets the compiler drop the state-dependent EOS chain entirely. Left in the
375+
# call graph it costs registers, and so occupancy, in every kernel that can reach it.
376+
eos_state_dependent = {3, 4, 5} # Mie-Gruneisen, JWL, Vinet; see eos_* in m_constants.fpp
377+
num_fluids_case = int(self.params.get("num_fluids", 1))
378+
any_state_dependent_eos = 1 if any(int(self.params.get(f"fluid_pp({f})%eos", 1)) in eos_state_dependent for f in range(1, num_fluids_case + 1)) else 0
379+
374380
mhd = 1 if self.params.get("mhd", "F") == "T" else 0
375381
relativity = 1 if self.params.get("relativity", "F") == "T" else 0
376382
viscous = 1 if self.params.get("viscous", "F") == "T" else 0
@@ -404,6 +410,7 @@ def __get_sim_fpp(self, print: bool) -> str:
404410
#:set igr_pres_lim = {igr_pres_lim}
405411
#:set igr_order = {self.params.get("igr_order", 3)}
406412
#:set viscous = {viscous}
413+
#:set any_state_dependent_eos = {any_state_dependent_eos}
407414
"""
408415

409416
else:

toolchain/mfc/params/generators/fortran_gen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,9 @@ def generate_constants_fpp() -> str:
283283
("muscl_polyn", "integer", "Degree of the MUSCL polynomials"),
284284
("weno_num_stencils", "integer", "Number of stencils for WENO reconstruction"),
285285
("wenojs", "logical", "WENO-JS (default)"),
286+
("any_state_dependent_eos", "logical", "Some fluid's coefficients vary with density"),
286287
]
287-
COMMON_CASE_OPT_EXTRA_NAMES = {"num_dims", "num_vels", "weno_polyn", "muscl_polyn"}
288+
COMMON_CASE_OPT_EXTRA_NAMES = {"num_dims", "num_vels", "weno_polyn", "muscl_polyn", "any_state_dependent_eos"}
288289

289290
_CASE_OPT_DECL_COL = 24 # '::' alignment for case-opt declarations
290291

0 commit comments

Comments
 (0)