1#ifndef AMREX_PARTICLEREDUCE_SIMD_H_
2#define AMREX_PARTICLEREDUCE_SIMD_H_
3#include <AMReX_Config.H>
18namespace particle_detail {
22 struct SIMDTupleWrapper
26 template <
typename PTD,
typename SI>
28 auto operator() (PTD
const& ptd, SI
const si)
const noexcept
41 template <
typename F,
typename PTD>
42 struct SIMDKernelBinder
47 template <
typename SI>
49 auto operator() (SI
const si)
const noexcept
51 return m_f(m_ptd, si);
118 class PC,
class F,
typename... Ps>
119 requires(IsParticleContainer<PC>::value)
124 static_assert(WIDTH >= 1,
"ParticleReduceSIMD: WIDTH must be at least 1");
125 static_assert((Reduce::detail::is_simd_reduce_op<Ps> && ...),
126 "ParticleReduceSIMD supports only ReduceOpSum, ReduceOpMin and "
129 RD reduce_data(reduce_ops);
130 for (
int lev = lev_min; lev <= lev_max; ++lev) {
131 const auto &plev = pc.GetParticles(lev);
134 for (
auto &kv : plev) {
135 grid_tile_ids.push_back(kv.first);
136 ptile_ptrs.push_back(&(kv.second));
141#if !defined(AMREX_USE_GPU) && defined(AMREX_USE_OMP)
142#pragma omp parallel for
144 for (
int pmap_it = 0; pmap_it < std::ssize(ptile_ptrs); ++pmap_it)
146 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
147 const auto np = tile.numParticles();
148 const auto& ptd = tile.getConstParticleTileData();
150 reduce_ops.
eval(np, reduce_data,
157 constexpr int EffWidth = WIDTH;
159 constexpr int EffWidth = 1;
161 using PTDType = std::decay_t<
decltype(ptd)>;
162 evalReduceSIMD<EffWidth>(np, reduce_data,
163 particle_detail::SIMDKernelBinder<F, PTDType>{f, ptd},
168 return reduce_data.value(reduce_ops);
185 class PC,
class F,
typename... Ps>
186 requires(IsParticleContainer<PC>::value)
189 return ParticleReduceSIMD<RD, WIDTH>(pc, lev, lev, f, reduce_ops);
205 class PC,
class F,
typename... Ps>
206 requires(IsParticleContainer<PC>::value)
209 return ParticleReduceSIMD<RD, WIDTH>(pc, 0, pc.finestLevel(), f, reduce_ops);
250requires (IsParticleContainer<PC>::value)
254 using ConstPTDType =
typename PC::ConstPTDType;
255 using T = std::decay_t<std::invoke_result_t<F, ConstPTDType const&, SIMDindex<1, int>>>;
257 auto r = ParticleReduceSIMD<ReduceData<T>, WIDTH>(
258 pc, lev_min, lev_max, particle_detail::SIMDTupleWrapper<F>{f}, reduce_ops);
259 return amrex::get<0>(r);
275requires (IsParticleContainer<PC>::value)
279 return ReduceSumSIMD<WIDTH>(pc, lev, lev, f);
294requires (IsParticleContainer<PC>::value)
298 return ReduceSumSIMD<WIDTH>(pc, 0, pc.finestLevel(), f);
321requires (IsParticleContainer<PC>::value)
325 using ConstPTDType =
typename PC::ConstPTDType;
326 using T = std::decay_t<std::invoke_result_t<F, ConstPTDType const&, SIMDindex<1, int>>>;
328 auto r = ParticleReduceSIMD<ReduceData<T>, WIDTH>(
329 pc, lev_min, lev_max, particle_detail::SIMDTupleWrapper<F>{f}, reduce_ops);
330 return amrex::get<0>(r);
345requires (IsParticleContainer<PC>::value)
349 return ReduceMinSIMD<WIDTH>(pc, lev, lev, f);
363requires (IsParticleContainer<PC>::value)
367 return ReduceMinSIMD<WIDTH>(pc, 0, pc.finestLevel(), f);
390requires (IsParticleContainer<PC>::value)
394 using ConstPTDType =
typename PC::ConstPTDType;
395 using T = std::decay_t<std::invoke_result_t<F, ConstPTDType const&, SIMDindex<1, int>>>;
397 auto r = ParticleReduceSIMD<ReduceData<T>, WIDTH>(
398 pc, lev_min, lev_max, particle_detail::SIMDTupleWrapper<F>{f}, reduce_ops);
399 return amrex::get<0>(r);
414requires (IsParticleContainer<PC>::value)
418 return ReduceMaxSIMD<WIDTH>(pc, lev, lev, f);
432requires (IsParticleContainer<PC>::value)
436 return ReduceMaxSIMD<WIDTH>(pc, 0, pc.finestLevel(), f);
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Definition AMReX_Reduce.H:597
void eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:731
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
constexpr auto native_simd_size_particlereal
Definition AMReX_SIMD.H:221
Definition AMReX_Amr.cpp:50
auto ReduceMaxSIMD(PC const &pc, int lev_min, int lev_max, F const &f)
A SIMD-vectorized max reduction over the particles in a ParticleContainer. This version operates from...
Definition AMReX_ParticleReduceSIMD.H:392
__host__ __device__ constexpr GpuTuple< detail::tuple_decay_t< Ts >... > makeTuple(Ts &&... args)
Definition AMReX_Tuple.H:269
auto ReduceMinSIMD(PC const &pc, int lev_min, int lev_max, F const &f)
A SIMD-vectorized min reduction over the particles in a ParticleContainer. This version operates from...
Definition AMReX_ParticleReduceSIMD.H:323
auto ReduceSumSIMD(PC const &pc, int lev_min, int lev_max, F const &f)
A SIMD-vectorized sum reduction over the particles in a ParticleContainer. This version operates from...
Definition AMReX_ParticleReduceSIMD.H:252
RD::Type ParticleReduceSIMD(PC const &pc, int lev_min, int lev_max, F const &f, ReduceOps< Ps... > &reduce_ops)
A general SIMD-vectorized reduction method for the particles in a ParticleContainer....
Definition AMReX_ParticleReduceSIMD.H:120
Definition AMReX_GpuLaunchFunctsSIMD.H:24