WarpX
FilterCopyTransform.H
Go to the documentation of this file.
1 /* Copyright 2019-2020 Andrew Myers, Axel Huebl,
2  * Maxence Thevenet
3  *
4  * This file is part of WarpX.
5  *
6  * License: BSD-3-Clause-LBNL
7  */
8 #ifndef WARPX_FILTER_COPY_TRANSFORM_H_
9 #define WARPX_FILTER_COPY_TRANSFORM_H_
10 
12 
13 #include <AMReX_GpuContainers.H>
14 #include <AMReX_TypeTraits.H>
15 
52 template <int N, typename DstPC, typename DstTile, typename SrcTile, typename Index,
53  typename TransFunc, typename CopyFunc,
55 Index filterCopyTransformParticles (DstPC& pc, DstTile& dst, SrcTile& src,
56  Index* mask, Index dst_index,
57  CopyFunc&& copy, TransFunc&& transform) noexcept
58 {
59  using namespace amrex;
60 
61  const auto np = src.numParticles();
62  if (np == 0) { return 0; }
63 
64  Gpu::DeviceVector<Index> offsets(np);
65  auto total = amrex::Scan::ExclusiveSum(np, mask, offsets.data());
66  const Index num_added = N * total;
67  auto old_np = dst.size();
68  auto new_np = std::max(dst_index + num_added, dst.numParticles());
69  dst.resize(new_np);
70 
71  auto *const p_offsets = offsets.dataPtr();
72 
73  const auto src_data = src.getParticleTileData();
74  const auto dst_data = dst.getParticleTileData();
75 
77  [=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const& engine) noexcept
78  {
79  if (mask[i])
80  {
81  for (int j = 0; j < N; ++j) {
82  copy(dst_data, src_data, i, N*p_offsets[i] + dst_index + j, engine);
83  }
84  transform(dst_data, src_data, i, N*p_offsets[i] + dst_index, engine);
85  }
86  });
87 
89  0, 0,
90  pc.getUserRealAttribs(), pc.getUserIntAttribs(),
91  pc.getParticleComps(), pc.getParticleiComps(),
92  pc.getUserRealAttribParser(),
93  pc.getUserIntAttribParser(),
94 #ifdef WARPX_QED
95  false, // do not initialize QED quantities, since they were initialized
96  // when calling the CopyFunc functor
97  pc.get_breit_wheeler_engine_ptr(),
98  pc.get_quantum_sync_engine_ptr(),
99 #endif
100  pc.getIonizationInitialLevel(),
101  old_np, new_np);
102 
104  return num_added;
105 }
106 
144 template <int N, typename DstPC, typename DstTile, typename SrcTile, typename Index,
145  typename PredFunc, typename TransFunc, typename CopyFunc>
146 Index filterCopyTransformParticles (DstPC& pc, DstTile& dst, SrcTile& src, Index dst_index,
147  PredFunc&& filter, CopyFunc&& copy, TransFunc&& transform) noexcept
148 {
149  using namespace amrex;
150 
151  const auto np = src.numParticles();
152  if (np == 0) { return 0; }
153 
155 
156  auto *p_mask = mask.dataPtr();
157  const auto src_data = src.getParticleTileData();
158 
160  [=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const& engine) noexcept
161  {
162  p_mask[i] = filter(src_data, i, engine);
163  });
164 
165  return filterCopyTransformParticles<N>(pc, dst, src, mask.dataPtr(), dst_index,
166  std::forward<CopyFunc>(copy),
167  std::forward<TransFunc>(transform));
168 }
169 
211 template <int N, typename DstPC, typename DstTile, typename SrcTile, typename Index,
212  typename TransFunc, typename CopyFunc1, typename CopyFunc2,
214 Index filterCopyTransformParticles (DstPC& pc1, DstPC& pc2, DstTile& dst1, DstTile& dst2, SrcTile& src, Index* mask,
215  Index dst1_index, Index dst2_index,
216  CopyFunc1&& copy1, CopyFunc2&& copy2,
217  TransFunc&& transform) noexcept
218 {
219  using namespace amrex;
220 
221  auto np = src.numParticles();
222  if (np == 0) { return 0; }
223 
224  Gpu::DeviceVector<Index> offsets(np);
225  auto total = amrex::Scan::ExclusiveSum(np, mask, offsets.data());
226  const Index num_added = N * total;
227  auto old_np1 = dst1.size();
228  auto new_np1 = std::max(dst1_index + num_added, dst1.numParticles());
229  dst1.resize(new_np1);
230 
231  auto old_np2 = dst2.size();
232  auto new_np2 = std::max(dst2_index + num_added, dst2.numParticles());
233  dst2.resize(new_np2);
234 
235  auto *p_offsets = offsets.dataPtr();
236 
237  const auto src_data = src.getParticleTileData();
238  const auto dst1_data = dst1.getParticleTileData();
239  const auto dst2_data = dst2.getParticleTileData();
240 
242  [=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const& engine) noexcept
243  {
244  if (mask[i])
245  {
246  for (int j = 0; j < N; ++j)
247  {
248  copy1(dst1_data, src_data, i, N*p_offsets[i] + dst1_index + j, engine);
249  copy2(dst2_data, src_data, i, N*p_offsets[i] + dst2_index + j, engine);
250  }
251  transform(dst1_data, dst2_data, src_data, i,
252  N*p_offsets[i] + dst1_index,
253  N*p_offsets[i] + dst2_index,
254  engine);
255  }
256  });
257 
259  0, 0,
260  pc1.getUserRealAttribs(), pc1.getUserIntAttribs(),
261  pc1.getParticleComps(), pc1.getParticleiComps(),
262  pc1.getUserRealAttribParser(),
263  pc1.getUserIntAttribParser(),
264 #ifdef WARPX_QED
265  false, // do not initialize QED quantities, since they were initialized
266  // when calling the CopyFunc functor
267  pc1.get_breit_wheeler_engine_ptr(),
268  pc1.get_quantum_sync_engine_ptr(),
269 #endif
270  pc1.getIonizationInitialLevel(),
271  old_np1, new_np1);
273  0, 0,
274  pc2.getUserRealAttribs(), pc2.getUserIntAttribs(),
275  pc2.getParticleComps(), pc2.getParticleiComps(),
276  pc2.getUserRealAttribParser(),
277  pc2.getUserIntAttribParser(),
278 #ifdef WARPX_QED
279  false, // do not initialize QED quantities, since they were initialized
280  // when calling the CopyFunc functor
281  pc2.get_breit_wheeler_engine_ptr(),
282  pc2.get_quantum_sync_engine_ptr(),
283 #endif
284  pc2.getIonizationInitialLevel(),
285  old_np2, new_np2);
286 
288  return num_added;
289 }
290 
333 template <int N, typename DstPC, typename DstTile, typename SrcTile, typename Index,
334  typename PredFunc, typename TransFunc, typename CopyFunc1, typename CopyFunc2>
335 Index filterCopyTransformParticles (DstPC& pc1, DstPC& pc2, DstTile& dst1, DstTile& dst2, SrcTile& src,
336  Index dst1_index, Index dst2_index,
337  PredFunc&& filter, CopyFunc1&& copy1, CopyFunc2&& copy2,
338  TransFunc&& transform) noexcept
339 {
340  using namespace amrex;
341 
342  auto np = src.numParticles();
343  if (np == 0) { return 0; }
344 
346 
347  auto *p_mask = mask.dataPtr();
348  const auto src_data = src.getParticleTileData();
349 
351  [=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const& engine)
352  {
353  p_mask[i] = filter(src_data, i, engine);
354  });
355 
356  return filterCopyTransformParticles<N>(pc1, pc2, dst1, dst2, src, mask.dataPtr(),
357  dst1_index, dst2_index,
358  std::forward<CopyFunc1>(copy1),
359  std::forward<CopyFunc2>(copy2),
360  std::forward<TransFunc>(transform));
361 }
362 
363 #endif //WARPX_FILTER_COPY_TRANSFORM_H_
#define AMREX_GPU_DEVICE
Array4< int const > mask
Index filterCopyTransformParticles(DstPC &pc, DstTile &dst, SrcTile &src, Index *mask, Index dst_index, CopyFunc &&copy, TransFunc &&transform) noexcept
Apply a filter, copy, and transform operation to the particles in src, in that order,...
Definition: FilterCopyTransform.H:55
T * data() noexcept
T * dataPtr() noexcept
void DefaultInitializeRuntimeAttributes(PTile &ptile, const int n_external_attr_real, const int n_external_attr_int, const std::vector< std::string > &user_real_attribs, const std::vector< std::string > &user_int_attribs, const std::map< std::string, int > &particle_comps, const std::map< std::string, int > &particle_icomps, const std::vector< amrex::Parser * > &user_real_attrib_parser, const std::vector< amrex::Parser * > &user_int_attrib_parser, const bool do_qed_comps, BreitWheelerEngine *p_bw_engine, QuantumSynchrotronEngine *p_qs_engine, const int ionization_initial_level, int start, int stop)
Default initialize runtime attributes in a tile. This routine does not initialize the first n_externa...
Definition: DefaultInitialization.H:118
void synchronize() noexcept
void copy(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
T ExclusiveSum(N n, T const *in, T *out, RetSum a_ret_sum=retSum)
AMREX_ATTRIBUTE_FLATTEN_FOR void ParallelForRNG(T n, L const &f) noexcept
std::enable_if_t< B, T > EnableIf_t
i
Definition: check_interp_points_and_weights.py:174
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int const * dataPtr() const noexcept