Skip to content
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

Pure SoA Particle: Separate Array for IdCPU #3585

Merged
91 changes: 71 additions & 20 deletions Src/Particle/AMReX_ParticleTile.H
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct ParticleTileData

ParticleType* AMREX_RESTRICT m_aos;

uint64_t* m_idcpu;
GpuArray<ParticleReal*, NAR> m_rdata;
GpuArray<int*, NAI> m_idata;

Expand All @@ -67,7 +68,7 @@ struct ParticleTileData
if constexpr(!ParticleType::is_soa_particle) {
return this->m_aos[index].id();
} else {
return this->m_idata[0][index];
return ParticleIDWrapper(this->m_idcpu[index]);
}
}

Expand All @@ -77,7 +78,17 @@ struct ParticleTileData
if constexpr(!ParticleType::is_soa_particle) {
return this->m_aos[index].cpu();
} else {
return this->m_idata[1][index];
return ParticleCPUWrapper(this->m_idcpu[index]);
}
}

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
decltype(auto) idcpu (const int index) const &
{
if constexpr(ParticleType::is_soa_particle) {
return this->m_idcpu[index];
} else {
amrex::Abort("not implemented");
}
}

Expand Down Expand Up @@ -112,6 +123,9 @@ struct ParticleTileData
if constexpr (!ParticleType::is_soa_particle) {
memcpy(dst, m_aos + src_index, sizeof(ParticleType));
dst += sizeof(ParticleType);
} else {
memcpy(dst, m_idcpu + src_index, sizeof(uint64_t));
dst += sizeof(uint64_t);
}
int array_start_index = AMREX_SPACEDIM + NStructReal;
for (int i = 0; i < NAR; ++i)
Expand Down Expand Up @@ -160,6 +174,9 @@ struct ParticleTileData
if constexpr (!ParticleType::is_soa_particle) {
memcpy(m_aos + dst_index, src, sizeof(ParticleType));
src += sizeof(ParticleType);
} else {
memcpy(m_idcpu + dst_index, src, sizeof(uint64_t));
src += sizeof(uint64_t);
}
int array_start_index = AMREX_SPACEDIM + NStructReal;
for (int i = 0; i < NAR; ++i)
Expand Down Expand Up @@ -231,9 +248,8 @@ struct ParticleTileData
{
AMREX_ASSERT(index < m_size);
SuperParticleType sp;
sp.m_idcpu = m_idcpu[index];
for (int i = 0; i < AMREX_SPACEDIM; ++i) {sp.pos(i) = m_rdata[i][index];}
sp.id() = m_idata[0][index];
sp.cpu() = m_idata[1][index];
for (int i = 0; i < NAR; ++i) {
sp.rdata(i) = m_rdata[i][index];
}
Expand Down Expand Up @@ -270,6 +286,7 @@ struct ParticleTileData
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void setSuperParticle (const SuperParticleType& sp, int index) const noexcept
{
m_idcpu[index] = sp.m_idcpu;
for (int i = 0; i < NAR; ++i) {
m_rdata[i][index] = sp.rdata(i);
}
Expand Down Expand Up @@ -303,10 +320,10 @@ struct ConstSoAParticle : SoAParticleBase
//functions to get id and cpu in the SOA data

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
int cpu () const { return this->m_constparticle_tile_data.m_idata[1][m_index]; }
ConstParticleCPUWrapper cpu () const { return this->m_constparticle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
int id () const { return this->m_constparticle_tile_data.m_idata[0][m_index]; }
ConstParticleIDWrapper id () const { return this->m_constparticle_tile_data.m_idcpu[m_index]; }

//functions to get positions of the particle in the SOA data

Expand Down Expand Up @@ -366,16 +383,22 @@ struct SoAParticle : SoAParticleBase
//functions to get id and cpu in the SOA data

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
int& cpu () & { return this->m_particle_tile_data.m_idata[1][m_index]; }
ParticleCPUWrapper cpu () & { return this->m_particle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
ParticleIDWrapper id () & { return this->m_particle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
int& id () & { return this->m_particle_tile_data.m_idata[0][m_index]; }
uint64_t& idcpu () & { return this->m_particle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
const int& cpu () const & { return this->m_particle_tile_data.m_idata[1][m_index]; }
ConstParticleCPUWrapper cpu () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
const int& id () const & { return this->m_particle_tile_data.m_idata[0][m_index]; }
ConstParticleIDWrapper id () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
const uint64_t& idcpu () const & { return this->m_particle_tile_data.m_idcpu[m_index]; }

//functions to get positions of the particle in the SOA data

Expand Down Expand Up @@ -477,6 +500,7 @@ struct ConstParticleTileData
Long m_size;
const ParticleType* AMREX_RESTRICT m_aos;

const uint64_t* m_idcpu;
GpuArray<const ParticleReal*, NArrayReal> m_rdata;
GpuArray<const int*, NArrayInt > m_idata;

Expand All @@ -496,7 +520,7 @@ struct ConstParticleTileData
if constexpr(!ParticleType::is_soa_particle) {
return this->m_aos[index].id();
} else {
return this->m_idata[0][index];
return ConstParticleIDWrapper(this->m_idcpu[index]);
}
}

Expand All @@ -506,7 +530,17 @@ struct ConstParticleTileData
if constexpr(!ParticleType::is_soa_particle) {
return this->m_aos[index].cpu();
} else {
return this->m_idata[1][index];
return ConstParticleCPUWrapper(this->m_idcpu[index]);
}
}

[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
decltype(auto) idcpu (const int index) const &
{
if constexpr(ParticleType::is_soa_particle) {
return this->m_idcpu[index];
} else {
amrex::Abort("not implemented");
}
}

Expand Down Expand Up @@ -546,6 +580,9 @@ struct ConstParticleTileData
if constexpr (!ParticleType::is_soa_particle) {
memcpy(dst, m_aos + src_index, sizeof(ParticleType));
dst += sizeof(ParticleType);
} else {
memcpy(dst, m_idcpu + src_index, sizeof(uint64_t));
dst += sizeof(uint64_t);
}
int array_start_index = AMREX_SPACEDIM + NStructReal;
for (int i = 0; i < NArrayReal; ++i)
Expand Down Expand Up @@ -622,8 +659,7 @@ struct ConstParticleTileData
AMREX_ASSERT(index < m_size);
SuperParticleType sp;
for (int i = 0; i < AMREX_SPACEDIM; ++i) {sp.pos(i) = m_rdata[i][index];}
sp.id() = m_idata[0][index];
sp.cpu() = m_idata[1][index];
sp.m_idcpu = m_idcpu[index];
for (int i = 0; i < NAR; ++i) {
sp.rdata(i) = m_rdata[i][index];
}
Expand Down Expand Up @@ -663,7 +699,10 @@ struct ParticleTile
ArrayOfStructs<ParticleType, Allocator>>::type;
//using ParticleVector = typename AoS::ParticleVector;

using SoA = StructOfArrays<NArrayReal, NArrayInt, Allocator>;
using SoA = typename std::conditional<
ParticleType::is_soa_particle,
StructOfArrays<NArrayReal, NArrayInt, Allocator, true>,
StructOfArrays<NArrayReal, NArrayInt, Allocator, true>>::type;
ax3l marked this conversation as resolved.
Show resolved Hide resolved
using RealVector = typename SoA::RealVector;
using IntVector = typename SoA::IntVector;
using StorageParticleType = typename ParticleType::StorageParticleType;
Expand All @@ -688,7 +727,7 @@ struct ParticleTile
if constexpr (!ParticleType::is_soa_particle) {
return m_aos_tile[index].id();
} else {
return m_soa_tile.GetIntData(0)[index];
return ParticleIDWrapper(m_soa_tile.GetIdCPUData()[index]);
}
}

Expand All @@ -697,7 +736,7 @@ struct ParticleTile
if constexpr (!ParticleType::is_soa_particle) {
return m_aos_tile[index].id();
} else {
return m_soa_tile.GetIntData(0)[index];
return ConstParticleIDWrapper(m_soa_tile.GetIdCPUData()[index]);
}
}

Expand All @@ -706,7 +745,7 @@ struct ParticleTile
if constexpr (!ParticleType::is_soa_particle) {
return m_aos_tile[index].cpu();
} else {
return m_soa_tile.GetIntData(1)[index];
return ParticleCPUWrapper(m_soa_tile.GetIdCPUData()[index]);
}
}

Expand All @@ -715,7 +754,7 @@ struct ParticleTile
if constexpr (!ParticleType::is_soa_particle) {
return m_aos_tile[index].cpu();
} else {
return m_soa_tile.GetIntData(1)[index];
return ConstParticleCPUWrapper(m_soa_tile.GetIdCPUData()[index]);
}
}

Expand Down Expand Up @@ -873,7 +912,9 @@ struct ParticleTile
}

m_soa_tile.resize(np+1);

if constexpr (!ParticleType::is_soa_particle) {
m_soa_tile.GetIdCPUData()[np] = sp.m_idcpu;
}
auto& arr_rdata = m_soa_tile.GetRealData();
auto& arr_idata = m_soa_tile.GetIntData();
for (int i = 0; i < NArrayReal; ++i) {
Expand Down Expand Up @@ -1092,6 +1133,11 @@ struct ParticleTile
} else {
ptd.m_aos = nullptr;
}
if constexpr (ParticleType::is_soa_particle) {
ptd.m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
} else {
ptd.m_idcpu = nullptr;
}
if constexpr(NArrayReal > 0) {
for (int i = 0; i < NArrayReal; ++i) {
ptd.m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
Expand Down Expand Up @@ -1157,6 +1203,11 @@ struct ParticleTile
} else {
ptd.m_aos = nullptr;
}
if constexpr (ParticleType::is_soa_particle) {
ptd.m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
} else {
ptd.m_idcpu = nullptr;
}
if constexpr(NArrayReal > 0) {
for (int i = 0; i < NArrayReal; ++i) {
ptd.m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
Expand Down
25 changes: 23 additions & 2 deletions Src/Particle/AMReX_StructOfArrays.H
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
namespace amrex {

template <int NReal, int NInt,
template<class> class Allocator=DefaultAllocator>
template<class> class Allocator=DefaultAllocator,
bool use64BitIdCpu=false>
struct StructOfArrays {

using IdCPU = amrex::PODVector<uint64_t, Allocator<uint64_t> >;
using RealVector = amrex::PODVector<ParticleReal, Allocator<ParticleReal> >;
using IntVector = amrex::PODVector<int, Allocator<int> >;

Expand All @@ -28,9 +30,12 @@ struct StructOfArrays {

[[nodiscard]] int NumIntComps () const noexcept { return NInt + m_runtime_idata.size(); }

[[nodiscard]] IdCPU& GetIdCPUData () { return m_idcpu; }
[[nodiscard]] std::array<RealVector, NReal>& GetRealData () { return m_rdata; }
[[nodiscard]] std::array< IntVector, NInt>& GetIntData () { return m_idata; }

/** Get access to the particle id/cpu Arrays */
[[nodiscard]] const IdCPU& GetIdCPUData () const { return m_idcpu; }
/** Get access to the particle Real Arrays (only compile-time components) */
[[nodiscard]] const std::array<RealVector, NReal>& GetRealData () const { return m_rdata; }
/** Get access to the particle Int Arrays (only compile-time components) */
Expand Down Expand Up @@ -119,7 +124,10 @@ struct StructOfArrays {
*/
[[nodiscard]] std::size_t size () const
{
if constexpr (NReal > 0) {
// TODO: if pure SoA:
atmyers marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (use64BitIdCpu == true) {
return m_idcpu.size();
} else if constexpr (NReal > 0) {
return m_rdata[0].size();
} else if constexpr (NInt > 0) {
return m_idata[0].size();
Expand Down Expand Up @@ -175,6 +183,9 @@ struct StructOfArrays {

void resize (size_t count)
{
if constexpr (use64BitIdCpu == true) {
m_idcpu.resize(count);
}
if constexpr (NReal > 0) {
for (int i = 0; i < NReal; ++i) { m_rdata[i].resize(count); }
}
Expand All @@ -185,6 +196,15 @@ struct StructOfArrays {
for (int i = 0; i < int(m_runtime_idata.size()); ++i) { m_runtime_idata[i].resize(count); }
}

[[nodiscard]] IdCPU* idcpuarray () {
if constexpr (use64BitIdCpu == true) {
return m_idcpu.dataPtr();
} else {
return nullptr;
}

}

[[nodiscard]] GpuArray<ParticleReal*, NReal> realarray ()
{
GpuArray<Real*, NReal> arr;
Expand All @@ -208,6 +228,7 @@ struct StructOfArrays {
int m_num_neighbor_particles{0};

private:
IdCPU m_idcpu;
std::array<RealVector, NReal> m_rdata;
std::array< IntVector, NInt> m_idata;

Expand Down
Loading