diff options
Diffstat (limited to 'Source/Particles')
-rw-r--r-- | Source/Particles/MultiParticleContainer.cpp | 3 | ||||
-rw-r--r-- | Source/Particles/ParticleCreation/DefaultInitialization.H | 94 | ||||
-rw-r--r-- | Source/Particles/ParticleCreation/SmartCopy.H | 67 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 6 |
4 files changed, 95 insertions, 75 deletions
diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index ccb21fe63..fe8354da0 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -652,6 +652,9 @@ MultiParticleContainer::doFieldIonization () // Get product species auto& pc_product = allcontainers[pc_source->ionization_product]; + SmartCopyFactory copy_factory(*pc_source, *pc_product); + auto Copier = copy_factory.getSmartCopy(); + pc_source ->defineAllParticleTiles(); pc_product->defineAllParticleTiles(); diff --git a/Source/Particles/ParticleCreation/DefaultInitialization.H b/Source/Particles/ParticleCreation/DefaultInitialization.H index e2491a483..87ebdc5cb 100644 --- a/Source/Particles/ParticleCreation/DefaultInitialization.H +++ b/Source/Particles/ParticleCreation/DefaultInitialization.H @@ -28,35 +28,6 @@ enum struct InitializationPolicy {Zero=0, One, SignalingNan, RandomTau}; /** - * \brief This is a functor that implements the above InitializationPolicies - * in a switch statement. It is designed to be used in device code when - * running on GPUs. - */ -struct DefaultInitializer -{ - const InitializationPolicy* m_policies; - - AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - amrex::Real operator() (int j) const noexcept - { - switch (m_policies[j]) { - case InitializationPolicy::Zero : return 0.0; - case InitializationPolicy::One : return 1.0; - case InitializationPolicy::SignalingNan : { - return 1.0; - } - case InitializationPolicy::RandomTau : { - return 1.0; - } - default : { - amrex::Abort("Initialization Policy not recognized"); - return 1.0; - } - } - } -}; - -/** * \brief This map sets the initialization policy for each particle component * used in WarpX. */ @@ -74,41 +45,42 @@ static std::map<std::string, InitializationPolicy> initialization_policies = { #ifdef WARPX_DIM_RZ {"theta", InitializationPolicy::Zero}, #endif - {"tau", InitializationPolicy::RandomTau} + {"tau", InitializationPolicy::RandomTau} }; -/** - * \brief This is a factory class that creates instances of "DefaultInitializer". - * Each particle type in WarpX has one of these associated with it. While - * "DefaultInitializer" is a lightweight class intended to be used on the device, - * this class is meant to be used on the host. - */ -class DefaultInitializerFactory +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +amrex::ParticleReal initializeRealValue (const InitializationPolicy policy) noexcept { - amrex::Gpu::DeviceVector<InitializationPolicy> m_policies; - bool m_defined; - -public: - - DefaultInitializerFactory () noexcept : m_defined(false) {}; - - void define (const std::map<std::string, int>& comps) noexcept - { - m_policies.resize(comps.size()); - for (const auto& kv : comps) - { - m_policies[kv.second] = initialization_policies[kv.first]; - m_defined = true; - } - } + switch (policy) { + case InitializationPolicy::Zero : return 0.0; + case InitializationPolicy::One : return 1.0; + case InitializationPolicy::SignalingNan : { + return 1.0; + } + case InitializationPolicy::RandomTau : { + return 1.0; + } + default : { + amrex::Abort("Initialization Policy not recognized"); + return 1.0; + } + } +} - DefaultInitializer getDefaultInitializer () const noexcept - { - AMREX_ASSERT(m_defined); - return DefaultInitializer{m_policies.dataPtr()}; - } - - bool isDefined () const noexcept { return m_defined; } -}; +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +int initializeIntValue (const InitializationPolicy policy) noexcept +{ + switch (policy) { + case InitializationPolicy::Zero : return 0; + case InitializationPolicy::One : return 1; + case InitializationPolicy::SignalingNan : { + return 1; + } + default : { + amrex::Abort("Initialization Policy not recognized"); + return 1; + } + } +} #endif diff --git a/Source/Particles/ParticleCreation/SmartCopy.H b/Source/Particles/ParticleCreation/SmartCopy.H index 2247d8109..827f23678 100644 --- a/Source/Particles/ParticleCreation/SmartCopy.H +++ b/Source/Particles/ParticleCreation/SmartCopy.H @@ -1,6 +1,8 @@ #ifndef SMART_COPY_H_ #define SMART_COPY_H_ +#include <DefaultInitialization.H> + #include <AMReX_GpuContainers.H> #include <map> @@ -17,25 +19,49 @@ struct SmartCopyTag int size () const noexcept { return common_names.size(); } }; +struct DefaultInitializationTag +{ + amrex::Gpu::DeviceVector<InitializationPolicy> m_policy_real; + amrex::Gpu::DeviceVector<InitializationPolicy> m_policy_int; + +}; + SmartCopyTag getSmartCopyTag (const NameMap& src, const NameMap& dst); struct SmartCopy { - int m_num_real; + int m_num_copy_real; const int* m_src_comps_r; const int* m_dst_comps_r; - int m_num_int; + int m_num_copy_int; const int* m_src_comps_i; const int* m_dst_comps_i; - template <typename DstData, typename SrcData> + const InitializationPolicy* m_policy_real; + const InitializationPolicy* m_policy_int; + + template <typename DstData, typename SrcData> AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator() (const DstData& dst, const SrcData& src, int i_src, int i_dst) const noexcept { + // the particle struct is always copied over dst.m_aos[i_dst] = src.m_aos[i_src]; - for (int j = 0; j < m_num_real; ++j) + // initialize the real components + for (int j = 0; j < DstData::NAR; ++j) + dst.m_rdata[j] = initializeRealValue(m_policy_real[j]); + for (int j = 0; j < dst.m_num_runtime_real; ++j) + dst.m_rdata[j] = initializeRealValue(m_policy_real[j+DstData::NAR]); + + // initialize the int components + for (int j = 0; j < DstData::NAI; ++j) + dst.m_idata[j] = initializeIntValue(m_policy_int[j]); + for (int j = 0; j < dst.m_num_runtime_int; ++j) + dst.m_idata[j] = initializeIntValue(m_policy_int[j+DstData::NAI]); + + // copy the shared real components + for (int j = 0; j < m_num_copy_real; ++j) { int src_comp = (m_src_comps_r[j] < SrcData::NAR) ? m_src_comps_r[j] : m_src_comps_r[j] - SrcData::NAR; int dst_comp = (m_dst_comps_r[j] < DstData::NAR) ? m_dst_comps_r[j] : m_dst_comps_r[j] - DstData::NAR; @@ -46,7 +72,8 @@ struct SmartCopy dst_data[dst_comp] = src_data[src_comp]; } - for (int j = 0; j < m_num_int; ++j) + // copy the shared int components + for (int j = 0; j < m_num_copy_int; ++j) { int src_comp = (m_src_comps_i[j] < SrcData::NAI) ? m_src_comps_i[j] : m_src_comps_i[j] - SrcData::NAI; int dst_comp = (m_dst_comps_i[j] < DstData::NAI) ? m_dst_comps_i[j] : m_dst_comps_i[j] - DstData::NAI; @@ -63,14 +90,32 @@ class SmartCopyFactory { SmartCopyTag m_tag_real; SmartCopyTag m_tag_int; + amrex::Gpu::DeviceVector<InitializationPolicy> m_policy_real; + amrex::Gpu::DeviceVector<InitializationPolicy> m_policy_int; bool m_defined; - template <class PC1, class PC2> - SmartCopyFactory (const PC1& pc1, const PC2& pc2) noexcept +public: + template <class SrcPC, class DstPC> + SmartCopyFactory (const SrcPC& src, const DstPC& dst) noexcept : m_defined(false) { - m_tag_real = getSmartCopyTag(pc1.getParticleComps(), pc2.getParticleComps()); - m_tag_int = getSmartCopyTag(pc1.getParticleiComps(), pc2.getParticleiComps()); + m_tag_real = getSmartCopyTag(src.getParticleComps(), dst.getParticleComps()); + m_tag_int = getSmartCopyTag(src.getParticleiComps(), dst.getParticleiComps()); + + auto real_comps = dst.getParticleComps(); + m_policy_real.resize(real_comps.size()); + for (const auto& kv : real_comps) + { + m_policy_real[kv.second] = initialization_policies[kv.first]; + } + + auto int_comps = dst.getParticleiComps(); + m_policy_int.resize(int_comps.size()); + for (const auto& kv : int_comps) + { + m_policy_int[kv.second] = initialization_policies[kv.first]; + } + m_defined = true; } @@ -82,7 +127,9 @@ class SmartCopyFactory m_tag_real.dst_comps.dataPtr(), m_tag_int.size(), m_tag_int. src_comps.dataPtr(), - m_tag_int. dst_comps.dataPtr()}; + m_tag_int. dst_comps.dataPtr(), + m_policy_real.dataPtr(), + m_policy_int.dataPtr()}; } bool isDefined () const noexcept { return m_defined; } diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index c258f28c7..3bf4d4e9c 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -315,8 +315,8 @@ public: amrex::Gpu::ManagedDeviceVector<int>& ionization_mask) {}; - std::map<std::string, int> getParticleComps () { return particle_comps;} - std::map<std::string, int> getParticleiComps () { return particle_icomps;} + std::map<std::string, int> getParticleComps () const noexcept { return particle_comps;} + std::map<std::string, int> getParticleiComps () const noexcept { return particle_icomps;} //amrex::Real getCharge () {return charge;} amrex::ParticleReal getCharge () const {return charge;} @@ -397,8 +397,6 @@ protected: amrex::Vector<std::map<PairIndex, std::array<DataContainer, TmpIdx::nattribs> > > tmp_particle_data; - DefaultInitializerFactory m_default_initializer_factory; - void defineAllParticleTiles () noexcept; private: |