Namespace for SIMD-decorated loops over SoA particles (particle analogue of BoxLoops).
More...
|
| template<typename P , typename Traits , typename Functor > |
| ALWAYS_INLINE void | loop (const ParticleSoA< P, Traits > &a_soa, Functor &&a_kernel) |
| | Launch a kernel over every particle in a ParticleSoA, decorating the loop with CD_PRAGMA_SIMD.
|
| |
| template<typename P , typename Traits , typename T , typename Functor > |
| ALWAYS_INLINE T | reduce (const ParticleSoA< P, Traits > &a_soa, T a_initial, Functor &&a_kernel) |
| | Fold a kernel over every particle in a ParticleSoA, accumulating a reduction value.
|
| |
Namespace for SIMD-decorated loops over SoA particles (particle analogue of BoxLoops).
◆ loop()
template<typename P , typename Traits , typename Functor >
| ALWAYS_INLINE void ParticleLoops::loop |
( |
const ParticleSoA< P, Traits > & |
a_soa, |
|
|
Functor && |
a_kernel |
|
) |
| |
Launch a kernel over every particle in a ParticleSoA, decorating the loop with CD_PRAGMA_SIMD.
The kernel is invoked as a_kernel(i) for each particle index i in [0, a_soa.size()). The trip count is taken from the container, so it always matches the columns the kernel captured from the same container – there is intentionally no bare-count overload to pass the wrong size to. Force-inlined so the kernel body fuses into the vectorizable loop.
- Note
- a_soa is taken by const reference because loop() itself only reads a_soa.size() – it never touches particle data. Whether the kernel may WRITE columns is governed entirely by how the caller captured the column pointers: column()/positionColumn()/weightColumn() return mutable pointers from a non-const container and read-only pointers from a const one. This mirrors BoxLoops::loop(const Box&, ...), where the iteration domain is const and the kernel mutates separately-captured FArrayBox data.
- Template Parameters
-
| P | Payload type of the ParticleSoA. |
| Traits | Column descriptor for the payload. |
| Functor | Callable type taking a std::size_t particle index. |
- Parameters
-
| [in] | a_soa | Particle container to iterate over (read for its size only). |
| [in,out] | a_kernel | Callable taking a std::size_t particle index. |
◆ reduce()
template<typename P , typename Traits , typename T , typename Functor >
| ALWAYS_INLINE T ParticleLoops::reduce |
( |
const ParticleSoA< P, Traits > & |
a_soa, |
|
|
T |
a_initial, |
|
|
Functor && |
a_kernel |
|
) |
| |
Fold a kernel over every particle in a ParticleSoA, accumulating a reduction value.
The accumulator is threaded sequentially through the particles: for each particle index i in [0, a_soa.size()) the accumulator is updated as acc = a_kernel(acc, i), and the final value is returned. This is the reduction analogue of loop(): because CD_PRAGMA_SIMD (ivdep) does not guarantee a correct floating-point reduction, this loop is intentionally a plain sequential fold with NO SIMD decoration. As with loop(), capture the column pointers ONCE before the call and read them by index inside the kernel – do not call a_soa.column<>() inside the kernel, and do not mutate the container's structure (append/remove/resize).
- Note
- Sequential and order-deterministic, so it is correct for non-associative reductions (e.g. floating-point sums where bitwise reproducibility matters) as well as min/max. The trip count is taken from the container so it always matches the columns the kernel captured from it.
- Template Parameters
-
| P | Payload type of the ParticleSoA. |
| Traits | Column descriptor for the payload. |
| T | Accumulator type. |
| Functor | Callable type taking (T accumulator, std::size_t particle index) and returning T. |
- Parameters
-
| [in] | a_soa | Particle container to iterate over (read for its size only). |
| [in] | a_initial | Initial accumulator value. |
| [in,out] | a_kernel | Callable taking (T accumulator, std::size_t particle index) and returning the updated accumulator. |
- Returns
- The accumulator after folding over every particle.