-
Notifications
You must be signed in to change notification settings - Fork 21
Thread execution spaces through vector API #630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
6ba7a14
update ports
jonahm-LANL dc72ae5
thread spaces through API calls in base class
jonahm-LANL c4fa646
fill eos in variant class
jonahm-LANL af19c21
and threaded through the variant
jonahm-LANL 215732b
Do it with SieFromDensityPressure
jonahm-LANL 959f616
Merge branch 'jmm/python-warnings' into jmm/thread-spaces
jonahm-LANL 7c45226
Merge branch 'jmm/python-warnings' into jmm/thread-spaces
jonahm-LANL afa924f
working commit
jonahm-LANL c78ab37
Thread it through the rest
jonahm-LANL a3d270e
Merge branch 'main' into jmm/thread-spaces
jonahm-LANL e65fd46
host space in python module
jonahm-LANL 971fd73
leverage macros for overloads
jonahm-LANL b78d0b4
macro needs scratch
jonahm-LANL b2d4286
lets try with explicit overloads
jonahm-LANL bd4008f
documentation
jonahm-LANL fbcb830
test
jonahm-LANL d2422a6
Add tests
jonahm-LANL 3dd1963
the sfinae needed a check of non-indexable index for Space and yes-in…
jonahm-LANL b81da8c
unused variable
jonahm-LANL e414821
name template SFINAEs
jonahm-LANL cb56624
name the SFINAE types
jonahm-LANL 400a3a3
formatting
jonahm-LANL 77b22bb
add overloads for space to the modifiers
jonahm-LANL c41b8ee
changelog
jonahm-LANL 3db0a99
clean up doc
jonahm-LANL a5dec5e
formatting
jonahm-LANL 668b871
add modifier wrapper macros
jonahm-LANL 1e33c88
dramatically reduce boiler plate in modifiers with overloads with mor…
jonahm-LANL 4e9d77d
macros comment
jonahm-LANL 20dae89
formatting
jonahm-LANL 76b9fe8
fix hard compare
jonahm-LANL 9f9c1a8
CC
jonahm-LANL cb9a328
oops now CC
jonahm-LANL 35c4a75
formatting
jonahm-LANL 93bed3d
plan history for macros for modifier overloads
jonahm-LANL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
186 changes: 186 additions & 0 deletions
186
plan_histories/MR630-2026-04-09-modifier-vector-macro-proposal.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| # MR630 Modifier Vector Macro Proposal | ||
|
|
||
| ## Goal | ||
|
|
||
| Reduce the line count in `singularity-eos/eos/modifiers/*.hpp` for the raw-pointer | ||
| vector API, especially the overloads that only forward to | ||
| `PortsOfCall::Exec::Device()`. | ||
|
|
||
| ## Current Situation | ||
|
|
||
| The modified vector API in the modifier headers now has two overload families for each | ||
| raw-pointer vector method: | ||
|
|
||
| 1. A `Space` overload: | ||
|
|
||
| ```cpp | ||
| template <typename Space, typename LambdaIndexer, | ||
| typename EnableIfSpace = | ||
| std::enable_if_t<!variadic_utils::has_int_index_v<Space>>> | ||
| inline void NAME(const Space &s, ...); | ||
| ``` | ||
|
|
||
| 2. A default-device wrapper: | ||
|
|
||
| ```cpp | ||
| template <typename LambdaIndexer> | ||
| inline void NAME(...) const { | ||
| NAME(PortsOfCall::Exec::Device(), ...); | ||
| } | ||
| ``` | ||
|
|
||
| This repeats across: | ||
|
|
||
| - `scaled_eos.hpp` | ||
| - `shifted_eos.hpp` | ||
| - `eos_unitsystem.hpp` | ||
| - `ramps_eos.hpp` | ||
| - `floored_energy.hpp` | ||
|
|
||
| ## Important Constraint | ||
|
|
||
| The default-device wrappers cannot simply be deleted while preserving the current API. | ||
| The inherited wrappers in `eos/eos_base.hpp` do not automatically route into the | ||
| modifier-specific raw-pointer `Space` overloads. If we want to keep the existing | ||
| call surface, the realistic near-term win is to generate these wrappers, not remove the | ||
| behavior. | ||
|
|
||
| ## Recommended Macro Scheme | ||
|
|
||
| Introduce a small modifier-only macro header, for example: | ||
|
|
||
| - `singularity-eos/eos/modifiers/modifier_vector_macros.hpp` | ||
|
|
||
| That header would define the default-device wrappers once. | ||
|
|
||
| ### 2-in / 1-out wrapper | ||
|
|
||
| ```cpp | ||
| #define SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(NAME) \ | ||
| template <typename LambdaIndexer> \ | ||
| inline void NAME(const Real *in1, const Real *in2, Real *out, Real *scratch, \ | ||
| const int num, LambdaIndexer &&lambdas, \ | ||
| Transform &&transform = Transform()) const { \ | ||
| NAME(PortsOfCall::Exec::Device(), in1, in2, out, scratch, num, \ | ||
| std::forward<LambdaIndexer>(lambdas), std::forward<Transform>(transform)); \ | ||
| } | ||
| ``` | ||
|
|
||
| ### 1-in / 1-out wrapper | ||
|
|
||
| ```cpp | ||
| #define SG_MODIFIER_DEVICE_WRAP_1IN_1OUT(NAME) \ | ||
| template <typename LambdaIndexer> \ | ||
| inline void NAME(const Real *in1, Real *out, Real *scratch, const int num, \ | ||
| LambdaIndexer &&lambdas, \ | ||
| Transform &&transform = Transform()) const { \ | ||
| NAME(PortsOfCall::Exec::Device(), in1, out, scratch, num, \ | ||
| std::forward<LambdaIndexer>(lambdas), std::forward<Transform>(transform)); \ | ||
| } | ||
| ``` | ||
|
|
||
| ### Aggregate wrapper list | ||
|
|
||
| ```cpp | ||
| #define SG_MODIFIER_DEVICE_WRAP_ALL() \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(TemperatureFromDensityInternalEnergy) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(PressureFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(PressureFromDensityInternalEnergy) \ | ||
| SG_MODIFIER_DEVICE_WRAP_1IN_1OUT(MinInternalEnergyFromDensity) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(SpecificHeatFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(SpecificHeatFromDensityInternalEnergy) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(BulkModulusFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(BulkModulusFromDensityInternalEnergy) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(GruneisenParamFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(GruneisenParamFromDensityInternalEnergy) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(InternalEnergyFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(EntropyFromDensityTemperature) \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(EntropyFromDensityInternalEnergy) | ||
| ``` | ||
|
|
||
| ## How This Would Be Used | ||
|
|
||
| Each modifier would keep only its `Space` overload implementations. At the end of the | ||
| vector API block, it would add: | ||
|
|
||
| ```cpp | ||
| SG_MODIFIER_DEVICE_WRAP_ALL() | ||
| ``` | ||
|
|
||
| That removes most of the duplicate default-device wrapper code while preserving the | ||
| current behavior. | ||
|
|
||
| ## Second Stage for Simple Forwarders | ||
|
|
||
| For `scaled_eos.hpp` and `eos_unitsystem.hpp`, the `Space` overload bodies are also | ||
| highly repetitive: | ||
|
|
||
| - update `transform` | ||
| - call `t_.NAME(s, ...)` | ||
|
|
||
| Those two files could use a second macro family such as: | ||
|
|
||
| ```cpp | ||
| #define SG_MODIFIER_FORWARD_2IN_1OUT(NAME, PREPARE) \ | ||
| template <typename Space, typename LambdaIndexer, \ | ||
| typename EnableIfSpace = \ | ||
| std::enable_if_t<!variadic_utils::has_int_index_v<Space>>> \ | ||
| inline void NAME(const Space &s, const Real *in1, const Real *in2, Real *out, \ | ||
| Real *scratch, const int num, LambdaIndexer &&lambdas, \ | ||
| Transform &&transform = Transform()) const { \ | ||
| PREPARE \ | ||
| t_.NAME(s, in1, in2, out, scratch, num, \ | ||
| std::forward<LambdaIndexer>(lambdas), std::forward<Transform>(transform)); \ | ||
| } \ | ||
| SG_MODIFIER_DEVICE_WRAP_2IN_1OUT(NAME) | ||
| ``` | ||
|
|
||
| Example usage: | ||
|
|
||
| ```cpp | ||
| SG_MODIFIER_FORWARD_2IN_1OUT( | ||
| TemperatureFromDensityInternalEnergy, | ||
| transform.x.apply(scale_); | ||
| transform.y.apply(inv_scale_);) | ||
| ``` | ||
|
|
||
| ## Where Not to Overuse Macros | ||
|
|
||
| I would not force the body macros into: | ||
|
|
||
| - `shifted_eos.hpp` | ||
| - `floored_energy.hpp` | ||
| - `ramps_eos.hpp` | ||
|
|
||
| Those files contain real per-method logic: | ||
|
|
||
| - scratch-buffer preprocessing and postprocessing | ||
| - local `portableFor` loops | ||
| - ramp-pressure overrides | ||
|
|
||
| For those files, the better tradeoff is: | ||
|
|
||
| - keep explicit `Space` overload bodies | ||
| - macro-generate only the default-device wrappers | ||
|
|
||
| ## Alternative If True Elimination Is Desired | ||
|
|
||
| If the actual goal is to eliminate per-file default-device overloads entirely, use a CRTP | ||
| mixin instead of macros. Each modifier would define only the `Space` overloads, and the | ||
| mixin would provide the no-space wrappers once. | ||
|
|
||
| That is conceptually cleaner than making the macro scheme more aggressive, but it is a | ||
| larger refactor than the macro-only approach above. | ||
|
|
||
| ## Recommendation | ||
|
|
||
| Preferred implementation order: | ||
|
|
||
| 1. Add a shared modifier macro header that generates the default-device wrappers. | ||
| 2. Convert all five modified modifier headers to use that wrapper macro set. | ||
| 3. Optionally add the forwarding-body macros for `ScaledEOS` and `EOSUnitSystem`. | ||
| 4. Leave `ShiftedEOS`, `FlooredEnergy`, and `BilinearRampEOS` with explicit `Space` | ||
| overload bodies. | ||
|
|
||
| This gives most of the line-count reduction without hiding the custom vector logic that | ||
| still needs to be readable. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,8 +302,8 @@ class VariadicIndexerBase { | |
| PORTABLE_FORCEINLINE_FUNCTION | ||
| VariadicIndexerBase(const Data_t &data) : data_(data) {} | ||
|
|
||
| template <typename T, | ||
| typename = std::enable_if_t<variadic_utils::contains<T, Ts...>::value>> | ||
| template <typename T, typename EnableIfContained = | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naming the SFINAE/concept type produced more useful error messages from the cuda compiler. |
||
| std::enable_if_t<variadic_utils::contains<T, Ts...>::value>> | ||
| PORTABLE_FORCEINLINE_FUNCTION Real &operator[](const T &t) { | ||
| constexpr std::size_t idx = variadic_utils::GetIndexInTL<T, Ts...>(); | ||
| return data_[idx]; | ||
|
|
@@ -312,8 +312,8 @@ class VariadicIndexerBase { | |
| PORTABLE_FORCEINLINE_FUNCTION | ||
| Real &operator[](const std::size_t idx) { return data_[idx]; } | ||
|
|
||
| template <typename T, | ||
| typename = std::enable_if_t<variadic_utils::contains<T, Ts...>::value>> | ||
| template <typename T, typename EnableIfContained = | ||
| std::enable_if_t<variadic_utils::contains<T, Ts...>::value>> | ||
| PORTABLE_FORCEINLINE_FUNCTION const Real &operator[](const T &t) const { | ||
| constexpr std::size_t idx = variadic_utils::GetIndexInTL<T, Ts...>(); | ||
| return data_[idx]; | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eliminates an unused variable warning