Skip to content

Commit a7f0aed

Browse files
atmyersax3lasalmgrenWeiqunZhang
authored
Add section on pure SoA particles to documentation (#4759)
The proposed changes: - [ ] fix a bug or incorrect behavior in AMReX - [ ] add new capabilities to AMReX - [ ] changes answers in the test suite to more than roundoff level - [ ] are likely to significantly affect the results of downstream AMReX users - [x] include documentation in the code and/or rst files, if appropriate --------- Co-authored-by: Axel Huebl <[email protected]> Co-authored-by: Ann Almgren <[email protected]> Co-authored-by: Weiqun Zhang <[email protected]>
1 parent b9a78a3 commit a7f0aed

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

Docs/sphinx_documentation/source/Particle.rst

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -152,24 +152,15 @@ See the figure :ref:`below<fig:particles:particle_arrays>` for an illustration.
152152

153153
\end{center}
154154

155-
To see why the distinction between AoS and SoA data is important, consider the
156-
following extreme case. Say you have particles that carry 100 different
157-
components, but that most of the time, you only need to do calculations
158-
involving 3 of them (say, the particle positions) at once. In this case,
159-
storing all 100 particle variables in the particle struct is clearly
160-
inefficient, since most of the time you are reading 97 extra variables into
161-
cache that you will never use. By splitting up the particle variables into
162-
stuff that gets used all the time (stored in the AoS) and stuff that only gets
163-
used infrequently (stored in the SoA), you can in principle achieve much better
164-
cache reuse. Of course, the usage pattern of your application likely won't be
165-
so clear-cut. Flexibility in how the particle data is stored also makes it
166-
easier to interface between AMReX and already-existing Fortran subroutines.
167-
168-
Note that while "extra" particle data can be stored in either the SoA or AoS
169-
style, the particle positions and id numbers are **always** stored in the
170-
particle structs. This is because these particle variables are special and used
171-
internally by AMReX to assign the particles to grids and to mark particles as
172-
valid or invalid, respectively.
155+
.. attention::
156+
157+
The ability to store particle data in AoS form is provided for backward
158+
compatibility and convenience; however, for performance reasons, whether
159+
targeting CPU or GPU execution, we recommend storing extra particle variables in SoA form.
160+
Additionally, starting in AMReX version 23.05, the ability to store *all* particle
161+
data, including the particle positions and `idcpu` numbers, is provided via the
162+
:cpp:`amrex::ParticleContainerPureSoA` class. Details on using pure SoA particles
163+
are provided in the Section on :ref:`sec:Particles:PureSoA`.
173164

174165
Constructing ParticleContainers
175166
-------------------------------
@@ -466,6 +457,41 @@ on whether ``USE_SINGLE_PRECISION_PARTICLES`` is ``TRUE`` or not. We recommend
466457
always using this type in Fortran routines that work on particle data to avoid
467458
hard-to-debug incompatibilities between floating point types.
468459

460+
.. _sec:Particles:PureSoA:
461+
462+
Pure Struct-of-Array Particles
463+
------------------------------
464+
465+
Beginning with AMReX version 24.05, the requirement that the particle positions
466+
and ids be stored in AoS form has been lifted. Users can now use the class
467+
:cpp:`amrex::ParticleContainerPureSoA`, which stores all components in SoA form.
468+
When using data layout, it is assumed that the first :cpp:`AMREX_SPACEDIM` :cpp:`Real`
469+
components store the particle position variables, which are used internally to map
470+
particle coordinates to grids and cells.
471+
472+
For the most part, functions that work on the standard :cpp:`ParticleContainer` will
473+
also work on :cpp:`ParticleContainerPureSoA`. :cpp:`ParticleTile` can be used to access
474+
the underlying :cpp:`StructOfArrays`, which can be used as before. However, it is
475+
particlularly convenient to use the :cpp:`[]` operator of :cpp:`ParticleTileData`, which
476+
allows the same code to work with both AoS and pure SoA particles. For example, within
477+
a ``ParIter`` loop, one can do:
478+
479+
.. highlight:: c++
480+
481+
::
482+
483+
// Iterating over SoA Particles
484+
ParticleTileDataType ptd = pti.GetParticleTile().getParticleTileData();
485+
486+
ParallelFor( np, [=] AMREX_GPU_DEVICE (long ip)
487+
{
488+
ParticleType p = ptd[ip]; // p will be a different type for AoS and pure SoA
489+
// use p.pos(0), p.id(), etc.
490+
}
491+
492+
In this way, code can be written that is agnostic as to the data layout. For more examples
493+
of pure SoA particles, please see the SOA tests in :cpp:`amrex/Tests/Particles/`, or refer
494+
to `WarpX <https://github.com/BLAST-WarpX/warpx>`_, `Hipace++ <https://github.com/Hi-PACE/hipace>`_, or `ImpactX <https://github.com/BLAST-ImpactX/impactx>`_, which use this type of particle container.
469495

470496
.. _sec:Particles:Interacting:
471497

0 commit comments

Comments
 (0)