18#include "Communicate/DataTypes.h"
20#include "Utility/IpplTimings.h"
24 template <
typename T,
class... Properties>
26 size_type required = *(this->localNum_mp) + n;
27 if (this->size() < required) {
28 int overalloc = Comm->getDefaultOverallocation();
29 if (non_destructive) {
31 this->resize(required * overalloc);
34 this->realloc(required * overalloc);
39 template <
typename T,
class... Properties>
41 int overalloc = Comm->getDefaultOverallocation();
42 this->realloc(n * overalloc);
45 template <
typename T,
class... Properties>
47 const hash_type& keepIndex,
48 size_type invalidCount) {
52 using policy_type = Kokkos::RangePolicy<execution_space>;
54 "ParticleAttrib::destroy()", policy_type(0, invalidCount),
55 KOKKOS_LAMBDA(
const size_t i) {
56 dview(deleteIndex(i)) = dview(keepIndex(i));
60 template <
typename T,
class... Properties>
62 auto size = hash.extent(0);
63 if (buf_m.extent(0) < size) {
64 int overalloc = Comm->getDefaultOverallocation();
65 Kokkos::realloc(buf_m, size * overalloc);
70 using policy_type = Kokkos::RangePolicy<execution_space>;
72 "ParticleAttrib::pack()", policy_type(0, size),
73 KOKKOS_LAMBDA(
const size_t i) { buf(i) = dview(hash(i)); });
77 template <
typename T,
class... Properties>
79 auto size = dview_m.extent(0);
80 size_type required = *(this->localNum_mp) + nrecvs;
81 if (size < required) {
82 int overalloc = Comm->getDefaultOverallocation();
83 this->resize(required * overalloc);
86 size_type count = *(this->localNum_mp);
89 using policy_type = Kokkos::RangePolicy<execution_space>;
91 "ParticleAttrib::unpack()", policy_type(0, nrecvs),
92 KOKKOS_LAMBDA(
const size_t i) { dview(count + i) = buf(i); });
96 template <
typename T,
class... Properties>
100 using policy_type = Kokkos::RangePolicy<execution_space>;
101 Kokkos::parallel_for(
102 "ParticleAttrib::operator=()", policy_type(0, *(this->localNum_mp)),
103 KOKKOS_LAMBDA(
const size_t i) { dview(i) = x; });
107 template <
typename T,
class... Properties>
108 template <
typename E,
size_t N>
113 capture_type expr_ =
reinterpret_cast<const capture_type&
>(expr);
115 auto dview = dview_m;
116 using policy_type = Kokkos::RangePolicy<execution_space>;
117 Kokkos::parallel_for(
118 "ParticleAttrib::operator=()", policy_type(0, *(this->localNum_mp)),
119 KOKKOS_LAMBDA(
const size_t i) { dview(i) = expr_(i); });
123 template <
typename T,
class... Properties>
124 template <
typename Field,
class PT,
typename policy_type>
127 policy_type iteration_policy, hash_type hash_array)
const {
128 constexpr unsigned Dim = Field::dim;
129 using PositionType =
typename Field::Mesh_t::value_type;
131 static IpplTimings::TimerRef scatterTimer = IpplTimings::getTimer(
"scatter");
132 IpplTimings::startTimer(scatterTimer);
133 using view_type =
typename Field::view_type;
134 view_type view = f.getView();
136 using mesh_type =
typename Field::Mesh_t;
137 const mesh_type& mesh = f.get_mesh();
139 using vector_type =
typename mesh_type::vector_type;
140 using value_type =
typename ParticleAttrib<T, Properties...>::value_type;
142 const vector_type& dx = mesh.getMeshSpacing();
143 const vector_type& origin = mesh.getOrigin();
144 const vector_type invdx = 1.0 / dx;
148 const int nghost = f.getNghost();
151 const bool useHashView = hash_array.extent(0) > 0;
152 if (useHashView && (iteration_policy.end() > hash_array.extent(0))) {
154 m <<
"Hash array was passed to scatter, but size does not match iteration policy." << endl;
157 auto dview = dview_m;
158 auto ppview = pp.getView();
159 Kokkos::parallel_for(
160 "ParticleAttrib::scatter", iteration_policy,
161 KOKKOS_LAMBDA(
const size_t idx) {
163 size_t mapped_idx = useHashView ? hash_array(idx) : idx;
166 vector_type l = (ppview(mapped_idx) - origin) * invdx + 0.5;
174 const value_type& val = dview(mapped_idx);
175 detail::scatterToField(std::make_index_sequence<1 << Field::dim>{}, view, wlo, whi,
178 IpplTimings::stopTimer(scatterTimer);
180 static IpplTimings::TimerRef accumulateHaloTimer = IpplTimings::getTimer(
"accumulateHalo");
181 IpplTimings::startTimer(accumulateHaloTimer);
183 IpplTimings::stopTimer(accumulateHaloTimer);
186 template <
typename T,
class... Properties>
187 template <
typename Field,
typename P2>
190 const bool addToAttribute) {
191 constexpr unsigned Dim = Field::dim;
192 using PositionType =
typename Field::Mesh_t::value_type;
194 static IpplTimings::TimerRef fillHaloTimer = IpplTimings::getTimer(
"fillHalo");
195 IpplTimings::startTimer(fillHaloTimer);
197 IpplTimings::stopTimer(fillHaloTimer);
199 static IpplTimings::TimerRef gatherTimer = IpplTimings::getTimer(
"gather");
200 IpplTimings::startTimer(gatherTimer);
201 const typename Field::view_type view = f.getView();
203 using mesh_type =
typename Field::Mesh_t;
204 const mesh_type& mesh = f.get_mesh();
206 using vector_type =
typename mesh_type::vector_type;
208 const vector_type& dx = mesh.getMeshSpacing();
209 const vector_type& origin = mesh.getOrigin();
210 const vector_type invdx = 1.0 / dx;
214 const int nghost = f.getNghost();
216 auto dview = dview_m;
217 auto ppview = pp.getView();
218 using policy_type = Kokkos::RangePolicy<execution_space>;
219 Kokkos::parallel_for(
220 "ParticleAttrib::gather", policy_type(0, *(this->localNum_mp)),
221 KOKKOS_LAMBDA(
const size_t idx) {
223 vector_type l = (ppview(idx) - origin) * invdx + 0.5;
231 value_type gathered = detail::gatherFromField(std::make_index_sequence<1 << Field::dim>{},
232 view, wlo, whi, args);
233 if (addToAttribute) {
234 dview(idx) += gathered;
236 dview(idx) = gathered;
239 IpplTimings::stopTimer(gatherTimer);
242 template <
typename T,
class... Properties>
244 const hash_type& permutation) {
246 const auto view = this->getView();
247 const auto size = this->getParticleCount();
249 view_type temp(
"copy", size);
251 using policy_type = Kokkos::RangePolicy<execution_space>;
252 Kokkos::parallel_for(
253 "Copy to temp", policy_type(0, size),
254 KOKKOS_LAMBDA(
const size_type& i) { temp(permutation(i)) = view(i); });
258 Kokkos::deep_copy(Kokkos::subview(view, Kokkos::make_pair<size_type, size_type>(0, size)), temp);
261 template<
typename T,
class... Properties>
263 const hash_type &indices) {
264 auto copySize = indices.size();
267 auto view = this->getView();
268 const auto size = this->getParticleCount();
270 using policy_type = Kokkos::RangePolicy<execution_space>;
271 Kokkos::parallel_for(
272 "Copy to temp", policy_type(0, copySize),
273 KOKKOS_LAMBDA(
const size_type &i) {
274 view(size + i) = view(i);
301 template <
typename Attrib1,
typename Field,
typename Attrib2,
302 typename policy_type = Kokkos::RangePolicy<typename Field::execution_space>>
303 inline void scatter(
const Attrib1& attrib,
Field& f,
const Attrib2& pp) {
304 attrib.scatter(f, pp, policy_type(0, attrib.getParticleCount()));
325 template <
typename Attrib1,
typename Field,
typename Attrib2,
326 typename policy_type = Kokkos::RangePolicy<typename Field::execution_space>>
327 inline void scatter(
const Attrib1& attrib,
Field& f,
const Attrib2& pp,
328 policy_type iteration_policy,
typename Attrib1::hash_type hash_array = {}) {
329 attrib.scatter(f, pp, iteration_policy, hash_array);
349 template <
typename Attrib1,
typename Field,
typename Attrib2>
351 const bool addToAttribute =
false) {
352 attrib.gather(f, pp, addToAttribute);
355#define DefineParticleReduction(fun, name, op, MPI_Op) \
356 template <typename T, class... Properties> \
357 T ParticleAttrib<T, Properties...>::name() { \
359 auto dview = dview_m; \
360 using policy_type = Kokkos::RangePolicy<execution_space>; \
361 Kokkos::parallel_reduce( \
362 "fun", policy_type(0, *(this->localNum_mp)), \
363 KOKKOS_LAMBDA(const size_t i, T& valL) { \
364 T myVal = dview(i); \
367 Kokkos::fun<T>(temp)); \
368 T globaltemp = 0.0; \
369 Comm->allreduce(temp, globaltemp, 1, MPI_Op<T>()); \
373 DefineParticleReduction(Sum, sum, valL += myVal, std::plus)
374 DefineParticleReduction(Max, max,
if (myVal > valL) valL = myVal, std::greater)
375 DefineParticleReduction(Min, min,
if (myVal < valL) valL = myVal, std::less)
376 DefineParticleReduction(Prod, prod, valL *= myVal, std::multiplies)
Definition FieldLayout.h:166
Definition ParticleAttrib.h:33
void destroy(const hash_type &deleteIndex, const hash_type &keepIndex, size_type invalidCount) override
Definition ParticleAttrib.hpp:46
void internalCopy(const hash_type &indices) override
Copy and create values of given indices.
Definition ParticleAttrib.hpp:262
void scatter(Field &f, const ParticleAttrib< Vector< P2, Field::dim >, Properties... > &pp, policy_type iteration_policy, hash_type hash_array={}) const
Scatter particle attribute data onto a field.
void gather(Field &f, const ParticleAttrib< Vector< P2, Field::dim >, Properties... > &pp, const bool addToAttribute=false)
Gather field data into the particle attribute.
Definition ParticleAttrib.hpp:188
void applyPermutation(const hash_type &permutation) override
Sort the attribute according to a permutation.
Definition ParticleAttrib.hpp:243
ParticleAttrib< T, Properties... > & operator=(T x)
Definition ParticleAttrib.hpp:98
void gather(Attrib1 &attrib, Field &f, const Attrib2 &pp, const bool addToAttribute=false)
Non-class interface for gathering field data into a particle attribute.
Definition ParticleAttrib.hpp:350
void scatter(const Attrib1 &attrib, Field &f, const Attrib2 &pp)
Non-class interface for scattering particle attribute data onto a field.
Definition ParticleAttrib.hpp:303
Definition IpplExpressions.h:44
Definition IpplExpressions.h:26