Skip to content

Commit 2bcb898

Browse files
committed
Particles: Templated Real Type
If we want to develop applications that can use double and single precision switches at runtime, then we need to be able to generate both in the same binary. This adds the corresponding templates (that default to the current status quo) in particle containers.
1 parent 61f7201 commit 2bcb898

7 files changed

Lines changed: 88 additions & 72 deletions

Src/Particle/AMReX_NeighborParticles.H

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ template <int T_NArrayReal, int T_NArrayInt,
545545
template<class> class Allocator=DefaultAllocator,
546546
class CellAssignor=DefaultAssignor>
547547
using NeighborParticleContainerPureSoA =
548-
NeighborParticleContainer_impl<SoAParticle<T_NArrayReal, T_NArrayInt>,
548+
NeighborParticleContainer_impl<SoAParticle<T_NArrayReal, T_NArrayInt, ParticleReal>,
549549
T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
550550

551551
}

Src/Particle/AMReX_ParIter.H

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ParticleContainer_impl;
1515
template <int T_NReal, int T_NInt>
1616
struct Particle;
1717

18-
template <int NArrayReal, int NArrayInt>
18+
template <int NArrayReal, int NArrayInt, class T_RealType>
1919
struct SoAParticle;
2020

2121
template <class RType, class IType>
@@ -220,14 +220,21 @@ using ParIterBase = ParIterBase_impl<is_const, Particle<T_NStructReal, T_NStruct
220220

221221
template <bool is_const, int T_NArrayReal=0, int T_NArrayInt=0,
222222
template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
223-
using ParIterBaseSoA = ParIterBase_impl<is_const,SoAParticle<T_NArrayReal, T_NArrayInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
223+
using ParIterBaseSoA = ParIterBase_impl<is_const,SoAParticle<T_NArrayReal, T_NArrayInt, ParticleReal>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
224+
225+
template <bool is_const, class RType, int T_NArrayReal=0, int T_NArrayInt=0,
226+
template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
227+
using ParIterBaseSoAT = ParIterBase_impl<is_const,SoAParticle<T_NArrayReal, T_NArrayInt, RType>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
224228

225229
template <int T_NStructReal, int T_NStructInt=0, int T_NArrayReal=0, int T_NArrayInt=0,
226230
template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
227231
using ParConstIter = ParConstIter_impl<Particle<T_NStructReal, T_NStructInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
228232

229233
template <int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
230-
using ParConstIterSoA = ParConstIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
234+
using ParConstIterSoA = ParConstIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt, ParticleReal>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
235+
236+
template <class RType, int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
237+
using ParConstIterSoAT = ParConstIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt, RType>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
231238

232239
/// \ingroup amrex_particles
233240
template <class RType=ParticleReal, class IType=int, class CellAssignor=DefaultAssignor>
@@ -238,7 +245,10 @@ template <int T_NStructReal, int T_NStructInt=0, int T_NArrayReal=0, int T_NArra
238245
using ParIter = ParIter_impl<Particle<T_NStructReal, T_NStructInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
239246

240247
template <int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
241-
using ParIterSoA = ParIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
248+
using ParIterSoA = ParIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt, ParticleReal>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
249+
250+
template <class RType, int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
251+
using ParIterSoAT = ParIter_impl<SoAParticle<T_NArrayReal, T_NArrayInt, RType>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
242252

243253
template <class RType=ParticleReal, class IType=int, class CellAssignor=DefaultAssignor>
244254
using ParIterRTSoA = ParIter_impl<RTSoAParticle<RType, IType>, 0, 0, PolymorphicArenaAllocator, CellAssignor>;

Src/Particle/AMReX_ParticleContainer.H

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,11 @@ template <int T_NStructReal, int T_NStructInt, int T_NArrayReal, int T_NArrayInt
15801580
using ParticleContainer = ParticleContainer_impl<Particle<T_NStructReal, T_NStructInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
15811581

15821582
template <int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
1583-
using ParticleContainerPureSoA = ParticleContainer_impl<SoAParticle<T_NArrayReal, T_NArrayInt>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
1583+
using ParticleContainerPureSoA = ParticleContainer_impl<SoAParticle<T_NArrayReal, T_NArrayInt, ParticleReal>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
1584+
1585+
/// Like ParticleContainerPureSoA, but with the SoA real storage type RType (e.g. float/double) configurable.
1586+
template <class RType, int T_NArrayReal, int T_NArrayInt, template<class> class Allocator=DefaultAllocator, class CellAssignor=DefaultAssignor>
1587+
using ParticleContainerPureSoAT = ParticleContainer_impl<SoAParticle<T_NArrayReal, T_NArrayInt, RType>, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor>;
15841588

15851589
template <class RType=ParticleReal, class IType=int, class CellAssignor=DefaultAssignor>
15861590
using ParticleContainerRTSoA = ParticleContainer_impl<RTSoAParticle<RType, IType>, 0, 0, PolymorphicArenaAllocator, CellAssignor>;

Src/Particle/AMReX_ParticleReduce.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ namespace amrex {
2020
/// \cond DOXYGEN_IGNORE
2121
namespace particle_detail {
2222

23-
template <typename F, typename T_ParticleType, int NAR, int NAI>
23+
template <typename F, typename T_ParticleType, int NAR, int NAI, class RType>
2424
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
2525
auto call_f (F const& f,
26-
const ConstParticleTileData<T_ParticleType, NAR, NAI>& p,
26+
const ConstParticleTileData<T_ParticleType, NAR, NAI, RType>& p,
2727
const int i) noexcept
2828
{
2929
if constexpr ( ! T_ParticleType::is_soa_particle &&

Src/Particle/AMReX_ParticleTile.H

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@
2020
namespace amrex {
2121

2222
// Forward Declaration
23-
template <int NArrayReal, int NArrayInt>
23+
template <int NArrayReal, int NArrayInt, class T_RealType=ParticleReal>
2424
struct ConstSoAParticle;
25-
template <int NArrayReal, int NArrayInt>
25+
template <int NArrayReal, int NArrayInt, class T_RealType>
2626
struct SoAParticle;
2727

28-
template <typename T_ParticleType, int NArrayReal, int NArrayInt>
28+
template <typename T_ParticleType, int NArrayReal, int NArrayInt, class T_RealType=ParticleReal>
2929
struct ConstParticleTileData;
3030

3131
/// \ingroup amrex_particles
32-
template <typename T_ParticleType, int NArrayReal, int NArrayInt>
32+
template <typename T_ParticleType, int NArrayReal, int NArrayInt, class T_RealType=ParticleReal>
3333
struct ParticleTileData
3434
{
3535
static constexpr int NAR = NArrayReal;
3636
static constexpr int NAI = NArrayInt;
3737

3838
using ParticleType = T_ParticleType;
3939
using ParticleRefType = T_ParticleType&;
40-
using Self = ParticleTileData<ParticleType, NAR, NAI>;
41-
using RealType = ParticleReal;
40+
using RealType = T_RealType;
41+
using Self = ParticleTileData<ParticleType, NAR, NAI, RealType>;
4242
using IntType = int;
4343

4444
static constexpr int NStructReal = ParticleType::NReal;
@@ -55,12 +55,12 @@ struct ParticleTileData
5555
AOS_PTR m_aos;
5656

5757
uint64_t* m_idcpu;
58-
GpuArray<ParticleReal*, NAR> m_rdata;
58+
GpuArray<RealType*, NAR> m_rdata;
5959
GpuArray<int*, NAI> m_idata;
6060

6161
int m_num_runtime_real;
6262
int m_num_runtime_int;
63-
ParticleReal* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_rdata;
63+
RealType* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_rdata;
6464
int* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_idata;
6565

6666
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
@@ -104,7 +104,7 @@ struct ParticleTileData
104104
}
105105

106106
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
107-
ParticleReal * rdata (const int attribute_index) const
107+
RealType * rdata (const int attribute_index) const
108108
{
109109
return this->m_rdata[attribute_index];
110110
}
@@ -121,7 +121,7 @@ struct ParticleTileData
121121
if constexpr (!ParticleType::is_soa_particle) {
122122
return m_aos[index];
123123
} else {
124-
return SoAParticle<NAR, NAI>(*this, index);
124+
return SoAParticle<NAR, NAI, RealType>(*this, index);
125125
}
126126
}
127127

@@ -146,17 +146,17 @@ struct ParticleTileData
146146
{
147147
if (comm_real[array_start_index + i])
148148
{
149-
memcpy(dst, m_rdata[i] + src_index, sizeof(ParticleReal));
150-
dst += sizeof(ParticleReal);
149+
memcpy(dst, m_rdata[i] + src_index, sizeof(RealType));
150+
dst += sizeof(RealType);
151151
}
152152
}
153153
int runtime_start_index = array_start_index + NAR;
154154
for (int i = 0; i < m_num_runtime_real; ++i)
155155
{
156156
if (comm_real[runtime_start_index + i])
157157
{
158-
memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(ParticleReal));
159-
dst += sizeof(ParticleReal);
158+
memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(RealType));
159+
dst += sizeof(RealType);
160160
}
161161
}
162162
array_start_index = 2 + NStructInt;
@@ -201,8 +201,8 @@ struct ParticleTileData
201201
{
202202
if (comm_real[array_start_index + i])
203203
{
204-
memcpy(m_rdata[i] + dst_index, src, sizeof(ParticleReal));
205-
src += sizeof(ParticleReal);
204+
memcpy(m_rdata[i] + dst_index, src, sizeof(RealType));
205+
src += sizeof(RealType);
206206
}
207207
}
208208
}
@@ -211,8 +211,8 @@ struct ParticleTileData
211211
{
212212
if (comm_real[runtime_start_index + i])
213213
{
214-
memcpy(m_runtime_rdata[i] + dst_index, src, sizeof(ParticleReal));
215-
src += sizeof(ParticleReal);
214+
memcpy(m_runtime_rdata[i] + dst_index, src, sizeof(RealType));
215+
src += sizeof(RealType);
216216
}
217217
}
218218
array_start_index = 2 + NStructInt;
@@ -322,18 +322,18 @@ struct ParticleTileData
322322
};
323323

324324
// SOA Particle Structure
325-
template <int T_NArrayReal, int T_NArrayInt>
325+
template <int T_NArrayReal, int T_NArrayInt, class T_RealType>
326326
struct alignas(sizeof(double)) ConstSoAParticle : SoAParticleBase
327327
{
328328
static constexpr int NArrayReal = T_NArrayReal;
329329
static constexpr int NArrayInt = T_NArrayInt;
330330
using StorageParticleType = SoAParticleBase;
331-
using ConstPTD = ConstParticleTileData<SoAParticleBase, NArrayReal, NArrayInt>;
331+
using ConstPTD = ConstParticleTileData<SoAParticleBase, NArrayReal, NArrayInt, T_RealType>;
332332
static constexpr bool is_soa_particle = true;
333333
static constexpr bool is_rtsoa_particle = false;
334334
static constexpr bool is_constsoa_particle = true;
335335

336-
using RealType = ParticleReal;
336+
using RealType = T_RealType;
337337
using IntType = int;
338338

339339
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
@@ -386,19 +386,19 @@ struct alignas(sizeof(double)) ConstSoAParticle : SoAParticleBase
386386
int m_index;
387387
};
388388

389-
template <int T_NArrayReal, int T_NArrayInt>
389+
template <int T_NArrayReal, int T_NArrayInt, class T_RealType>
390390
struct alignas(sizeof(double)) SoAParticle : SoAParticleBase
391391
{
392392
static constexpr int NArrayReal = T_NArrayReal;
393393
static constexpr int NArrayInt = T_NArrayInt;
394394
using StorageParticleType = SoAParticleBase;
395-
using PTD = ParticleTileData<SoAParticleBase, NArrayReal, NArrayInt>;
395+
using PTD = ParticleTileData<SoAParticleBase, NArrayReal, NArrayInt, T_RealType>;
396396
static constexpr bool is_soa_particle = true;
397397
static constexpr bool is_rtsoa_particle = false;
398398
static constexpr bool is_constsoa_particle = false;
399399

400-
using ConstType = ConstSoAParticle<T_NArrayReal, T_NArrayInt>;
401-
using RealType = ParticleReal;
400+
using ConstType = ConstSoAParticle<T_NArrayReal, T_NArrayInt, T_RealType>;
401+
using RealType = T_RealType;
402402
using IntType = int;
403403

404404
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
@@ -471,11 +471,11 @@ private :
471471
};
472472

473473
//template <int NArrayReal, int NArrayInt> Long ConstSoAParticle<NArrayReal, NArrayInt>::the_next_id = 1;
474-
template <int NArrayReal, int NArrayInt> Long SoAParticle<NArrayReal, NArrayInt>::the_next_id = 1;
474+
template <int NArrayReal, int NArrayInt, class T_RealType> Long SoAParticle<NArrayReal, NArrayInt, T_RealType>::the_next_id = 1;
475475

476-
template <int NArrayReal, int NArrayInt>
476+
template <int NArrayReal, int NArrayInt, class T_RealType>
477477
Long
478-
SoAParticle<NArrayReal, NArrayInt>::NextID ()
478+
SoAParticle<NArrayReal, NArrayInt, T_RealType>::NextID ()
479479
{
480480
Long next;
481481
// we should be able to test on _OPENMP < 201107 for capture (version 3.1)
@@ -494,9 +494,9 @@ SoAParticle<NArrayReal, NArrayInt>::NextID ()
494494
return next;
495495
}
496496

497-
template <int NArrayReal, int NArrayInt>
497+
template <int NArrayReal, int NArrayInt, class T_RealType>
498498
Long
499-
SoAParticle<NArrayReal, NArrayInt>::UnprotectedNextID ()
499+
SoAParticle<NArrayReal, NArrayInt, T_RealType>::UnprotectedNextID ()
500500
{
501501
Long next = the_next_id++;
502502
if (next > LongParticleIds::LastParticleID) {
@@ -505,21 +505,21 @@ SoAParticle<NArrayReal, NArrayInt>::UnprotectedNextID ()
505505
return next;
506506
}
507507

508-
template <int NArrayReal, int NArrayInt>
508+
template <int NArrayReal, int NArrayInt, class T_RealType>
509509
void
510-
SoAParticle<NArrayReal, NArrayInt>::NextID (Long nextid)
510+
SoAParticle<NArrayReal, NArrayInt, T_RealType>::NextID (Long nextid)
511511
{
512512
the_next_id = nextid;
513513
}
514514

515-
template <typename T_ParticleType, int NArrayReal, int NArrayInt>
515+
template <typename T_ParticleType, int NArrayReal, int NArrayInt, class T_RealType>
516516
struct ConstParticleTileData
517517
{
518518
static constexpr int NAR = NArrayReal;
519519
static constexpr int NAI = NArrayInt;
520520
using ParticleType = T_ParticleType;
521521
using ParticleRefType = T_ParticleType const&;
522-
using RealType = ParticleReal;
522+
using RealType = T_RealType;
523523
using IntType = int;
524524

525525
static constexpr int NStructReal = ParticleType::NReal;
@@ -536,7 +536,7 @@ struct ConstParticleTileData
536536
AOS_PTR m_aos;
537537

538538
const uint64_t* m_idcpu;
539-
GpuArray<const ParticleReal*, NArrayReal> m_rdata;
539+
GpuArray<const RealType*, NArrayReal> m_rdata;
540540
GpuArray<const int*, NArrayInt > m_idata;
541541

542542
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
@@ -580,7 +580,7 @@ struct ConstParticleTileData
580580
}
581581

582582
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
583-
const ParticleReal * rdata (const int attribute_index) const
583+
const RealType * rdata (const int attribute_index) const
584584
{
585585
return this->m_rdata[attribute_index];
586586
}
@@ -597,13 +597,13 @@ struct ConstParticleTileData
597597
if constexpr (!ParticleType::is_soa_particle) {
598598
return m_aos[index];
599599
} else {
600-
return ConstSoAParticle<NAR, NAI>(*this, index);
600+
return ConstSoAParticle<NAR, NAI, RealType>(*this, index);
601601
}
602602
}
603603

604604
int m_num_runtime_real;
605605
int m_num_runtime_int;
606-
const ParticleReal* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_rdata;
606+
const RealType* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_rdata;
607607
const int* AMREX_RESTRICT * AMREX_RESTRICT m_runtime_idata;
608608

609609
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
@@ -628,8 +628,8 @@ struct ConstParticleTileData
628628
{
629629
if (comm_real[array_start_index + i])
630630
{
631-
memcpy(dst, m_rdata[i] + src_index, sizeof(ParticleReal));
632-
dst += sizeof(ParticleReal);
631+
memcpy(dst, m_rdata[i] + src_index, sizeof(RealType));
632+
dst += sizeof(RealType);
633633
}
634634
}
635635
}
@@ -638,8 +638,8 @@ struct ConstParticleTileData
638638
{
639639
if (comm_real[runtime_start_index + i])
640640
{
641-
memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(ParticleReal));
642-
dst += sizeof(ParticleReal);
641+
memcpy(dst, m_runtime_rdata[i] + src_index, sizeof(RealType));
642+
dst += sizeof(RealType);
643643
}
644644
}
645645
array_start_index = 2 + NStructInt;
@@ -783,14 +783,14 @@ struct ParticleTile
783783

784784
using SoA = std::conditional_t<
785785
ParticleType::is_soa_particle,
786-
StructOfArrays<NArrayReal, NArrayInt, Allocator, true>,
787-
StructOfArrays<NArrayReal, NArrayInt, Allocator, false>>;
786+
StructOfArrays<NArrayReal, NArrayInt, Allocator, true, RealType>,
787+
StructOfArrays<NArrayReal, NArrayInt, Allocator, false, RealType>>;
788788
using RealVector = typename SoA::RealVector;
789789
using IntVector = typename SoA::IntVector;
790790
using StorageParticleType = typename ParticleType::StorageParticleType;
791791

792-
using ParticleTileDataType = ParticleTileData<StorageParticleType, NArrayReal, NArrayInt>;
793-
using ConstParticleTileDataType = ConstParticleTileData<StorageParticleType, NArrayReal, NArrayInt>;
792+
using ParticleTileDataType = ParticleTileData<StorageParticleType, NArrayReal, NArrayInt, RealType>;
793+
using ConstParticleTileDataType = ConstParticleTileData<StorageParticleType, NArrayReal, NArrayInt, RealType>;
794794

795795
static constexpr bool has_polymorphic_allocator =
796796
IsPolymorphicArenaAllocator<Allocator<RealType>>::value;
@@ -1227,7 +1227,7 @@ struct ParticleTile
12271227
for (int j = 0; j < NumRealComps(); ++j)
12281228
{
12291229
auto& rdata = GetStructOfArrays().GetRealData(j);
1230-
nbytes += rdata.capacity() * sizeof(ParticleReal);
1230+
nbytes += rdata.capacity() * sizeof(RealType);
12311231
}
12321232

12331233
for (int j = 0; j < NumIntComps(); ++j)
@@ -1581,16 +1581,16 @@ private:
15811581

15821582
bool m_defined = false;
15831583

1584-
amrex::PODVector<ParticleReal*, Allocator<ParticleReal*> > m_runtime_r_ptrs;
1584+
amrex::PODVector<RealType*, Allocator<RealType*> > m_runtime_r_ptrs;
15851585
amrex::PODVector<int*, Allocator<int*> > m_runtime_i_ptrs;
15861586

1587-
mutable amrex::PODVector<const ParticleReal*, Allocator<const ParticleReal*> > m_runtime_r_cptrs;
1587+
mutable amrex::PODVector<const RealType*, Allocator<const RealType*> > m_runtime_r_cptrs;
15881588
mutable amrex::PODVector<const int*, Allocator<const int*> >m_runtime_i_cptrs;
15891589

1590-
amrex::Gpu::HostVector<ParticleReal*> m_h_runtime_r_ptrs;
1590+
amrex::Gpu::HostVector<RealType*> m_h_runtime_r_ptrs;
15911591
amrex::Gpu::HostVector<int*> m_h_runtime_i_ptrs;
15921592

1593-
mutable amrex::Gpu::HostVector<const ParticleReal*> m_h_runtime_r_cptrs;
1593+
mutable amrex::Gpu::HostVector<const RealType*> m_h_runtime_r_cptrs;
15941594
mutable amrex::Gpu::HostVector<const int*> m_h_runtime_i_cptrs;
15951595

15961596
RuntimePtrCacheDirtyFlag m_runtime_ptrs_dirty;

0 commit comments

Comments
 (0)