SpECTRE
v2025.03.17
|
Holds the data in the different directions for the nodegroup DgElementArray
implementation.
More...
#include <AtomicInboxBoundaryData.hpp>
Public Types | |
using | stored_type = evolution::dg::BoundaryData< Dim > |
Public Member Functions | |
AtomicInboxBoundaryData (const AtomicInboxBoundaryData &)=delete | |
AtomicInboxBoundaryData & | operator= (const AtomicInboxBoundaryData &)=delete |
AtomicInboxBoundaryData (AtomicInboxBoundaryData &&rhs) noexcept | |
AtomicInboxBoundaryData & | operator= (AtomicInboxBoundaryData &&) noexcept=delete |
void | pup (PUP::er &p) |
Static Public Member Functions | |
static size_t | index (const DirectionalId< Dim > &directional_id) |
Public Attributes | |
std::array< Parallel::StaticSpscQueue< std::tuple<::TimeStepId, stored_type, DirectionalId< Dim > >, 20 >, maximum_number_of_neighbors(Dim)> | boundary_data_in_directions {} |
std::atomic_uint | message_count {} |
std::atomic_uint | number_of_neighbors {} |
Holds the data in the different directions for the nodegroup DgElementArray
implementation.
The reason for this class is to reduce contention between cores and to allow the use of a Single-Producer-Single-Consumer (SPSC) queue instead of an MPMC queue. This has significant performance improvements since it drastically reduces contention.
The uint message counter is used to count how many neighbors have contributed for the next time. This is used to delay calling perform_algorithm()
in order to reduce the number of messages we send through the runtime system. The number_of_neighbors
is used to track the number of expected messages. Note that some additional logic is needed also for supporting local time stepping, since not every message entry "counts" since it depends on the time level of neighboring elements.
AtomicInboxBoundaryData
with zero messages can be move constructed. A non-zero number of neighbors is allowed. This is necessary in order to be able to serialize a std::unordered_map<Key,AtomicInboxBoundaryData>
.
|
static |
Computes the 1d index into the boundary_data_in_directions
array for a specific directional_id
that has been re-oriented using the OrientationMap
to be put in the same block frame as the element that is receiving the data (i.e. that whose inbox this is being inserted into).
The hash is computed as
where SegmentId
's of the neighbor's ElementId
for the dimensions other than SegmentId
index along the face is even (odd); and for SegmentId
indices along the face are both even (lower dim odd, higher dim odd, both dims odd). The element segment hash is computed as the logical and
of the SegmentID
's index in that direction, left shifted by which direction on the face it is.