From 15145a61b5a5bccc6e480b3a5a98e4c3fef4a00c Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Mon, 23 Sep 2024 12:08:01 -0700 Subject: [PATCH] Named SoA Support Add support to optionally name SoA Real and Int components, both for compile-time and runtime components. --- Src/Particle/AMReX_ParticleContainer.H | 35 +++++++++++- Src/Particle/AMReX_ParticleContainerI.H | 51 ++++++++++++++++- Src/Particle/AMReX_ParticleTile.H | 12 +++- Src/Particle/AMReX_StructOfArrays.H | 74 ++++++++++++++++++++++++- 4 files changed, 163 insertions(+), 9 deletions(-) diff --git a/Src/Particle/AMReX_ParticleContainer.H b/Src/Particle/AMReX_ParticleContainer.H index 03a2254a10e..1cdcf73b73f 100644 --- a/Src/Particle/AMReX_ParticleContainer.H +++ b/Src/Particle/AMReX_ParticleContainer.H @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -1144,7 +1145,8 @@ public: */ ParticleTileType& DefineAndReturnParticleTile (int lev, int grid, int tile) { - m_particles[lev][std::make_pair(grid, tile)].define(NumRuntimeRealComps(), NumRuntimeIntComps()); + m_particles[lev][std::make_pair(grid, tile)].define(NumRuntimeRealComps(), NumRuntimeIntComps(), &m_soa_rdata_names, &m_soa_idata_names); + return ParticlesAt(lev, grid, tile); } @@ -1249,8 +1251,10 @@ public: template ,int> = 0> - void AddRealComp (T communicate=true) + void AddRealComp (std::string name, T communicate=true) { + m_soa_rdata_names.push_back(name); + m_runtime_comps_defined = true; m_num_runtime_real++; h_redistribute_real_comp.push_back(communicate); @@ -1272,8 +1276,18 @@ public: template ,int> = 0> - void AddIntComp (T communicate=true) + void AddRealComp (T communicate=true) + { + std::string default_name = "make-up-name"; //! @FIXME add naming scheme + AddRealComp(default_name, communicate); + } + + template ,int> = 0> + void AddIntComp (std::string name, T communicate=true) { + m_soa_idata_names.push_back(name); + m_runtime_comps_defined = true; m_num_runtime_int++; h_redistribute_int_comp.push_back(communicate); @@ -1293,6 +1307,14 @@ public: } } + template ,int> = 0> + void AddIntComp (T communicate=true) + { + std::string default_name = "make-up-name"; //! @FIXME add naming scheme + AddIntComp(default_name, communicate); + } + int NumRuntimeRealComps () const { return m_num_runtime_real; } int NumRuntimeIntComps () const { return m_num_runtime_int; } @@ -1428,6 +1450,9 @@ private: void Initialize (); + /** Overwrite the default names for the compile-time SoA components */ + void SetSoACompileTimeNames (std::vector const & rdata_name, std::vector const & idata_name); + bool m_runtime_comps_defined{false}; int m_num_runtime_real{0}; int m_num_runtime_int{0}; @@ -1435,6 +1460,10 @@ private: size_t particle_size, superparticle_size; int num_real_comm_comps, num_int_comm_comps; Vector m_particles; + + // names of both compile-time and runtime Real and Int SoA data + std::vector m_soa_rdata_names; + std::vector m_soa_idata_names; }; template class Allocator, class CellAssignor> diff --git a/Src/Particle/AMReX_ParticleContainerI.H b/Src/Particle/AMReX_ParticleContainerI.H index 74e65b792f0..550a59bed39 100644 --- a/Src/Particle/AMReX_ParticleContainerI.H +++ b/Src/Particle/AMReX_ParticleContainerI.H @@ -1,6 +1,10 @@ -#include #include +#include +#include +#include + + template class Allocator, class CellAssignor> void @@ -60,10 +64,51 @@ ParticleContainer_impl class Allocator, class CellAssignor> +void +ParticleContainer_impl :: SetSoACompileTimeNames ( + std::vector const & rdata_name, std::vector const & idata_name +) +{ + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(rdata_name.size() == NArrayReal, "rdata_name must be equal to NArrayReal"); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(idata_name.size() == NArrayInt, "idata_name must be equal to NArrayInt"); + + for (int i=0; i class Allocator, class CellAssignor> template @@ -1161,7 +1206,7 @@ ParticleContainer_impl #include +#include #include +#include + namespace amrex { @@ -730,10 +733,15 @@ struct ParticleTile ParticleTile& operator= (ParticleTile &&) noexcept = default; #endif - void define (int a_num_runtime_real, int a_num_runtime_int) + void define ( + int a_num_runtime_real, + int a_num_runtime_int, + std::vector* soa_rdata_names=nullptr, + std::vector* soa_idata_names=nullptr + ) { m_defined = true; - GetStructOfArrays().define(a_num_runtime_real, a_num_runtime_int); + GetStructOfArrays().define(a_num_runtime_real, a_num_runtime_int, soa_rdata_names, soa_idata_names); m_runtime_r_ptrs.resize(a_num_runtime_real); m_runtime_i_ptrs.resize(a_num_runtime_int); m_runtime_r_cptrs.resize(a_num_runtime_real); diff --git a/Src/Particle/AMReX_StructOfArrays.H b/Src/Particle/AMReX_StructOfArrays.H index 4de35e085ca..201cf340dc1 100644 --- a/Src/Particle/AMReX_StructOfArrays.H +++ b/Src/Particle/AMReX_StructOfArrays.H @@ -6,7 +6,11 @@ #include #include +#include #include +#include +#include + namespace amrex { @@ -19,11 +23,18 @@ struct StructOfArrays { using RealVector = amrex::PODVector >; using IntVector = amrex::PODVector >; - void define (int a_num_runtime_real, int a_num_runtime_int) + void define ( + int a_num_runtime_real, + int a_num_runtime_int, + std::vector* soa_rdata_names=nullptr, + std::vector* soa_idata_names=nullptr + ) { m_defined = true; m_runtime_rdata.resize(a_num_runtime_real); m_runtime_idata.resize(a_num_runtime_int ); + m_rdata_names = soa_rdata_names; + m_idata_names = soa_idata_names; } [[nodiscard]] int NumRealComps () const noexcept { return NReal + m_runtime_rdata.size(); } @@ -79,6 +90,32 @@ struct StructOfArrays { } } + /** Get access to a particle Real component Array (compile-time and runtime component) + * + * @param name named component component with 0...NReal-1 compile-time and NReal... runtime arguments + */ + [[nodiscard]] RealVector& GetRealData (std::string const & name) { + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_rdata_names != nullptr, "SoA Real names were not defined."); + auto const pos = std::find(m_rdata_names->begin(), m_rdata_names->end(), name); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pos != m_rdata_names->end(), "Soa Real name='" + name + "' was not found components"); + + int const index = std::distance(m_rdata_names->begin(), pos); + return GetRealData(index); + } + + /** Get access to a particle Real component Array (compile-time and runtime component) + * + * @param name named component component with 0...NReal-1 compile-time and NReal... runtime arguments + */ + [[nodiscard]] const RealVector& GetRealData (std::string const & name) const { + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_rdata_names != nullptr, "SoA Real names were not defined."); + auto const pos = std::find(m_rdata_names->begin(), m_rdata_names->end(), name); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pos != m_rdata_names->end(), "Soa Real name='" + name + "' was not found components"); + + int const index = std::distance(m_rdata_names->begin(), pos); + return GetRealData(index); + } + /** Get access to a particle Int component Array (compile-time and runtime component) * * @param index component with 0...NInt-1 compile-time and NInt... runtime arguments @@ -118,6 +155,34 @@ struct StructOfArrays { } } + /** Get access to a particle Int component Array (compile-time and runtime component) + * + * @param index component with 0...NInt-1 compile-time and NInt... runtime arguments + * @return + */ + [[nodiscard]] IntVector& GetIntData (std::string const & name) { + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_idata_names != nullptr, "SoA Int names were not defined."); + auto const pos = std::find(m_idata_names->begin(), m_idata_names->end(), name); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pos != m_idata_names->end(), "Soa Int name='" + name + "' was not found components"); + + int const index = std::distance(m_idata_names->begin(), pos); + return GetIntData(index); + } + + /** Get access to a particle Int component Array (compile-time and runtime component) + * + * @param index component with 0...NInt-1 compile-time and NInt... runtime arguments + * @return + */ + [[nodiscard]] const IntVector& GetIntData (std::string const & name) const { + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_idata_names != nullptr, "SoA Int names were not defined."); + auto const pos = std::find(m_idata_names->begin(), m_idata_names->end(), name); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pos != m_idata_names->end(), "Soa Int name='" + name + "' was not found components"); + + int const index = std::distance(m_idata_names->begin(), pos); + return GetIntData(index); + } + /** * \brief Returns the total number of particles (real and neighbor) * @@ -226,13 +291,20 @@ struct StructOfArrays { int m_num_neighbor_particles{0}; private: + // compile-time data IdCPU m_idcpu; std::array m_rdata; std::array< IntVector, NInt> m_idata; + // runtime data std::vector m_runtime_rdata; std::vector m_runtime_idata; + // names of both compile-time and runtime Real and Int data + std::vector* m_rdata_names = nullptr; + std::vector* m_idata_names = nullptr; + + //! whether the runtime components are sized correctly bool m_defined{false}; };