ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
GhostComm Namespace Reference

Namespaces

namespace  anonymous_namespace{HaloExchange.cpp}
 

Classes

struct  CollectiveSection
 
class  CommBuf
 Class that stores marshalled data for ghost communications. More...
 
struct  ExchangeBuffers
 Persistent per-neighbor buffer pool for halo exchanges. More...
 
struct  ExchangeOp
 
struct  GhostExchange
 Opaque handle for one in-flight halo exchange. More...
 
struct  HaloPlan
 
struct  LocalComm
 
struct  NeighborComm
 
struct  SendRegion
 
class  SerializationSizeCalculator
 Pseudo-archive to calculate the size of the serialization buffer. More...
 

Enumerations

enum class  Direction { Push , Reduce }
 
enum class  Combine { Overwrite , Add }
 
enum class  CollectivePattern { None , Broadcast , ReduceSum }
 
enum class  ReductionPolicy { MOVE , UPDATE }
 Type of reduction to carry out during serialization. More...
 
enum class  SerializationDirection { SAVE , LOAD }
 Whether to save the state to or load the state from the archive. More...
 

Functions

GhostExchange halo_exchange_start (HaloPlan const &plan, BoxGeometry const &box, unsigned data_parts, ExchangeOp op, ExchangeBuffers &bufs)
 Begin a halo exchange using a caller-owned buffer pool.
 
GhostExchange halo_exchange_start (HaloPlan const &plan, BoxGeometry const &box, unsigned data_parts, ExchangeOp op)
 Convenience overload that allocates a temporary ExchangeBuffers.
 
void halo_exchange_finish (GhostExchange &state)
 Complete a halo exchange: run same-rank copies (overlapping the in-flight messages), wait for all requests, then unpack or reduce.
 
void halo_exchange (HaloPlan const &plan, BoxGeometry const &box, unsigned data_parts, ExchangeOp op, ExchangeBuffers &bufs)
 Blocking wrapper using a caller-owned buffer pool (no per-call alloc after warm-up).
 
void halo_exchange (HaloPlan const &plan, BoxGeometry const &box, unsigned data_parts, ExchangeOp op)
 Blocking convenience wrapper: start + finish (allocates a temporary ExchangeBuffers; use the pool overload on hot paths).
 
std::vector< std::string > validate_halo_plan (HaloPlan const &plan, std::span< Cell *const > local_cells, std::span< Cell *const > ghost_cells)
 Validate a HaloPlan for correctness.
 
std::vector< std::string > validate_halo_plan_symmetry (HaloPlan const &plan)
 Cross-rank symmetry check for a HaloPlan.
 
bool report_violations (std::vector< std::string > const &violations, char const *context)
 Print violations to stderr and return whether the list was empty.
 
void mark_boundary_cells (std::span< Cell *const > local_cells, std::span< Cell *const > ghost_cells, std::function< bool(Cell const *, Cell const *)> wrap_predicate=nullptr)
 Classify each local cell as interior or boundary.
 
void mark_plan_cells_boundary (HaloPlan const &plan, std::span< Cell *const > local_cells)
 Mark plan-exported local cells as boundary (source 2, see mark_boundary_cells).
 
template<class Archive >
static void serialize_and_reduce (Archive &ar, Particle &p, unsigned int data_parts, ReductionPolicy policy, SerializationDirection direction, BoxGeometry const &box_geo, Utils::Vector3d const *ghost_shift)
 Serialize particle data, possibly with reduction.
 
static void prepare_ghost_cell (ParticleList *cell, std::size_t size)
 
std::size_t calc_transmit_size (BoxGeometry const &box_geo, unsigned data_parts)
 Calculate the per-particle transmit size for the given data parts.
 
std::size_t calc_transmit_size (std::span< ParticleList *const > cells, BoxGeometry const &box_geo, unsigned data_parts)
 Calculate the total transmit size for a list of cells and data parts.
 
void pack_cells (CommBuf &buf, std::span< ParticleList *const > cells, Utils::Vector3d const &shift, BoxGeometry const &box_geo, unsigned data_parts)
 Pack particle data from cells into a communication buffer.
 
void unpack_cells (CommBuf &buf, std::span< ParticleList *const > cells, BoxGeometry const &box_geo, unsigned data_parts)
 Unpack particle data from a communication buffer into cells.
 
void add_forces (CommBuf &buf, std::span< ParticleList *const > cells, unsigned data_parts)
 Add forces (and optionally torques) from a communication buffer to particles in cells.
 
void add_rattle (CommBuf &buf, std::span< ParticleList *const > cells)
 Add rattle corrections from a communication buffer to particles.
 
void add_dip_fld (CommBuf &buf, std::span< ParticleList *const > cells)
 Add dipole fields from a communication buffer to particles.
 
void local_cell_copy (ParticleList &src, ParticleList &dst, Utils::Vector3d const &shift, BoxGeometry const &box_geo, unsigned data_parts)
 Copy particle data from src to dst applying a ghost shift.
 

Enumeration Type Documentation

◆ CollectivePattern

enum class GhostComm::CollectivePattern
strong
Enumerator
None 
Broadcast 
ReduceSum 

Definition at line 53 of file HaloPlan.hpp.

◆ Combine

enum class GhostComm::Combine
strong
Enumerator
Overwrite 
Add 

Definition at line 32 of file HaloPlan.hpp.

◆ Direction

enum class GhostComm::Direction
strong
Enumerator
Push 
Reduce 

Definition at line 31 of file HaloPlan.hpp.

◆ ReductionPolicy

enum class GhostComm::ReductionPolicy
strong

Type of reduction to carry out during serialization.

Enumerator
MOVE 

Reduction for domain-to-domain particle communication.

UPDATE 

Reduction for cell-to-cell particle update.

Definition at line 67 of file particle_packing.cpp.

◆ SerializationDirection

Whether to save the state to or load the state from the archive.

Enumerator
SAVE 
LOAD 

Definition at line 75 of file particle_packing.cpp.

Function Documentation

◆ add_dip_fld()

void GhostComm::add_dip_fld ( CommBuf buf,
std::span< ParticleList *const >  cells 
)

Add dipole fields from a communication buffer to particles.

Definition at line 349 of file particle_packing.cpp.

References GhostComm::CommBuf::make_span().

Referenced by halo_exchange_finish().

◆ add_forces()

void GhostComm::add_forces ( CommBuf buf,
std::span< ParticleList *const >  cells,
unsigned  data_parts 
)

Add forces (and optionally torques) from a communication buffer to particles in cells.

Parameters
bufBuffer produced by a force-reduce exchange.
cellsDestination (owned) particle lists.
data_partsBitmask of GHOSTTRANS_* flags; must include GHOSTTRANS_FORCE, may include GHOSTTRANS_TORQUE.

Definition at line 312 of file particle_packing.cpp.

References GHOSTTRANS_FORCE, GHOSTTRANS_TORQUE, and GhostComm::CommBuf::make_span().

Referenced by halo_exchange_finish().

◆ add_rattle()

void GhostComm::add_rattle ( CommBuf buf,
std::span< ParticleList *const >  cells 
)

Add rattle corrections from a communication buffer to particles.

Definition at line 335 of file particle_packing.cpp.

References GhostComm::CommBuf::make_span().

Referenced by halo_exchange_finish().

◆ calc_transmit_size() [1/2]

std::size_t GhostComm::calc_transmit_size ( BoxGeometry const &  box_geo,
unsigned  data_parts 
)

◆ calc_transmit_size() [2/2]

std::size_t GhostComm::calc_transmit_size ( std::span< ParticleList *const >  cells,
BoxGeometry const &  box_geo,
unsigned  data_parts 
)

Calculate the total transmit size for a list of cells and data parts.

When GHOSTTRANS_PARTNUM is set, returns sizeof(unsigned int) per cell. Otherwise returns the total number of particles times the per-particle size.

Definition at line 227 of file particle_packing.cpp.

References calc_transmit_size(), and GHOSTTRANS_PARTNUM.

◆ halo_exchange() [1/2]

void GhostComm::halo_exchange ( HaloPlan const &  plan,
BoxGeometry const &  box,
unsigned  data_parts,
ExchangeOp  op 
)

Blocking convenience wrapper: start + finish (allocates a temporary ExchangeBuffers; use the pool overload on hot paths).

Definition at line 640 of file HaloExchange.cpp.

References halo_exchange_finish(), and halo_exchange_start().

◆ halo_exchange() [2/2]

void GhostComm::halo_exchange ( HaloPlan const &  plan,
BoxGeometry const &  box,
unsigned  data_parts,
ExchangeOp  op,
ExchangeBuffers bufs 
)

◆ halo_exchange_finish()

◆ halo_exchange_start() [1/2]

GhostExchange GhostComm::halo_exchange_start ( HaloPlan const &  plan,
BoxGeometry const &  box,
unsigned  data_parts,
ExchangeOp  op 
)

Convenience overload that allocates a temporary ExchangeBuffers.

Use this form when buffer reuse across calls is not needed (e.g. unit tests, cold resort paths). Equivalent to the original single-call allocation.

Definition at line 423 of file HaloExchange.cpp.

References halo_exchange_start().

◆ halo_exchange_start() [2/2]

GhostExchange GhostComm::halo_exchange_start ( HaloPlan const &  plan,
BoxGeometry const &  box,
unsigned  data_parts,
ExchangeOp  op,
ExchangeBuffers bufs 
)

Begin a halo exchange using a caller-owned buffer pool.

The buffers in bufs are resized to the current neighbor count (retaining capacity) so that, after the first call (warm-up), no heap allocation occurs on the POSITION / FORCE hot path.

Parameters
planCommunication plan (peers, regions, local copies).
boxBox geometry for position folding.
data_partsBitmask of GHOSTTRANS_* flags to transfer.
opDirection (Push/Reduce) and combine mode (Overwrite/Add).
bufsPersistent buffer pool (must outlive the returned handle).
Precondition
Each peer rank appears at most once in plan.neighbors. Multiple send/receive regions to the same peer must be folded into that peer's single NeighborComm (as the plan builders do). This is what makes the (peer, data-part tag) message matching unambiguous: without this invariant two NeighborComm entries sharing the same peer and tag would cross-match, silently corrupting data or deadlocking. The plan builders (e.g. RegularDecomposition) always produce unique peers; the invariant is asserted at runtime when ESPRESSO_ADDITIONAL_CHECKS is defined.

Definition at line 234 of file HaloExchange.cpp.

References Add, GhostComm::GhostExchange::box, GhostComm::GhostExchange::bufs, calc_transmit_size(), GhostComm::ExchangeOp::combine, GhostComm::HaloPlan::comm, GhostComm::GhostExchange::data_parts, GhostComm::ExchangeOp::direction, espresso_cali_active(), GHOSTTRANS_BONDS, GHOSTTRANS_DIPFLD, GHOSTTRANS_FORCE, GHOSTTRANS_NONE, GHOSTTRANS_RATTLE, GHOSTTRANS_TORQUE, GhostComm::HaloPlan::local, local_cell_copy(), GhostComm::HaloPlan::neighbors, GhostComm::GhostExchange::op, pack_cells(), GhostComm::GhostExchange::plan, Push, GhostComm::ExchangeBuffers::recv, GhostComm::ExchangeBuffers::recv_cells, report_violations(), GhostComm::ExchangeBuffers::requests, GhostComm::ExchangeBuffers::send, GhostComm::ExchangeBuffers::send_cells, GhostComm::ExchangeBuffers::slot_to_neighbor, GhostComm::HaloPlan::symmetry_validated, and validate_halo_plan_symmetry().

Referenced by CellStructure::ghosts_reduce_forces_start(), halo_exchange(), halo_exchange(), and halo_exchange_start().

◆ local_cell_copy()

void GhostComm::local_cell_copy ( ParticleList src,
ParticleList dst,
Utils::Vector3d const &  shift,
BoxGeometry const &  box_geo,
unsigned  data_parts 
)

Copy particle data from src to dst applying a ghost shift.

For GHOSTTRANS_PARTNUM, resizes dst to match src. Otherwise serializes each particle from src and deserializes into dst, applying the shift and folding the position. Bond data is copied directly.

Parameters
srcSource particle list.
dstDestination particle list.
shiftGhost shift to apply.
box_geoBox geometry for fold_position.
data_partsBitmask of GHOSTTRANS_* flags.

Definition at line 361 of file particle_packing.cpp.

References Utils::Bag< T >::begin(), calc_transmit_size(), GHOSTTRANS_BONDS, GHOSTTRANS_PARTNUM, LOAD, GhostComm::CommBuf::make_span(), prepare_ghost_cell(), GhostComm::CommBuf::resize(), SAVE, serialize_and_reduce(), Utils::Bag< T >::size(), and UPDATE.

Referenced by halo_exchange_start().

◆ mark_boundary_cells()

void GhostComm::mark_boundary_cells ( std::span< Cell *const >  local_cells,
std::span< Cell *const >  ghost_cells,
std::function< bool(Cell const *, Cell const *)>  wrap_predicate = nullptr 
)
inline

Classify each local cell as interior or boundary.

A local cell is boundary for two independent reasons:

Source 1 — geometric wrap rules: the cell has a ghost neighbor (rule a) or participates in a periodic wrap-around neighborship on a single MPI rank (rule b, captured by the optional wrap_predicate). These rules serve future Euclidean-distance uses: wrap-neighborship must mark a cell boundary even when it is not exported by the current plan.

Source 2 — plan membership: the cell appears as a send source in any NeighborComm or as a LocalComm src. Plans for geometries such as Lees-Edwards fully-connected boundaries and ELC periodicity-change paths can export cells that the geometric rules never see. Those cells must still be boundary so that the integrator step-2 / force-reduce overlap does not update their velocities before remote force contributions arrive.

Both sources are complementary: keep both to satisfy present and future callers. mark_plan_cells_boundary applies source 2.

All other local cells are interior.

The function first resets every local cell to interior (idempotent on repeated calls / plan rebuild), then marks boundary cells.

Call this right after m_halo_plan = make_halo_plan() in each decomposition, where local_cells() and ghost_cells() are already populated.

Parameters
local_cellsLocal cell pointer span.
ghost_cellsGhost cell pointer span.
wrap_predicateOptional predicate (Cell const *a, Cell const *b) -> bool that returns true when the neighbor relation a->b crosses a periodic box boundary (both cells are local). When omitted, no additional wrapping boundary is detected.

Definition at line 70 of file mark_boundary_cells.hpp.

Referenced by AtomDecomposition::AtomDecomposition(), HybridDecomposition::HybridDecomposition(), and RegularDecomposition::RegularDecomposition().

◆ mark_plan_cells_boundary()

void GhostComm::mark_plan_cells_boundary ( HaloPlan const &  plan,
std::span< Cell *const >  local_cells 
)
inline

Mark plan-exported local cells as boundary (source 2, see mark_boundary_cells).

Iterates the halo plan and marks every local cell that appears as a send source. Specifically: every NeighborComm::send[k].cell and every LocalComm::src. Recv/dst targets are ghost cells by construction and are not touched.

Call this immediately after mark_boundary_cells so that the combined invariant "interior ⇒ not exported by the plan" holds for any plan shape.

Parameters
planThe halo plan produced by make_halo_plan().
local_cellsLocal cell pointer span (used to build the ParticleList -> Cell reverse map in O(n)).

Definition at line 114 of file mark_boundary_cells.hpp.

References GhostComm::HaloPlan::local, and GhostComm::HaloPlan::neighbors.

Referenced by RegularDecomposition::RegularDecomposition().

◆ pack_cells()

void GhostComm::pack_cells ( CommBuf buf,
std::span< ParticleList *const >  cells,
Utils::Vector3d const &  shift,
BoxGeometry const &  box_geo,
unsigned  data_parts 
)

Pack particle data from cells into a communication buffer.

Handles GHOSTTRANS_PARTNUM (writes cell sizes) and GHOSTTRANS_BONDS (separate bond buffer) special cases.

Parameters
bufBuffer to pack into (resized as needed).
cellsSource particle lists.
shiftGhost shift applied to particle positions on save.
box_geoBox geometry for fold_position.
data_partsBitmask of GHOSTTRANS_* flags.

Definition at line 240 of file particle_packing.cpp.

References GhostComm::CommBuf::bonds(), calc_transmit_size(), GHOSTTRANS_BONDS, GHOSTTRANS_PARTNUM, GhostComm::CommBuf::make_span(), MOVE, GhostComm::CommBuf::resize(), SAVE, serialize_and_reduce(), and GhostComm::CommBuf::size().

Referenced by halo_exchange_start(), GhostComm::anonymous_namespace{HaloExchange.cpp}::pack_regions(), and GhostComm::anonymous_namespace{HaloExchange.cpp}::run_collective().

◆ prepare_ghost_cell()

static void GhostComm::prepare_ghost_cell ( ParticleList cell,
std::size_t  size 
)
static

Definition at line 208 of file particle_packing.cpp.

References Utils::Bag< T >::resize().

Referenced by local_cell_copy(), and unpack_cells().

◆ report_violations()

bool GhostComm::report_violations ( std::vector< std::string > const &  violations,
char const *  context 
)

Print violations to stderr and return whether the list was empty.

Intended for use inside assert(): a bare assert(validate_halo_plan(...).empty()) aborts without showing WHICH invariant failed, which makes CI failures undebuggable. Wrap the call: assert(GhostComm::report_violations(validate_halo_plan(...), "context")).

Definition at line 259 of file HaloPlanValidator.cpp.

Referenced by AtomDecomposition::AtomDecomposition(), halo_exchange_start(), HybridDecomposition::HybridDecomposition(), and RegularDecomposition::RegularDecomposition().

◆ serialize_and_reduce()

template<class Archive >
static void GhostComm::serialize_and_reduce ( Archive &  ar,
Particle p,
unsigned int  data_parts,
ReductionPolicy  policy,
SerializationDirection  direction,
BoxGeometry const &  box_geo,
Utils::Vector3d const *  ghost_shift 
)
static

◆ unpack_cells()

void GhostComm::unpack_cells ( CommBuf buf,
std::span< ParticleList *const >  cells,
BoxGeometry const &  box_geo,
unsigned  data_parts 
)

Unpack particle data from a communication buffer into cells.

Handles GHOSTTRANS_PARTNUM (resizes ghost cells) and GHOSTTRANS_BONDS (separate bond buffer) special cases.

Parameters
bufBuffer to unpack from.
cellsDestination particle lists.
box_geoBox geometry (unused here, kept for API symmetry).
data_partsBitmask of GHOSTTRANS_* flags.

Definition at line 275 of file particle_packing.cpp.

References GhostComm::CommBuf::bonds(), GHOSTTRANS_BONDS, GHOSTTRANS_PARTNUM, LOAD, GhostComm::CommBuf::make_span(), MOVE, prepare_ghost_cell(), serialize_and_reduce(), and GhostComm::CommBuf::size().

Referenced by halo_exchange_finish(), and GhostComm::anonymous_namespace{HaloExchange.cpp}::run_collective().

◆ validate_halo_plan()

std::vector< std::string > GhostComm::validate_halo_plan ( HaloPlan const &  plan,
std::span< Cell *const >  local_cells,
std::span< Cell *const >  ghost_cells 
)

Validate a HaloPlan for correctness.

Checks:

  1. Coverage: every ghost cell that a local cell references is filled. Point-to-point ghosts appear as a recv/local.dst target exactly once; no p2p target lies outside the ghost set; none appears twice. Ghosts filled by the collective broadcast/reduce section (AtomDecomposition, HybridDecomposition) are covered by that section instead of a recv/dst target. A ghost that no local cell references (e.g. the halo-layer cells on a single MPI rank, where the plan is intentionally empty) carries no physics and is not required to be filled.
  2. Neighborship-match: every local cell's ghost neighbor is covered, either as a recv/dst target or by the collective section.
  3. Peer-uniqueness: each peer value appears in at most one NeighborComm.
  4. Shape: each NeighborComm has send.size() == recv.size().
  5. Interior/boundary consistency: a cell marked interior has no ghost neighbor (enforced by mark_boundary_cells()).
  6. Overlap-safety invariant: an interior cell must not appear as a NeighborComm send source or a LocalComm src. This is the exact precondition that the integrator step-2 / force-reduce overlap (Task 5.3) relies on: interior cells receive no reduce contributions and therefore do not require the reduce to complete before their velocity is updated. LocalComm.dst and NeighborComm.recv are ghost cells by construction (guaranteed by the dst-in-ghost-set coverage check #1), so they are not checked here.
Returns
a human-readable violation string per problem; empty = valid.

Definition at line 36 of file HaloPlanValidator.cpp.

References GhostComm::HaloPlan::collective, Utils::Bag< T >::insert(), GhostComm::HaloPlan::local, GhostComm::HaloPlan::neighbors, and None.

Referenced by AtomDecomposition::AtomDecomposition(), HybridDecomposition::HybridDecomposition(), and RegularDecomposition::RegularDecomposition().

◆ validate_halo_plan_symmetry()

std::vector< std::string > GhostComm::validate_halo_plan_symmetry ( HaloPlan const &  plan)

Cross-rank symmetry check for a HaloPlan.

Uses a collective all-to-all exchange of per-rank send-counts so that every rank participates regardless of whether the neighbor sets are symmetric. This avoids the deadlock that a naive per-neighbor isend/irecv pattern would cause when a rank sends to a peer that has no matching recv posted.

Invariant: for every peer P, my recv-count from P must equal P's send-count to me (i.e. my_recv_from[P] == peers_send_to_me[P]).

Returns
a human-readable violation string per mismatch; empty = valid.

Definition at line 224 of file HaloPlanValidator.cpp.

References GhostComm::HaloPlan::comm, and GhostComm::HaloPlan::neighbors.

Referenced by halo_exchange_start().