From 11b2621daaf0b7d6ce53a34ccf88a9d78ebef9b5 Mon Sep 17 00:00:00 2001 From: Michael Zingale Date: Wed, 22 Oct 2025 11:16:27 -0400 Subject: [PATCH 1/5] squeeze some more space out of VODE's memory footprint --- integration/VODE/vode_type.H | 26 +++++++++++++------------- integration/integrator_data.H | 8 +++++++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/integration/VODE/vode_type.H b/integration/VODE/vode_type.H index 3c246bfb50..8c13016ec5 100644 --- a/integration/VODE/vode_type.H +++ b/integration/VODE/vode_type.H @@ -24,11 +24,11 @@ constexpr amrex::Real vode_decrease_change_factor = 0.25_rt; // For the backward differentiation formula (BDF) integration // the maximum order should be no greater than 5. -constexpr int VODE_MAXORD = 5; -constexpr int VODE_LMAX = VODE_MAXORD + 1; +constexpr std::uint8_t VODE_MAXORD = 5; +constexpr std::uint8_t VODE_LMAX = VODE_MAXORD + 1; // How many timesteps should pass before refreshing the Jacobian -constexpr int max_steps_between_jacobian_evals = 50; +constexpr std::uint8_t max_steps_between_jacobian_evals = 50; // Type dvode_t contains the integration solution and control variables template @@ -86,31 +86,31 @@ struct dvode_t // (recoverable error) // 2 means convergence failure with current Jacobian or // singular matrix (unrecoverable error) - short ICF; + std::int8_t ICF; // IPUP = Saved flag to signal updating of Newton matrix - short IPUP; + bool IPUP; // JCUR = Output flag from DVJAC showing Jacobian status: // JCUR = 0 means J is not current // JCUR = 1 means J is current - short JCUR; + bool JCUR; // L = Integer variable, NQ + 1, current order plus one - short L; + std::int8_t L; // NEWH = Saved integer to flag change of H - short NEWH; + std::int8_t NEWH; // NEWQ = The method order to be used on the next step - short NEWQ; + std::int8_t NEWQ; // NQ = Integer variable, the current integration method order - short NQ; + std::int8_t NQ; // NQWAIT = A counter controlling the frequency of order changes. // An order change is about to be considered if NQWAIT = 1. - short NQWAIT; + std::int8_t NQWAIT; // NSLJ = The number of steps taken as of the last Jacobian update int NSLJ; @@ -119,7 +119,7 @@ struct dvode_t int NSLP; // jacobian_type = the type of Jacobian to use (1 = analytic, 2 = numerical) - short jacobian_type; + std::int8_t jacobian_type; // EL = Real array of integration coefficients. See DVSET amrex::Array1D el; @@ -155,7 +155,7 @@ struct dvode_t amrex::Array1D ewt, savf; - amrex::Array1D pivot; + IArray1D pivot; // Array of size NEQ used for the accumulated corrections on each // step, scaled in the output to represent the estimated local diff --git a/integration/integrator_data.H b/integration/integrator_data.H index 2d4f7795cd..e73e96d724 100644 --- a/integration/integrator_data.H +++ b/integration/integrator_data.H @@ -1,12 +1,18 @@ #ifndef INTEGRATOR_DATA_H #define INTEGRATOR_DATA_H +#include + #include // Define the size of the ODE system that VODE will integrate constexpr int INT_NEQS = NumSpec + 1; +// the datatype we will use for integer quantities that hold +// indexing into our INT_NEQS +using smallint_t = std::conditional_t<(INT_NEQS < 255), std::uint8_t, short>; + // We will use this parameter to determine if a given species // abundance is unreasonably small or large (each X must satisfy // -failure_tolerance <= X <= 1.0 + failure_tolerance). @@ -50,7 +56,7 @@ constexpr int integrator_neqs () return int_neqs; } -using IArray1D = amrex::Array1D; +using IArray1D = amrex::Array1D; using RArray1D = amrex::Array1D; using RArray2D = ArrayUtil::MathArray2D<1, INT_NEQS, 1, INT_NEQS>; From 776cb2428ccd6848feb9ca6d63f40fc972ec57a3 Mon Sep 17 00:00:00 2001 From: Michael Zingale Date: Wed, 22 Oct 2025 11:52:46 -0400 Subject: [PATCH 2/5] fix --- integration/VODE/vode_type.H | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/integration/VODE/vode_type.H b/integration/VODE/vode_type.H index 8c13016ec5..0e50531e9a 100644 --- a/integration/VODE/vode_type.H +++ b/integration/VODE/vode_type.H @@ -86,7 +86,7 @@ struct dvode_t // (recoverable error) // 2 means convergence failure with current Jacobian or // singular matrix (unrecoverable error) - std::int8_t ICF; + std::uint8_t ICF; // IPUP = Saved flag to signal updating of Newton matrix bool IPUP; @@ -97,20 +97,20 @@ struct dvode_t bool JCUR; // L = Integer variable, NQ + 1, current order plus one - std::int8_t L; + std::uint8_t L; // NEWH = Saved integer to flag change of H - std::int8_t NEWH; + bool NEWH; // NEWQ = The method order to be used on the next step - std::int8_t NEWQ; + std::uint8_t NEWQ; // NQ = Integer variable, the current integration method order - std::int8_t NQ; + std::uint8_t NQ; // NQWAIT = A counter controlling the frequency of order changes. // An order change is about to be considered if NQWAIT = 1. - std::int8_t NQWAIT; + std::uint8_t NQWAIT; // NSLJ = The number of steps taken as of the last Jacobian update int NSLJ; @@ -119,7 +119,7 @@ struct dvode_t int NSLP; // jacobian_type = the type of Jacobian to use (1 = analytic, 2 = numerical) - std::int8_t jacobian_type; + std::uint8_t jacobian_type; // EL = Real array of integration coefficients. See DVSET amrex::Array1D el; From a80c9b5765f9728f52c3770eb7ca298f8eb09f42 Mon Sep 17 00:00:00 2001 From: Michael Zingale Date: Tue, 28 Oct 2025 10:37:24 -0400 Subject: [PATCH 3/5] a few more fixes --- .clang-tidy | 1 - integration/VODE/vode_dvhin.H | 8 ++++---- integration/VODE/vode_dvjust.H | 2 +- integration/VODE/vode_dvode.H | 6 +++--- integration/integrator.H | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 22c13bbf90..6ecef20425 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -13,7 +13,6 @@ Checks: > -cppcoreguidelines-non-private-member-variables-in-classes, -cppcoreguidelines-pro-*, misc-*, - -misc-const-correctness, -misc-include-cleaner, -misc-non-private-member-variables-in-classes, -misc-use-anonymous-namespace, diff --git a/integration/VODE/vode_dvhin.H b/integration/VODE/vode_dvhin.H index 96c18b5756..6d6441fd74 100644 --- a/integration/VODE/vode_dvhin.H +++ b/integration/VODE/vode_dvhin.H @@ -13,7 +13,8 @@ template AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -void dvhin (BurnT& state, DvodeT& vstate, amrex::Real& H0, int& NITER, int& IER) +int +dvhin (BurnT& state, DvodeT& vstate, amrex::Real& H0, int& NITER) { // This routine computes the step size, H0, to be attempted on the // first step, when the user has not supplied a value for this. @@ -34,8 +35,7 @@ void dvhin (BurnT& state, DvodeT& vstate, amrex::Real& H0, int& NITER, int& IER) if (TDIST < 2.0_rt * TROUND) { // Error return for vstate.tout - vstate.t too small. - IER = -1; - return; + return -1; } // Set a lower bound on h based on the roundoff level in vstate.t and vstate.tout. @@ -132,7 +132,7 @@ void dvhin (BurnT& state, DvodeT& vstate, amrex::Real& H0, int& NITER, int& IER) // apply sign H0 = std::copysign(H0, vstate.tout - vstate.t); NITER = iter; - IER = 0; + return 0; } diff --git a/integration/VODE/vode_dvjust.H b/integration/VODE/vode_dvjust.H index d48caf3222..70476f42ad 100644 --- a/integration/VODE/vode_dvjust.H +++ b/integration/VODE/vode_dvjust.H @@ -77,7 +77,7 @@ void dvjust (int IORD, BurnT& state, DvodeT& vstate) ALPH0 -= 1.0_rt / (j + 1); ALPH1 += 1.0_rt / XI; for (int iback = 1; iback <= j+1; ++iback) { - int i = (j + 4) - iback; + const int i = (j + 4) - iback; vstate.el(i) = vstate.el(i) * XIOLD + vstate.el(i-1); } XIOLD = XI; diff --git a/integration/VODE/vode_dvode.H b/integration/VODE/vode_dvode.H index bbbf414398..7d414304e7 100644 --- a/integration/VODE/vode_dvode.H +++ b/integration/VODE/vode_dvode.H @@ -27,7 +27,7 @@ int dvode (BurnT& state, DvodeT& vstate) // Local variables amrex::Real H0{}, S{}; - int IER{}, NITER{}; + int NITER{}; // Flag determining if we were successful. @@ -84,7 +84,7 @@ int dvode (BurnT& state, DvodeT& vstate) // Call DVHIN to set initial step size H0 to be attempted. H0 = 0.0_rt; - dvhin(state, vstate, H0, NITER, IER); + auto IER = dvhin(state, vstate, H0, NITER); vstate.n_rhs += NITER; if (IER != 0) { @@ -189,7 +189,7 @@ int dvode (BurnT& state, DvodeT& vstate) } - int kflag = dvstep(state, vstate); + const int kflag = dvstep(state, vstate); // Branch on KFLAG. KFLAG can be 0, -1, or -2. diff --git a/integration/integrator.H b/integration/integrator.H index 2c69366ad5..e5f34dfb8f 100644 --- a/integration/integrator.H +++ b/integration/integrator.H @@ -13,7 +13,7 @@ void integrator_wrapper (BurnT& state, amrex::Real dt) { if constexpr (enable_retry) { - burn_t old_state{state}; + const burn_t old_state{state}; actual_integrator(state, dt); From 37559cc52169b5fda3878fad270f5af0314c3334 Mon Sep 17 00:00:00 2001 From: Michael Zingale Date: Tue, 28 Oct 2025 10:56:34 -0400 Subject: [PATCH 4/5] revert --- .clang-tidy | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-tidy b/.clang-tidy index 6ecef20425..22c13bbf90 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -13,6 +13,7 @@ Checks: > -cppcoreguidelines-non-private-member-variables-in-classes, -cppcoreguidelines-pro-*, misc-*, + -misc-const-correctness, -misc-include-cleaner, -misc-non-private-member-variables-in-classes, -misc-use-anonymous-namespace, From a52e0d913b1cbb764d9c484b26f7f036c2bb2f07 Mon Sep 17 00:00:00 2001 From: Michael Zingale Date: Tue, 28 Oct 2025 11:01:59 -0400 Subject: [PATCH 5/5] try again --- integration/integrator_data.H | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/integrator_data.H b/integration/integrator_data.H index e73e96d724..a0dae9c796 100644 --- a/integration/integrator_data.H +++ b/integration/integrator_data.H @@ -11,7 +11,7 @@ constexpr int INT_NEQS = NumSpec + 1; // the datatype we will use for integer quantities that hold // indexing into our INT_NEQS -using smallint_t = std::conditional_t<(INT_NEQS < 255), std::uint8_t, short>; +using smallint_t = short; //std::conditional_t<(INT_NEQS < 255), std::uint8_t, short>; // We will use this parameter to determine if a given species // abundance is unreasonably small or large (each X must satisfy