1#ifndef AMREX_PARTICLETILE_H_
2#define AMREX_PARTICLETILE_H_
3#include <AMReX_Config.H>
23template <
int NArrayReal,
int NArrayInt>
24struct ConstSoAParticle;
25template <
int NArrayReal,
int NArrayInt>
28template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt>
29struct ConstParticleTileData;
32template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt>
35 static constexpr int NAR = NArrayReal;
36 static constexpr int NAI = NArrayInt;
53 using AOS_PTR = std::conditional_t<T_ParticleType::is_soa_particle,
67 decltype(
auto)
pos (
const int dir,
const int index)
const &
69 if constexpr(!ParticleType::is_soa_particle) {
70 return this->m_aos[index].pos(dir);
72 return this->m_rdata[dir][index];
77 decltype(
auto)
id (
const int index)
const &
79 if constexpr(!ParticleType::is_soa_particle) {
80 return this->m_aos[index].id();
87 decltype(
auto)
cpu (
const int index)
const &
89 if constexpr(!ParticleType::is_soa_particle) {
90 return this->m_aos[index].cpu();
97 decltype(
auto)
idcpu (
const int index)
const &
99 if constexpr(ParticleType::is_soa_particle) {
100 return this->m_idcpu[index];
102 return this->m_aos[index].idcpu();
109 return this->m_rdata[attribute_index];
113 int *
idata (
const int attribute_index)
const
115 return this->m_idata[attribute_index];
119 decltype(
auto)
operator[] (
const int index)
const
121 if constexpr (!ParticleType::is_soa_particle) {
130 const int* comm_real,
const int * comm_int)
const noexcept
133 auto* dst = buffer + dst_offset;
134 if constexpr (!ParticleType::is_soa_particle) {
138 memcpy(dst,
m_idcpu + src_index,
sizeof(uint64_t));
139 dst +=
sizeof(uint64_t);
141 int array_start_index = 0;
142 if constexpr (!ParticleType::is_soa_particle) {
145 for (
int i = 0; i <
NAR; ++i)
147 if (comm_real[array_start_index + i])
153 int runtime_start_index = array_start_index +
NAR;
156 if (comm_real[runtime_start_index + i])
163 for (
int i = 0; i <
NAI; ++i)
165 if (comm_int[array_start_index + i])
167 memcpy(dst,
m_idata[i] + src_index,
sizeof(
int));
174 if (comm_int[runtime_start_index + i])
184 const int* comm_real,
const int* comm_int)
const noexcept
187 const auto* src = buffer + src_offset;
188 if constexpr (!ParticleType::is_soa_particle) {
192 memcpy(
m_idcpu + dst_index, src,
sizeof(uint64_t));
193 src +=
sizeof(uint64_t);
195 int array_start_index = 0;
196 if constexpr (!ParticleType::is_soa_particle) {
199 if constexpr (
NAR > 0) {
200 for (
int i = 0; i <
NAR; ++i)
202 if (comm_real[array_start_index + i])
209 int runtime_start_index = array_start_index +
NAR;
212 if (comm_real[runtime_start_index + i])
219 if constexpr (
NAI > 0) {
220 for (
int i = 0; i <
NAI; ++i)
222 if (comm_int[array_start_index + i])
224 memcpy(
m_idata[i] + dst_index, src,
sizeof(
int));
232 if (comm_int[runtime_start_index + i])
240 template <
typename T = ParticleType, std::enable_if_t<!T::is_soa_particle,
int> = 0>
246 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
252 if constexpr (
NAR >0) {
253 for (
int i = 0; i <
NAR; ++i) {
262 if constexpr (
NAI > 0) {
263 for (
int i = 0; i <
NAI; ++i) {
270 template <
typename T = ParticleType, std::enable_if_t<T::is_soa_particle,
int> = 0>
277 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {sp.
pos(i) =
m_rdata[i][index];}
278 for (
int i = 0; i <
NAR; ++i) {
281 for (
int i = 0; i <
NAI; ++i) {
287 template <
typename T = ParticleType, std::enable_if_t<!T::is_soa_particle,
int> = 0>
291 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
292 m_aos[index].pos(i) = sp.pos(i);
295 m_aos[index].rdata(i) = sp.rdata(i);
297 for (
int i = 0; i <
NAR; ++i) {
300 m_aos[index].id() = sp.id();
301 m_aos[index].cpu() = sp.cpu();
303 m_aos[index].idata(i) = sp.idata(i);
305 for (
int i = 0; i <
NAI; ++i) {
310 template <
typename T = ParticleType, std::enable_if_t<T::is_soa_particle,
int> = 0>
315 for (
int i = 0; i <
NAR; ++i) {
316 m_rdata[i][index] = sp.rdata(i);
318 for (
int i = 0; i <
NAI; ++i) {
319 m_idata[i][index] = sp.idata(i);
325template <
int T_NArrayReal,
int T_NArrayInt>
341 m_constparticle_tile_data(ptd), m_index(
int(i))
358 RealVect pos () const & {
return RealVect(
AMREX_D_DECL(this->m_constparticle_tile_data.
m_rdata[0][m_index], this->m_constparticle_tile_data.m_rdata[1][m_index], this->m_constparticle_tile_data.m_rdata[2][m_index]));}
364 return this->m_constparticle_tile_data.
m_rdata[position_index][m_index];
383 static_assert(std::is_trivially_copyable<ConstPTD>(),
"ParticleTileData is not trivially copyable");
389template <
int T_NArrayReal,
int T_NArrayInt>
406 m_particle_tile_data(ptd), m_index(
int(i))
421 uint64_t&
idcpu () & {
return this->m_particle_tile_data.
m_idcpu[m_index]; }
430 const uint64_t&
idcpu () const & {
return this->m_particle_tile_data.
m_idcpu[m_index]; }
441 return this->m_particle_tile_data.
m_rdata[position_index][m_index];
448 return this->m_particle_tile_data.
m_rdata[position_index][m_index];
467 static_assert(std::is_trivially_copyable<PTD>(),
"ParticleTileData is not trivially copyable");
469 PTD m_particle_tile_data;
476template <
int NArrayReal,
int NArrayInt>
483#if defined(AMREX_USE_OMP) && defined(_OPENMP) && _OPENMP < 201307
484#pragma omp critical (amrex_particle_nextid)
485#elif defined(AMREX_USE_OMP)
486#pragma omp atomic capture
488 next = the_next_id++;
491 amrex::Abort(
"SoAParticle<NArrayReal, NArrayInt>::NextID() -- too many particles");
497template <
int NArrayReal,
int NArrayInt>
501 Long next = the_next_id++;
503 amrex::Abort(
"SoAParticle<NArrayReal, NArrayInt>::NextID() -- too many particles");
508template <
int NArrayReal,
int NArrayInt>
512 the_next_id = nextid;
515template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt>
518 static constexpr int NAR = NArrayReal;
519 static constexpr int NAI = NArrayInt;
534 using AOS_PTR = std::conditional_t<T_ParticleType::is_soa_particle,
543 decltype(
auto)
pos (
const int dir,
const int index)
const &
545 if constexpr(!ParticleType::is_soa_particle) {
546 return this->m_aos[index].pos(dir);
548 return this->m_rdata[dir][index];
553 decltype(
auto)
id (
const int index)
const &
555 if constexpr(!ParticleType::is_soa_particle) {
556 return this->m_aos[index].id();
563 decltype(
auto)
cpu (
const int index)
const &
565 if constexpr(!ParticleType::is_soa_particle) {
566 return this->m_aos[index].cpu();
573 decltype(
auto)
idcpu (
const int index)
const &
575 if constexpr(ParticleType::is_soa_particle) {
576 return this->m_idcpu[index];
578 return this->m_aos[index].idcpu();
585 return this->m_rdata[attribute_index];
589 const int *
idata (
const int attribute_index)
const
591 return this->m_idata[attribute_index];
595 decltype(
auto)
operator[] (
const int index)
const
597 if constexpr (!ParticleType::is_soa_particle) {
611 const int* comm_real,
const int * comm_int)
const noexcept
614 auto* dst = buffer + dst_offset;
615 if constexpr (!ParticleType::is_soa_particle) {
619 memcpy(dst,
m_idcpu + src_index,
sizeof(uint64_t));
620 dst +=
sizeof(uint64_t);
622 int array_start_index = 0;
623 if constexpr (!ParticleType::is_soa_particle) {
626 if constexpr (NArrayReal > 0) {
627 for (
int i = 0; i < NArrayReal; ++i)
629 if (comm_real[array_start_index + i])
636 int runtime_start_index = array_start_index + NArrayReal;
639 if (comm_real[runtime_start_index + i])
646 if constexpr (NArrayInt > 0) {
647 for (
int i = 0; i < NArrayInt; ++i)
649 if (comm_int[array_start_index + i])
651 memcpy(dst,
m_idata[i] + src_index,
sizeof(
int));
656 runtime_start_index = 2 +
NStructInt + NArrayInt;
659 if (comm_int[runtime_start_index + i])
667 template <
typename T = ParticleType, std::enable_if_t<!T::is_soa_particle,
int> = 0>
673 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
679 if constexpr(NArrayReal > 0) {
680 for (
int i = 0; i < NArrayReal; ++i) {
689 if constexpr(NArrayInt > 0) {
690 for (
int i = 0; i < NArrayInt; ++i) {
697 template <
typename T = ParticleType, std::enable_if_t<T::is_soa_particle,
int> = 0>
703 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {sp.
pos(i) =
m_rdata[i][index];}
705 for (
int i = 0; i <
NAR; ++i) {
708 for (
int i = 0; i <
NAI; ++i) {
737 m_value.store(
true, std::memory_order_relaxed);
743 m_value.store(
true, std::memory_order_relaxed);
747 void store (
bool value, std::memory_order order = std::memory_order_seq_cst)
noexcept
749 m_value.store(value, order);
752 [[nodiscard]]
bool load (std::memory_order order = std::memory_order_seq_cst)
const noexcept
754 return m_value.load(order);
758 std::atomic<bool> m_value {
true};
761template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
765 template <
typename T>
769 static constexpr int NAR = NArrayReal;
770 static constexpr int NAI = NArrayInt;
778 using AoS = std::conditional_t<
779 ParticleType::is_soa_particle,
784 using SoA = std::conditional_t<
785 ParticleType::is_soa_particle,
811 int a_num_runtime_real,
812 int a_num_runtime_int,
813 std::vector<std::string>* soa_rdata_names=
nullptr,
814 std::vector<std::string>* soa_idata_names=
nullptr,
815 Arena* a_arena=
nullptr
818 GetStructOfArrays().define(a_num_runtime_real, a_num_runtime_int, soa_rdata_names, soa_idata_names);
819 m_runtime_r_ptrs.resize(a_num_runtime_real);
820 m_runtime_i_ptrs.resize(a_num_runtime_int);
821 m_runtime_r_cptrs.resize(a_num_runtime_real);
822 m_runtime_i_cptrs.resize(a_num_runtime_int);
827 if constexpr (ParticleType::is_soa_particle) {
830 "ParticleTile with PolymorphicArenaAllocator redefined with "
831 "different memory arena");
834 a_arena == m_aos_tile().arena(),
835 "ParticleTile with PolymorphicArenaAllocator redefined with "
836 "different memory arena");
841 "ParticleTile with PolymorphicArenaAllocator defined with no memory arena! "
842 "Make sure to call setArena() on the ParticleContainer before initialization or "
843 "to pass an Arena to ParticleTile::define()");
845 if constexpr (ParticleType::is_soa_particle) {
848 m_aos_tile().setArena(a_arena);
859 invalidateRuntimePtrCaches();
863 decltype(
auto)
id (
int index) & {
864 if constexpr (!ParticleType::is_soa_particle) {
865 return m_aos_tile[index].id();
872 decltype(
auto)
id (
int index)
const & {
873 if constexpr (!ParticleType::is_soa_particle) {
874 return m_aos_tile[index].id();
881 decltype(
auto)
cpu (
int index) & {
882 if constexpr (!ParticleType::is_soa_particle) {
883 return m_aos_tile[index].cpu();
890 decltype(
auto)
cpu (
int index)
const & {
891 if constexpr (!ParticleType::is_soa_particle) {
892 return m_aos_tile[index].cpu();
900 if constexpr (!ParticleType::is_soa_particle) {
901 return m_aos_tile[index].pos(position_index);
903 static_assert(NArrayReal == ParticleType::PTD::NAR,
"ParticleTile mismatch in R");
904 static_assert(NArrayInt == ParticleType::PTD::NAI,
"ParticleTile mismatch in I");
905 static_assert(0 == ParticleType::StorageParticleType::NReal,
"ParticleTile 2 mismatch in R");
906 static_assert(0 == ParticleType::StorageParticleType::NInt,
"ParticleTile 2 mismatch in I");
908 return m_soa_tile.GetRealData(position_index)[index];
915 if constexpr (!ParticleType::is_soa_particle) {
916 return m_aos_tile[index].pos(position_index);
918 return m_soa_tile.GetRealData(position_index)[index];
936 if constexpr (!ParticleType::is_soa_particle) {
937 return m_aos_tile.size();
939 return m_soa_tile.size();
949 if constexpr (!ParticleType::is_soa_particle) {
950 return m_aos_tile.numParticles();
952 return m_soa_tile.numParticles();
962 if constexpr (!ParticleType::is_soa_particle) {
963 return m_aos_tile.numRealParticles();
965 return m_soa_tile.numRealParticles();
975 if constexpr (!ParticleType::is_soa_particle) {
976 return m_aos_tile.numNeighborParticles();
978 return m_soa_tile.numNeighborParticles();
988 if constexpr (!ParticleType::is_soa_particle) {
989 return m_aos_tile.numTotalParticles();
991 return m_soa_tile.numTotalParticles();
997 invalidateRuntimePtrCaches();
998 if constexpr(!ParticleType::is_soa_particle) {
999 m_aos_tile.setNumNeighbors(num_neighbors);
1001 m_soa_tile.setNumNeighbors(num_neighbors);
1006 if constexpr (!ParticleType::is_soa_particle) {
1007 AMREX_ASSERT( m_soa_tile.getNumNeighbors() == m_aos_tile.getNumNeighbors() );
1008 return m_aos_tile.getNumNeighbors();
1010 return m_soa_tile.getNumNeighbors();
1016 invalidateRuntimePtrCaches();
1017 if constexpr (!ParticleType::is_soa_particle) {
1018 m_aos_tile.resize(count, strategy);
1020 m_soa_tile.resize(count, strategy);
1025 invalidateRuntimePtrCaches();
1026 if constexpr (!ParticleType::is_soa_particle) {
1027 m_aos_tile.reserve(
capacity, strategy);
1029 m_soa_tile.reserve(
capacity, strategy);
1035 template <
typename T = ParticleType, std::enable_if_t<!T::is_soa_particle,
int> = 0>
1038 invalidateRuntimePtrCaches();
1039 m_aos_tile().push_back(p);
1045 template <
int NR = NArrayReal,
int NI = NArrayInt,
1046 std::enable_if_t<NR != 0 || NI != 0, int> foo = 0>
1049 invalidateRuntimePtrCaches();
1052 if constexpr (!ParticleType::is_soa_particle) {
1053 m_aos_tile.resize(np+1);
1054 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
1055 m_aos_tile[np].pos(i) = sp.
pos(i);
1058 m_aos_tile[np].rdata(i) = sp.
rdata(i);
1060 m_aos_tile[np].id() = sp.
id();
1061 m_aos_tile[np].cpu() = sp.
cpu();
1063 m_aos_tile[np].idata(i) = sp.
idata(i);
1067 m_soa_tile.resize(np+1);
1068 if constexpr (ParticleType::is_soa_particle) {
1069 m_soa_tile.GetIdCPUData()[np] = sp.
m_idcpu;
1071 auto& arr_rdata = m_soa_tile.GetRealData();
1072 auto& arr_idata = m_soa_tile.GetIntData();
1073 for (
int i = 0; i < NArrayReal; ++i) {
1076 for (
int i = 0; i < NArrayInt; ++i) {
1086 invalidateRuntimePtrCaches();
1087 m_soa_tile.GetRealData(comp).push_back(v);
1095 for (
int i = 0; i < NArrayReal; ++i) {
1096 m_soa_tile.GetRealData(i).push_back(v[i]);
1105 invalidateRuntimePtrCaches();
1106 auto it = m_soa_tile.GetRealData(comp).end();
1107 m_soa_tile.GetRealData(comp).insert(it, beg,
end);
1131 invalidateRuntimePtrCaches();
1132 auto new_size = m_soa_tile.GetRealData(comp).size() + npar;
1133 m_soa_tile.GetRealData(comp).resize(new_size, v);
1141 invalidateRuntimePtrCaches();
1142 m_soa_tile.GetIntData(comp).push_back(v);
1150 for (
int i = 0; i < NArrayInt; ++i) {
1151 m_soa_tile.GetIntData(i).push_back(v[i]);
1160 invalidateRuntimePtrCaches();
1161 auto it = m_soa_tile.GetIntData(comp).end();
1162 m_soa_tile.GetIntData(comp).insert(it, beg,
end);
1186 invalidateRuntimePtrCaches();
1187 auto new_size = m_soa_tile.GetIntData(comp).size() + npar;
1188 m_soa_tile.GetIntData(comp).resize(new_size, v);
1193 int NumIntComps () const noexcept {
return m_soa_tile.NumIntComps(); }
1201 invalidateRuntimePtrCaches();
1202 if constexpr (ParticleType::is_soa_particle) {
1205 m_aos_tile().shrink_to_fit();
1210 rdata.shrink_to_fit();
1216 idata.shrink_to_fit();
1223 if constexpr (ParticleType::is_soa_particle) {
1226 nbytes += m_aos_tile().capacity() *
sizeof(
ParticleType);
1237 nbytes += idata.capacity()*
sizeof(
int);
1244 if constexpr (ParticleType::is_soa_particle) {
1245 GetStructOfArrays().GetIdCPUData().swap(other.GetStructOfArrays().GetIdCPUData());
1247 m_aos_tile().swap(other.GetArrayOfStructs()());
1252 rdata.swap(other.GetStructOfArrays().GetRealData(j));
1258 idata.swap(other.GetStructOfArrays().GetIntData(j));
1260 invalidateRuntimePtrCaches();
1261 other.invalidateRuntimePtrCaches();
1266 refreshRuntimePtrCaches();
1269 if constexpr (!ParticleType::is_soa_particle) {
1270 ptd.
m_aos = m_aos_tile().dataPtr();
1272 ptd.
m_aos =
nullptr;
1274 if constexpr (ParticleType::is_soa_particle) {
1275 ptd.
m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
1279 if constexpr(NArrayReal > 0) {
1280 for (
int i = 0; i < NArrayReal; ++i) {
1281 ptd.
m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
1284 if constexpr(NArrayInt > 0) {
1285 for (
int i = 0; i < NArrayInt; ++i) {
1286 ptd.
m_idata[i] = m_soa_tile.GetIntData(i).dataPtr();
1300 refreshConstRuntimePtrCaches();
1303 if constexpr (!ParticleType::is_soa_particle) {
1304 ptd.
m_aos = m_aos_tile().dataPtr();
1306 ptd.
m_aos =
nullptr;
1308 if constexpr (ParticleType::is_soa_particle) {
1309 ptd.
m_idcpu = m_soa_tile.GetIdCPUData().dataPtr();
1313 if constexpr(NArrayReal > 0) {
1314 for (
int i = 0; i < NArrayReal; ++i) {
1315 ptd.
m_rdata[i] = m_soa_tile.GetRealData(i).dataPtr();
1318 if constexpr(NArrayInt > 0) {
1319 for (
int i = 0; i < NArrayInt; ++i) {
1320 ptd.
m_idata[i] = m_soa_tile.GetIntData(i).dataPtr();
1336 invalidateRuntimePtrCaches();
1337 if constexpr (!ParticleType::is_soa_particle) {
1338 m_aos_tile.collectVectors(pv);
1342 m_soa_tile.collectVectors(idcpuv, rv, iv);
1348 for (
auto [p,s] : addsizes) {
1349 p->reserve(p->size()+s);
1352 using PV = std::conditional_t<ParticleType::is_soa_particle,
1358 for (
auto [p,s] : addsizes) {
1364 p->collectVectors(pv, idcpuv, rv, iv);
1365 if constexpr (!ParticleType::is_soa_particle) {
1366 for (
auto* v : pv) {
1367 pvs.emplace_back(v, s);
1370 for (
auto* v : idcpuv) {
1371 ids.emplace_back(v, s);
1373 for (
auto* v : rv) {
1374 rvs.emplace_back(v, s);
1376 for (
auto* v : iv) {
1377 ivs.emplace_back(v, s);
1382 std::sort(pvs.begin(), pvs.end(), [] (
auto const& a,
auto const& b) {
1383 return (a.first->size() + a.second) >
1384 (b.first->size() + b.second);
1386 std::sort(ids.begin(), ids.end(), [] (
auto const& a,
auto const& b) {
1387 return (a.first->size() + a.second) >
1388 (b.first->size() + b.second);
1390 std::sort(rvs.begin(), rvs.end(), [] (
auto const& a,
auto const& b) {
1391 return (a.first->size() + a.second) >
1392 (b.first->size() + b.second);
1394 std::sort(ivs.begin(), ivs.end(), [] (
auto const& a,
auto const& b) {
1395 return (a.first->size() + a.second) >
1396 (b.first->size() + b.second);
1401 int i_pvs = 0, i_ids = 0, i_rvs = 0, i_ivs = 0;
1406 while ((i_pvs < n_pvs) || (i_ids < n_ids) || (i_rvs < n_rvs) ||
1408 std::size_t nbytes = 0;
1410 if (i_pvs < n_pvs) {
1411 std::size_t my_bytes = (pvs[i_pvs].first->
size()
1412 + pvs[i_pvs].second) *
sizeof(
typename PV::value_type);
1413 if (my_bytes > nbytes) {
1418 if (i_ids < n_ids) {
1419 std::size_t my_bytes = (ids[i_ids].first->
size()
1420 + ids[i_ids].second) *
sizeof(
typename SoA::IdCPU::value_type);
1421 if (my_bytes > nbytes) {
1426 if (i_rvs < n_rvs) {
1427 std::size_t my_bytes = (rvs[i_rvs].first->
size()
1428 + rvs[i_rvs].second) *
sizeof(
typename RealVector::value_type);
1429 if (my_bytes > nbytes) {
1434 if (i_ivs < n_ivs) {
1435 std::size_t my_bytes = (ivs[i_ivs].first->
size()
1436 + ivs[i_ivs].second) *
sizeof(
typename IntVector::value_type);
1437 if (my_bytes > nbytes) {
1443 auto [p,s] = pvs[i_pvs++];
1444 p->reserve(p->size() + s);
1445 }
else if (ii == 1) {
1446 auto [p,s] = ids[i_ids++];
1447 p->reserve(p->size() + s);
1448 }
else if (ii == 2) {
1449 auto [p,s] = rvs[i_rvs++];
1450 p->reserve(p->size() + s);
1452 auto [p,s] = ivs[i_ivs++];
1453 p->reserve(p->size() + s);
1462 void invalidateRuntimePtrCaches () noexcept
1464 m_runtime_ptrs_dirty.
store(
true, std::memory_order_release);
1465 m_runtime_cptrs_dirty.
store(
true, std::memory_order_release);
1468 void refreshRuntimePtrCaches ()
1470 if (!m_runtime_ptrs_dirty.
load(std::memory_order_acquire)) {
1473#if defined(AMREX_USE_OMP)
1474#pragma omp critical (amrex_particle_tile_data_cache)
1477 if (m_runtime_ptrs_dirty.
load(std::memory_order_relaxed)) {
1478 m_runtime_r_ptrs.resize(m_soa_tile.NumRealComps() - NArrayReal);
1479 m_runtime_i_ptrs.resize(m_soa_tile.NumIntComps() - NArrayInt);
1481 bool copy_real =
false;
1482 m_h_runtime_r_ptrs.resize(m_soa_tile.NumRealComps() - NArrayReal,
nullptr);
1483 for (std::size_t i = 0; i < m_h_runtime_r_ptrs.size(); ++i) {
1484 if (m_h_runtime_r_ptrs[i] != m_soa_tile.GetRealData(i + NArrayReal).dataPtr()) {
1485 m_h_runtime_r_ptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1494 bool copy_int =
false;
1495 m_h_runtime_i_ptrs.resize(m_soa_tile.NumIntComps() - NArrayInt,
nullptr);
1496 for (std::size_t i = 0; i < m_h_runtime_i_ptrs.size(); ++i) {
1497 if (m_h_runtime_i_ptrs[i] != m_soa_tile.GetIntData(i + NArrayInt).dataPtr()) {
1498 m_h_runtime_i_ptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1504 m_h_runtime_i_ptrs.size()*
sizeof(
int*));
1507 if (copy_real || copy_int) {
1511 for (std::size_t i = 0; i < m_runtime_r_ptrs.size(); ++i) {
1512 m_runtime_r_ptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1515 for (std::size_t i = 0; i < m_runtime_i_ptrs.size(); ++i) {
1516 m_runtime_i_ptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1519 m_runtime_ptrs_dirty.
store(
false, std::memory_order_release);
1524 void refreshConstRuntimePtrCaches ()
const
1526 if (!m_runtime_cptrs_dirty.
load(std::memory_order_acquire)) {
1529#if defined(AMREX_USE_OMP)
1530#pragma omp critical (amrex_const_particle_tile_data_cache)
1533 if (m_runtime_cptrs_dirty.
load(std::memory_order_relaxed)) {
1534 m_runtime_r_cptrs.resize(m_soa_tile.NumRealComps() - NArrayReal);
1535 m_runtime_i_cptrs.resize(m_soa_tile.NumIntComps() - NArrayInt);
1537 bool copy_real =
false;
1538 m_h_runtime_r_cptrs.resize(m_soa_tile.NumRealComps() - NArrayReal,
nullptr);
1539 for (std::size_t i = 0; i < m_h_runtime_r_cptrs.size(); ++i) {
1540 if (m_h_runtime_r_cptrs[i] != m_soa_tile.GetRealData(i + NArrayReal).dataPtr()) {
1541 m_h_runtime_r_cptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1550 bool copy_int =
false;
1551 m_h_runtime_i_cptrs.resize(m_soa_tile.NumIntComps() - NArrayInt,
nullptr);
1552 for (std::size_t i = 0; i < m_h_runtime_i_cptrs.size(); ++i) {
1553 if (m_h_runtime_i_cptrs[i] != m_soa_tile.GetIntData(i + NArrayInt).dataPtr()) {
1554 m_h_runtime_i_cptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1560 m_h_runtime_i_cptrs.size()*
sizeof(
int*));
1563 if (copy_real || copy_int) {
1567 for (std::size_t i = 0; i < m_runtime_r_cptrs.size(); ++i) {
1568 m_runtime_r_cptrs[i] = m_soa_tile.GetRealData(i + NArrayReal).dataPtr();
1571 for (std::size_t i = 0; i < m_runtime_i_cptrs.size(); ++i) {
1572 m_runtime_i_cptrs[i] = m_soa_tile.GetIntData(i + NArrayInt).dataPtr();
1575 m_runtime_cptrs_dirty.
store(
false, std::memory_order_release);
1583 bool m_defined =
false;
1597 RuntimePtrCacheDirtyFlag m_runtime_ptrs_dirty;
1598 mutable RuntimePtrCacheDirtyFlag m_runtime_cptrs_dirty;
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:32
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
A virtual base class for objects that manage their own dynamic memory allocation.
Definition AMReX_Arena.H:132
Definition AMReX_ArrayOfStructs.H:13
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:90
amrex_long Long
Definition AMReX_INT.H:30
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:310
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:421
constexpr Long LastParticleID
Definition AMReX_Particle.H:21
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
amrex::ArenaAllocator< T > DefaultAllocator
Definition AMReX_GpuAllocators.H:205
GrowthStrategy
Definition AMReX_PODVector.H:250
RealVectND< 3 > RealVect
Definition AMReX_ParmParse.H:36
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:241
const int[]
Definition AMReX_BLProfiler.cpp:1664
__host__ __device__ Dim3 end(BoxND< dim > const &box) noexcept
Definition AMReX_Box.H:2015
Definition AMReX_Particle.H:327
Definition AMReX_Particle.H:301
static constexpr bool is_particle_tile_data
Definition AMReX_ParticleTile.H:530
static constexpr int NAI
Definition AMReX_ParticleTile.H:519
int IntType
Definition AMReX_ParticleTile.H:523
GpuArray< const int *, NArrayInt > m_idata
Definition AMReX_ParticleTile.H:540
__host__ __device__ decltype(auto) idcpu(const int index) const &
Definition AMReX_ParticleTile.H:573
__host__ __device__ const int * idata(const int attribute_index) const
Definition AMReX_ParticleTile.H:589
Long m_size
Definition AMReX_ParticleTile.H:532
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:520
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:525
__host__ __device__ void packParticleData(char *buffer, int src_index, Long dst_offset, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:610
int m_num_runtime_real
Definition AMReX_ParticleTile.H:604
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:526
const int *__restrict__ *__restrict__ m_runtime_idata
Definition AMReX_ParticleTile.H:607
ParticleReal RealType
Definition AMReX_ParticleTile.H:522
__host__ __device__ decltype(auto) pos(const int dir, const int index) const &
Definition AMReX_ParticleTile.H:543
__host__ __device__ decltype(auto) cpu(const int index) const &
Definition AMReX_ParticleTile.H:563
int m_num_runtime_int
Definition AMReX_ParticleTile.H:605
std::conditional_t< T_ParticleType::is_soa_particle, void const *__restrict__, ParticleType const *__restrict__ > AOS_PTR
Definition AMReX_ParticleTile.H:535
T_ParticleType const & ParticleRefType
Definition AMReX_ParticleTile.H:521
static constexpr int NAR
Definition AMReX_ParticleTile.H:518
AOS_PTR m_aos
Definition AMReX_ParticleTile.H:536
const uint64_t * m_idcpu
Definition AMReX_ParticleTile.H:538
__host__ __device__ SuperParticleType getSuperParticle(int index) const noexcept
Definition AMReX_ParticleTile.H:669
__host__ __device__ const ParticleReal * rdata(const int attribute_index) const
Definition AMReX_ParticleTile.H:583
GpuArray< const ParticleReal *, NArrayReal > m_rdata
Definition AMReX_ParticleTile.H:539
const ParticleReal *__restrict__ *__restrict__ m_runtime_rdata
Definition AMReX_ParticleTile.H:606
Definition AMReX_ParticleTile.H:327
__host__ __device__ ConstParticleIDWrapper id() const
Definition AMReX_ParticleTile.H:353
static constexpr int NArrayReal
Definition AMReX_ParticleTile.H:328
ParticleReal RealType
Definition AMReX_ParticleTile.H:336
__host__ __device__ ConstSoAParticle(ConstPTD const &ptd, long i)
Definition AMReX_ParticleTile.H:340
static constexpr int NArrayInt
Definition AMReX_ParticleTile.H:329
static constexpr bool is_rtsoa_particle
Definition AMReX_ParticleTile.H:333
static void NextID(Long nextid)
Reset on restart.
static constexpr bool is_constsoa_particle
Definition AMReX_ParticleTile.H:334
static Long UnprotectedNextID()
This version can only be used inside omp critical.
__host__ __device__ const RealType & pos(int position_index) const &
Definition AMReX_ParticleTile.H:361
__host__ __device__ RealVect pos() const &
Definition AMReX_ParticleTile.H:358
__host__ __device__ ConstParticleCPUWrapper cpu() const
Definition AMReX_ParticleTile.H:350
int IntType
Definition AMReX_ParticleTile.H:337
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:43
Definition AMReX_GpuAllocators.H:173
Definition AMReX_GpuAllocators.H:184
uint64_t m_idcpu
Definition AMReX_Particle.H:359
Definition AMReX_Particle.H:259
Definition AMReX_Particle.H:154
Definition AMReX_ParticleTile.H:34
__host__ __device__ SuperParticleType getSuperParticle(int index) const noexcept
Definition AMReX_ParticleTile.H:242
T_ParticleType & ParticleRefType
Definition AMReX_ParticleTile.H:39
__host__ __device__ decltype(auto) cpu(const int index) const &
Definition AMReX_ParticleTile.H:87
uint64_t * m_idcpu
Definition AMReX_ParticleTile.H:57
GpuArray< ParticleReal *, NAR > m_rdata
Definition AMReX_ParticleTile.H:58
__host__ __device__ void unpackParticleData(const char *buffer, Long src_offset, int dst_index, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:183
__host__ __device__ decltype(auto) idcpu(const int index) const &
Definition AMReX_ParticleTile.H:97
__host__ __device__ ParticleReal * rdata(const int attribute_index) const
Definition AMReX_ParticleTile.H:107
__host__ __device__ void packParticleData(char *buffer, int src_index, std::size_t dst_offset, const int *comm_real, const int *comm_int) const noexcept
Definition AMReX_ParticleTile.H:129
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:45
GpuArray< int *, NAI > m_idata
Definition AMReX_ParticleTile.H:59
ParticleReal RealType
Definition AMReX_ParticleTile.H:41
__host__ __device__ decltype(auto) pos(const int dir, const int index) const &
Definition AMReX_ParticleTile.H:67
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:38
std::conditional_t< T_ParticleType::is_soa_particle, void *__restrict__, ParticleType *__restrict__ > AOS_PTR
Definition AMReX_ParticleTile.H:54
int m_num_runtime_int
Definition AMReX_ParticleTile.H:62
Long m_size
Definition AMReX_ParticleTile.H:51
static constexpr int NAR
Definition AMReX_ParticleTile.H:35
int IntType
Definition AMReX_ParticleTile.H:42
ParticleReal *__restrict__ *__restrict__ m_runtime_rdata
Definition AMReX_ParticleTile.H:63
int m_num_runtime_real
Definition AMReX_ParticleTile.H:61
static constexpr bool is_particle_tile_data
Definition AMReX_ParticleTile.H:49
__host__ __device__ int * idata(const int attribute_index) const
Definition AMReX_ParticleTile.H:113
AOS_PTR m_aos
Definition AMReX_ParticleTile.H:55
static constexpr int NAI
Definition AMReX_ParticleTile.H:36
int *__restrict__ *__restrict__ m_runtime_idata
Definition AMReX_ParticleTile.H:64
__host__ __device__ void setSuperParticle(const SuperParticleType &sp, int index) const noexcept
Definition AMReX_ParticleTile.H:289
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:44
Definition AMReX_ParticleTile.H:764
typename ParticleType::StorageParticleType StorageParticleType
Definition AMReX_ParticleTile.H:790
int NumRealComps() const noexcept
Definition AMReX_ParticleTile.H:1191
void push_back_real(int comp, amrex::Vector< amrex::ParticleReal > const &vec)
Definition AMReX_ParticleTile.H:1122
int NumIntComps() const noexcept
Definition AMReX_ParticleTile.H:1193
typename ParticleType::RealType RealType
Definition AMReX_ParticleTile.H:771
int getNumNeighbors() const
Definition AMReX_ParticleTile.H:1004
typename AoS::ParticleVector ParticleVector
Definition AMReX_ParticleTile.H:782
void push_back(const ParticleType &p)
Definition AMReX_ParticleTile.H:1036
ParticleTile(ParticleTile const &)=delete
std::conditional_t< ParticleType::is_soa_particle, StructOfArrays< NArrayReal, NArrayInt, Allocator, true >, StructOfArrays< NArrayReal, NArrayInt, Allocator, false > > SoA
Definition AMReX_ParticleTile.H:787
const SoA & GetStructOfArrays() const
Definition AMReX_ParticleTile.H:926
static constexpr int NAI
Definition AMReX_ParticleTile.H:770
ParticleTile(ParticleTile &&) noexcept=default
void push_back_real(int comp, const ParticleReal *beg, const ParticleReal *end)
Definition AMReX_ParticleTile.H:1104
static constexpr int NStructInt
Definition AMReX_ParticleTile.H:774
void setNumNeighbors(int num_neighbors)
Definition AMReX_ParticleTile.H:995
Long capacity() const
Definition AMReX_ParticleTile.H:1220
int numTotalParticles() const
Returns the total number of particles, real and neighbor.
Definition AMReX_ParticleTile.H:986
std::size_t size() const
Returns the total number of particles (real and neighbor)
Definition AMReX_ParticleTile.H:934
static constexpr bool has_polymorphic_allocator
Definition AMReX_ParticleTile.H:795
ParticleTileDataType getParticleTileData()
Definition AMReX_ParticleTile.H:1264
void reserve(std::size_t capacity, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_ParticleTile.H:1023
void push_back(const SuperParticleType &sp)
Definition AMReX_ParticleTile.H:1047
int numNeighborParticles() const
Returns the number of neighbor particles (excluding reals)
Definition AMReX_ParticleTile.H:973
const AoS & GetArrayOfStructs() const
Definition AMReX_ParticleTile.H:923
static constexpr int NAR
Definition AMReX_ParticleTile.H:769
ConstParticleTileDataType getConstParticleTileData() const
Definition AMReX_ParticleTile.H:1298
void shrink_to_fit()
Definition AMReX_ParticleTile.H:1199
T_ParticleType ParticleType
Definition AMReX_ParticleTile.H:768
int numParticles() const
Returns the number of real particles (excluding neighbors)
Definition AMReX_ParticleTile.H:947
void push_back_int(int comp, amrex::Vector< int > const &vec)
Definition AMReX_ParticleTile.H:1177
void resize(std::size_t count, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_ParticleTile.H:1014
void swap(ParticleTile< ParticleType, NArrayReal, NArrayInt, Allocator > &other) noexcept
Definition AMReX_ParticleTile.H:1242
void push_back_int(int comp, amrex::Vector< int >::const_iterator beg, amrex::Vector< int >::const_iterator end)
Definition AMReX_ParticleTile.H:1169
void push_back_real(const std::array< ParticleReal, NArrayReal > &v)
Definition AMReX_ParticleTile.H:1094
int NumRuntimeRealComps() const noexcept
Definition AMReX_ParticleTile.H:1195
void collectVectors(Vector< ParticleVector * > &pv, Vector< typename SoA::IdCPU * > &idcpuv, Vector< RealVector * > &rv, Vector< IntVector * > &iv)
Definition AMReX_ParticleTile.H:1332
AoS & GetArrayOfStructs()
Definition AMReX_ParticleTile.H:922
RealType & pos(int index, int position_index) &
Definition AMReX_ParticleTile.H:899
typename SoA::IntVector IntVector
Definition AMReX_ParticleTile.H:789
void push_back_int(const std::array< int, NArrayInt > &v)
Definition AMReX_ParticleTile.H:1149
void push_back_real(int comp, amrex::Vector< amrex::ParticleReal >::const_iterator beg, amrex::Vector< amrex::ParticleReal >::const_iterator end)
Definition AMReX_ParticleTile.H:1114
Allocator< T > AllocatorType
Definition AMReX_ParticleTile.H:766
int NumRuntimeIntComps() const noexcept
Definition AMReX_ParticleTile.H:1197
bool empty() const
Definition AMReX_ParticleTile.H:928
void push_back_int(int comp, int v)
Definition AMReX_ParticleTile.H:1140
RealType pos(int index, int position_index) const &
Definition AMReX_ParticleTile.H:913
decltype(auto) cpu(int index) &
Definition AMReX_ParticleTile.H:881
void define(int a_num_runtime_real, int a_num_runtime_int, std::vector< std::string > *soa_rdata_names=nullptr, std::vector< std::string > *soa_idata_names=nullptr, Arena *a_arena=nullptr)
Definition AMReX_ParticleTile.H:810
SoA & GetStructOfArrays()
Definition AMReX_ParticleTile.H:925
void push_back_int(int comp, std::size_t npar, int v)
Definition AMReX_ParticleTile.H:1185
void push_back_real(int comp, std::size_t npar, ParticleReal v)
Definition AMReX_ParticleTile.H:1130
void push_back_int(int comp, const int *beg, const int *end)
Definition AMReX_ParticleTile.H:1159
typename SoA::RealVector RealVector
Definition AMReX_ParticleTile.H:788
int numRealParticles() const
Returns the number of real particles (excluding neighbors)
Definition AMReX_ParticleTile.H:960
std::conditional_t< ParticleType::is_soa_particle, ThisParticleTileHasNoAoS, ArrayOfStructs< ParticleType, Allocator > > AoS
Definition AMReX_ParticleTile.H:781
static constexpr int NStructReal
Definition AMReX_ParticleTile.H:773
void push_back_real(int comp, ParticleReal v)
Definition AMReX_ParticleTile.H:1085
static void reserve(std::map< ParticleTile< T_ParticleType, NArrayReal, NArrayInt, Allocator > *, int > const &addsizes)
Definition AMReX_ParticleTile.H:1345
The struct used to store particles.
Definition AMReX_Particle.H:405
__host__ __device__ RealVect pos() const &
Definition AMReX_Particle.H:456
__host__ __device__ int & idata(int index) &
Definition AMReX_Particle.H:545
__host__ __device__ ParticleCPUWrapper cpu() &
Definition AMReX_Particle.H:424
__host__ __device__ ParticleIDWrapper id() &
Definition AMReX_Particle.H:427
__host__ __device__ RealType & rdata(int index) &
Definition AMReX_Particle.H:474
Definition AMReX_ParticleTile.H:722
RuntimePtrCacheDirtyFlag(RuntimePtrCacheDirtyFlag &&) noexcept
Definition AMReX_ParticleTile.H:731
RuntimePtrCacheDirtyFlag() noexcept=default
void store(bool value, std::memory_order order=std::memory_order_seq_cst) noexcept
Definition AMReX_ParticleTile.H:747
bool load(std::memory_order order=std::memory_order_seq_cst) const noexcept
Definition AMReX_ParticleTile.H:752
RuntimePtrCacheDirtyFlag & operator=(RuntimePtrCacheDirtyFlag const &) noexcept
Definition AMReX_ParticleTile.H:735
Definition AMReX_Particle.H:388
Definition AMReX_ParticleTile.H:391
static constexpr int NArrayReal
Definition AMReX_ParticleTile.H:392
ParticleTileData< SoAParticleBase, NArrayReal, NArrayInt > PTD
Definition AMReX_ParticleTile.H:395
__host__ __device__ uint64_t & idcpu() &
Definition AMReX_ParticleTile.H:421
static Long UnprotectedNextID()
This version can only be used inside omp critical.
Definition AMReX_ParticleTile.H:499
__host__ __device__ ConstParticleCPUWrapper cpu() const &
Definition AMReX_ParticleTile.H:424
static Long the_next_id
Definition AMReX_ParticleTile.H:410
static constexpr int NArrayInt
Definition AMReX_ParticleTile.H:393
__host__ __device__ const uint64_t & idcpu() const &
Definition AMReX_ParticleTile.H:430
__host__ __device__ RealVect pos() const &
Definition AMReX_ParticleTile.H:435
ParticleReal RealType
Definition AMReX_ParticleTile.H:401
__host__ __device__ ParticleCPUWrapper cpu() &
Definition AMReX_ParticleTile.H:415
__host__ __device__ ParticleIDWrapper id() &
Definition AMReX_ParticleTile.H:418
static constexpr bool is_constsoa_particle
Definition AMReX_ParticleTile.H:398
__host__ __device__ RealType & pos(int position_index) &
Definition AMReX_ParticleTile.H:438
static constexpr bool is_rtsoa_particle
Definition AMReX_ParticleTile.H:397
int IntType
Definition AMReX_ParticleTile.H:402
__host__ __device__ SoAParticle(PTD const &ptd, long i)
Definition AMReX_ParticleTile.H:405
__host__ __device__ ConstParticleIDWrapper id() const &
Definition AMReX_ParticleTile.H:427
static Long NextID()
Definition AMReX_ParticleTile.H:478
__host__ __device__ RealType pos(int position_index) const &
Definition AMReX_ParticleTile.H:445
Definition AMReX_StructOfArrays.H:20
Definition AMReX_ParticleTile.H:717
Definition AMReX_ParticleTile.H:715
Definition AMReX_MakeParticle.H:13