From db634abddf110207a68325ca9acab5b81ff91801 Mon Sep 17 00:00:00 2001 From: Jeffrey H Peterson Date: Wed, 29 Oct 2025 13:46:46 -0600 Subject: [PATCH 1/4] Add generic indexer --- singularity-eos/base/generic_indexer.hpp | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 singularity-eos/base/generic_indexer.hpp diff --git a/singularity-eos/base/generic_indexer.hpp b/singularity-eos/base/generic_indexer.hpp new file mode 100644 index 00000000000..70c35a2ea79 --- /dev/null +++ b/singularity-eos/base/generic_indexer.hpp @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// © 2021-2025. Triad National Security, LLC. All rights reserved. This +// program was produced under U.S. Government contract 89233218CNA000001 +// for Los Alamos National Laboratory (LANL), which is operated by Triad +// National Security, LLC for the U.S. Department of Energy/National +// Nuclear Security Administration. All rights in the program are +// reserved by Triad National Security, LLC, and the U.S. Department of +// Energy/National Nuclear Security Administration. The Government is +// granted for itself and others acting on its behalf a nonexclusive, +// paid-up, irrevocable worldwide license in this material to reproduce, +// prepare derivative works, distribute copies to the public, perform +// publicly and display publicly, and to permit others to do so. +//------------------------------------------------------------------------------ + +#ifndef SINGULARITY_EOS_BASE_GENERIC_INDEXER_HPP_ +#define SINGULARITY_EOS_BASE_GENERIC_INDEXER_HPP_ + +#include + +namespace singularity { + +template +struct GenericIndexer { + Arr arr_; + Map map_; + + template + constexpr GenericIndexer(ArrT_ &&arr_in, MapT_ &&map_in) + : arr_(std::forward(arr_in)), map_(std::forward(map_in)) {} + + // & : non-const lvalue + template + constexpr decltype(auto) operator[](I i) & { + return arr_[map_[i]]; + } + + // const& : const lvalue + template + constexpr decltype(auto) operator[](I i) const & { + return arr_[map_[i]]; + } + + // && : rvalue (indexer is a temporary) — forward arr_’s value category + template + constexpr decltype(auto) operator[](I i) && { + return std::forward(arr_)[map_[i]]; // move only if Arr is a value type + } + + // const rvalue indexer + template + constexpr decltype(auto) operator[](I i) const && { + return std::forward(arr_)[map_[i]]; // preserves const + } +}; + +// CTAD: preserve references for lvalues, decay for rvalues +template +GenericIndexer(ArrT_ &&, MapT_ &&) -> GenericIndexer; + +} // namespace singularity + +#endif // #ifndef SINGULARITY_EOS_BASE_GENERIC_INDEXER_HPP_ From bb74966e0db779a87da0e4a0624f7b9c2fe9f881 Mon Sep 17 00:00:00 2001 From: Jeffrey H Peterson Date: Wed, 29 Oct 2025 14:41:37 -0600 Subject: [PATCH 2/4] Add test for GenericIndexer --- test/CMakeLists.txt | 1 + test/test_generic_indxer.cpp | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 test/test_generic_indxer.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 903983d8051..dce185feed2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable( test_variadic_utils.cpp test_bounds.cpp test_indexable_types.cpp + test_generic_indxer.cpp ) add_executable( diff --git a/test/test_generic_indxer.cpp b/test/test_generic_indxer.cpp new file mode 100644 index 00000000000..5f41e271e58 --- /dev/null +++ b/test/test_generic_indxer.cpp @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------ +// © 2021-2025. Triad National Security, LLC. All rights reserved. This +// program was produced under U.S. Government contract 89233218CNA000001 +// for Los Alamos National Laboratory (LANL), which is operated by Triad +// National Security, LLC for the U.S. Department of Energy/National +// Nuclear Security Administration. All rights in the program are +// reserved by Triad National Security, LLC, and the U.S. Department of +// Energy/National Nuclear Security Administration. The Government is +// granted for itself and others acting on its behalf a nonexclusive, +// paid-up, irrevocable worldwide license in this material to reproduce, +// prepare derivative works, distribute copies to the public, perform +// publicly and display publicly, and to permit others to do so. +//------------------------------------------------------------------------------ + +#include + +#include +#include + +#ifndef CATCH_CONFIG_FAST_COMPILE +#define CATCH_CONFIG_FAST_COMPILE +#include +#endif +#include + +SCENARIO("Generic Indexer", "[GenericIndexer]") { + GIVEN("An array of arays populated with data") { + constexpr std::size_t n = 5; + constexpr std::size_t m = 7; + auto data = std::array, n>{}; + for (std::size_t i = 0; i < n; i++) { + for (std::size_t j = 0; j < m; j++) { + data[i][j] = (i + 1) * (j + 1); + } + } + WHEN("A flattened array is created with the same size and populated with " + "the same data") { + auto flat_data = std::array{}; + for (std::size_t i = 0; i < n; i++) { + for (std::size_t j = 0; j < m; j++) { + flat_data[i * m + j] = data[i][j]; + } + } + WHEN("We use the generic indexer to index into material data") { + struct constant_offset { + std::size_t offset; + constexpr constant_offset(std::size_t offset_) : offset{offset_} {} + constexpr std::size_t operator[](std::size_t i) { + return i * offset; + } + }; + auto mat_indexer = singularity::GenericIndexer(flat_data.data(), constant_offset{m}); + THEN("The data returned should be same as if we accessed the array of " + "arrays") { + for (std::size_t i = 0; i < n; i++) { + auto* mat_array = &mat_indexer[i]; + for (std::size_t j = 0; j < m; j++) { + INFO("i: " << i << " j: " << j); + CHECK_THAT(data[i][j], Catch::Matchers::WithinRel(mat_array[j], 1.0e-12)); + } + } + } + } + } + } +} + From 3ab9958721219a955abf0407caa068b2de26b6ef Mon Sep 17 00:00:00 2001 From: Jeffrey H Peterson Date: Wed, 29 Oct 2025 14:41:59 -0600 Subject: [PATCH 3/4] Clang format --- test/test_generic_indxer.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/test_generic_indxer.cpp b/test/test_generic_indxer.cpp index 5f41e271e58..a5fd7882b3e 100644 --- a/test/test_generic_indxer.cpp +++ b/test/test_generic_indxer.cpp @@ -45,15 +45,14 @@ SCENARIO("Generic Indexer", "[GenericIndexer]") { struct constant_offset { std::size_t offset; constexpr constant_offset(std::size_t offset_) : offset{offset_} {} - constexpr std::size_t operator[](std::size_t i) { - return i * offset; - } + constexpr std::size_t operator[](std::size_t i) { return i * offset; } }; - auto mat_indexer = singularity::GenericIndexer(flat_data.data(), constant_offset{m}); + auto mat_indexer = + singularity::GenericIndexer(flat_data.data(), constant_offset{m}); THEN("The data returned should be same as if we accessed the array of " "arrays") { for (std::size_t i = 0; i < n; i++) { - auto* mat_array = &mat_indexer[i]; + auto *mat_array = &mat_indexer[i]; for (std::size_t j = 0; j < m; j++) { INFO("i: " << i << " j: " << j); CHECK_THAT(data[i][j], Catch::Matchers::WithinRel(mat_array[j], 1.0e-12)); @@ -64,4 +63,3 @@ SCENARIO("Generic Indexer", "[GenericIndexer]") { } } } - From 8432c210ed31ac8ad40a19ccf2a617544b05a2ff Mon Sep 17 00:00:00 2001 From: Jeffrey H Peterson Date: Wed, 29 Oct 2025 14:45:10 -0600 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de733d480c1..c5fcddd408f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added (new features/APIs/variables/...) - [[PR556]](https://github.com/lanl/singularity-eos/pull/556) Add introspection into types available in the variant - [[PR564]](https://github.com/lanl/singularity-eos/pull/564) Removed Get() function from IndexableTypes since it could have unexpected consequences when a type wasn't present +- [[PR583]](https://github.com/lanl/singularity-eos/pull/583) Added GenericIndexer class to provide more complex array indirection ### Fixed (Repair bugs, etc) - [[PR567]](https://github.com/lanl/singularity-eos/pull/567) Fixed an OOB array access bug in the Fixed T PTE solver