Skip to content

Commit 2e99628

Browse files
AlexanderSinnax3l
andauthored
PureSoA: Disable AoS Access (#3290)
## Summary When using a PureSoA particle container, trying to access the AoS components will now result in a compile-time error. Previously it still compiled, and I suspect it even allocated memory for AoS. New error message: ``` /hipace/src/Hipace.cpp:1499:39: error: ‘struct amrex::ThisParticleTileHasNoAoS’ has no member named ‘begin’ 1499 | const auto& pos_structs = aos.begin() + nreal; | ^~~~~ ``` Using this I found more places that needed to be updated to account for PureSoA. PureSoA still has the following issues: - [x] I believe it’s not possible to use the binning functions (in `DenseBins.H`) as they require a particle pointer. - [ ] The `ParticleTileData` struct that is used to access SoA data can be very large, over 300 bytes in some cases. I recommend changing the array-of-pointers to a full 2D array. This way ParticleTileData could be as small as 24 bytes (real pointer, int pointer, stride). ## Additional background Follow-up to #2878. ## Checklist The proposed changes: - [x] fix a bug or incorrect behavior in AMReX - [ ] add new capabilities to AMReX - [ ] changes answers in the test suite to more than roundoff level - [ ] are likely to significantly affect the results of downstream AMReX users - [ ] include documentation in the code and/or rst files, if appropriate --------- Co-authored-by: Axel Huebl <[email protected]>
1 parent b2052f2 commit 2e99628

File tree

6 files changed

+32
-21
lines changed

6 files changed

+32
-21
lines changed

Src/Extern/SENSEI/AMReX_ParticleDataAdaptorI.H

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -581,14 +581,14 @@ int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::GetMeshMetadata(
581581
for (const auto& kv : pmap)
582582
{
583583
// loop over particles in ParticleTile
584-
const auto& aos = kv.second.GetArrayOfStructs();
585-
const auto &parts = aos();
584+
auto& particle_tile = kv.second;
585+
auto ptd = particle_tile.getConstParticleTileData();
586586

587587
// visit only the "real" particles, skip the "neighbor" particles.
588-
long long numReal = aos.numRealParticles();
588+
long long numReal = particle_tile.numRealParticles();
589589
for (long long i = 0; i < numReal; ++i)
590590
{
591-
const auto &part = parts[i];
591+
const auto &part = ptd[i];
592592
if (part.id() > 0)
593593
{
594594
#if (AMREX_SPACEDIM == 1)
@@ -869,7 +869,7 @@ int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOARea
869869
for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
870870
{
871871
auto& particle_attributes = pti.GetStructOfArrays();
872-
auto& aos = pti.GetArrayOfStructs();
872+
auto ptd = pti.GetParticleTile().getParticleTileData();
873873

874874
auto numReal = pti.numParticles();
875875
// shuffle from the AMReX component order
@@ -881,7 +881,7 @@ int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOARea
881881

882882
for (long long i = 0; i < numReal; ++i)
883883
{
884-
const auto &part = aos[i];
884+
const auto &part = ptd[i];
885885
if (part.id() > 0)
886886
{
887887
pData[i*nComps + j] = realData[i];
@@ -944,7 +944,7 @@ int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOAInt
944944
for (MyParIter pti(*this->m_particles, level); pti.isValid(); ++pti)
945945
{
946946
auto& particle_attributes = pti.GetStructOfArrays();
947-
auto& aos = pti.GetArrayOfStructs();
947+
auto ptd = pti.GetParticleTile().getParticleTileData();
948948

949949
auto numReal = pti.numParticles();
950950
// shuffle from the AMReX component order
@@ -953,7 +953,7 @@ int ParticleDataAdaptor<ParticleType, NArrayReal, NArrayInt>::AddParticlesSOAInt
953953

954954
for (long long i = 0; i < numReal; ++i)
955955
{
956-
const auto &part = aos[i];
956+
const auto &part = ptd[i];
957957
if (part.id() > 0)
958958
{
959959
pData[i] = intData[i];

Src/Particle/AMReX_ParticleContainerI.H

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,8 +1653,8 @@ ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssig
16531653
if (npart != 0) {
16541654
Long last = npart - 1;
16551655
Long pindex = 0;
1656+
auto ptd = particle_tile->getParticleTileData();
16561657
while (pindex <= last) {
1657-
auto ptd = particle_tile->getParticleTileData();
16581658
ParticleType p(ptd,pindex);
16591659

16601660
if ((remove_negative == false) && (p.id() < 0)) {
@@ -1669,7 +1669,7 @@ ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssig
16691669
for (int comp = 0; comp < NumIntComps(); comp++) {
16701670
soa.GetIntData(comp)[pindex] = soa.GetIntData(comp)[last];
16711671
}
1672-
correctCellVectors(last, pindex, grid, aos[pindex]);
1672+
correctCellVectors(last, pindex, grid, ptd[pindex]);
16731673
--last;
16741674
continue;
16751675
}
@@ -1685,7 +1685,7 @@ ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssig
16851685
for (int comp = 0; comp < NumIntComps(); comp++) {
16861686
soa.GetIntData(comp)[pindex] = soa.GetIntData(comp)[last];
16871687
}
1688-
correctCellVectors(last, pindex, grid, aos[pindex]);
1688+
correctCellVectors(last, pindex, grid, ptd[pindex]);
16891689
--last;
16901690
continue;
16911691
}
@@ -1739,7 +1739,7 @@ ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssig
17391739
for (int comp = 0; comp < NumIntComps(); comp++) {
17401740
soa.GetIntData(comp)[pindex] = soa.GetIntData(comp)[last];
17411741
}
1742-
correctCellVectors(last, pindex, grid, aos[pindex]);
1742+
correctCellVectors(last, pindex, grid, ptd[pindex]);
17431743
--last;
17441744
continue;
17451745
}
@@ -2206,13 +2206,15 @@ RedistributeMPI (std::map<int, Vector<char> >& not_ours,
22062206
const auto& src_tile = kv.second;
22072207

22082208
auto& dst_tile = GetParticles(host_lev)[std::make_pair(grid,tile)];
2209-
auto old_size = dst_tile.GetArrayOfStructs().size();
2209+
auto old_size = dst_tile.size();
22102210
auto new_size = old_size + src_tile.size();
22112211
dst_tile.resize(new_size);
22122212

2213-
Gpu::copyAsync(Gpu::hostToDevice,
2214-
src_tile.begin(), src_tile.end(),
2215-
dst_tile.GetArrayOfStructs().begin() + old_size);
2213+
if constexpr(! ParticleType::is_soa_particle) {
2214+
Gpu::copyAsync(Gpu::hostToDevice,
2215+
src_tile.begin(), src_tile.end(),
2216+
dst_tile.GetArrayOfStructs().begin() + old_size);
2217+
}
22162218

22172219
for (int i = 0; i < NumRealComps(); ++i) {
22182220
Gpu::copyAsync(Gpu::hostToDevice,

Src/Particle/AMReX_ParticleInit.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ InitRandom (Long icount,
11431143
const auto& src_tile = kv.second;
11441144

11451145
auto& dst_tile = GetParticles(host_lev)[std::make_pair(grid,tile)];
1146-
auto old_size = dst_tile.GetArrayOfStructs().size();
1146+
auto old_size = dst_tile.size();
11471147
auto new_size = old_size;
11481148
if constexpr(!ParticleType::is_soa_particle)
11491149
{
@@ -1286,7 +1286,7 @@ InitRandom (Long icount,
12861286
const auto& src_tile = kv.second;
12871287

12881288
auto& dst_tile = GetParticles(host_lev)[std::make_pair(grid,tile)];
1289-
auto old_size = dst_tile.GetArrayOfStructs().size();
1289+
auto old_size = dst_tile.size();
12901290
auto new_size = old_size;
12911291
if constexpr(!ParticleType::is_soa_particle)
12921292
{

Src/Particle/AMReX_ParticleTile.H

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,12 @@ struct ConstParticleTileData
634634
}
635635
};
636636

637+
struct ThisParticleTileHasNoParticleVector {};
638+
639+
struct ThisParticleTileHasNoAoS {
640+
using ParticleVector = ThisParticleTileHasNoParticleVector;
641+
};
642+
637643
template <typename T_ParticleType, int NArrayReal, int NArrayInt,
638644
template<class> class Allocator=DefaultAllocator>
639645
struct ParticleTile
@@ -651,7 +657,10 @@ struct ParticleTile
651657

652658
using SuperParticleType = Particle<NStructReal + NArrayReal, NStructInt + NArrayInt>;
653659

654-
using AoS = ArrayOfStructs<ParticleType, Allocator>;
660+
using AoS = typename std::conditional<
661+
ParticleType::is_soa_particle,
662+
ThisParticleTileHasNoAoS,
663+
ArrayOfStructs<ParticleType, Allocator>>::type;
655664
//using ParticleVector = typename AoS::ParticleVector;
656665

657666
using SoA = StructOfArrays<NArrayReal, NArrayInt, Allocator>;

Tests/Particles/RedistributeSOA/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class TestParticleContainer
132132
}
133133

134134
auto& particle_tile = DefineAndReturnParticleTile(lev, mfi.index(), mfi.LocalTileIndex());
135-
auto old_size = particle_tile.GetArrayOfStructs().size();
135+
auto old_size = particle_tile.size();
136136
auto new_size = old_size + host_real[0].size();
137137
particle_tile.resize(new_size);
138138

Tests/Particles/SENSEI_Insitu_SOA/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class TestParticleContainer
115115
}
116116

117117
auto& particle_tile = DefineAndReturnParticleTile(lev, mfi.index(), mfi.LocalTileIndex());
118-
auto old_size = particle_tile.GetArrayOfStructs().size();
118+
auto old_size = particle_tile.size();
119119
auto new_size = old_size + host_real[0].size();
120120
particle_tile.resize(new_size);
121121

0 commit comments

Comments
 (0)