|
Neko 1.99.5
A portable framework for high-order spectral element flow simulations
|
Crystal router: scalable all-to-some personalized exchange. More...
Functions/Subroutines | |
| subroutine, public | crystal_router_pack (out, dest, body) |
| Append one record to a packed crystal-router buffer. | |
| subroutine, public | crystal_router_transfer (buf, n) |
| Route packed records to their destination ranks. | |
| subroutine | cr_check_dest (buf, n) |
| Abort if any record destination falls outside \( [0, P) \). | |
| subroutine | cr_partition (buf, n, mid, lower, keep, nkeep, snd, nsnd) |
| Partition buf into records kept locally and records to be sent. A record is kept when the side of its destination (relative to mid) matches lower, i.e. it already belongs to our half. | |
| subroutine | cr_exchange (sbuf, sn, dst, rbuf, rn, src) |
Size-negotiated bidirectional exchange with a partner. Either dst or src may be MPI_PROC_NULL to make that direction a no-op. | |
| subroutine | cr_concat (buf, n, a, na, b, nb) |
| Rebuild buf as the concatenation a(1:na) ++ b(1:nb). | |
| subroutine | cr_append (buf, n, e, ne) |
| Append e(1:ne) to buf(1:n) in place. | |
Variables | |
| integer, parameter | cr_tag = 0 |
Message tag used for all crystal-router exchanges. Stages are fully synchronised (blocking MPI_Sendrecv), so a single tag suffices. | |
Routes a set of variable-length records, each tagged with a destination rank, from any source to any destination in \( \lceil \log_2 P \rceil \) communication stages. This replaces dense \( O(P) \)-round neighbour discovery / personalized exchange (which is \( O(P^2) \) globally and, under flat MPI at high rank counts, exhausts the MPI runtime's internal unexpected-message buffers) with a recursive-bisection routing that talks to at most one or two partners per stage.
Records are passed in a single packed integer(i8) buffer as a sequence of self-describing entries
[ dest, len, payload(1), ..., payload(len) ]
where dest is the destination rank in \( [0, P) \) and len is the payload length. On return the buffer holds exactly the records whose dest equals pe_rank, in the same packed format (the dest/len headers are preserved so the caller can unpack uniformly).
The active rank range [lo, hi) always contains pe_rank; it starts as [0, P) and is halved each stage at mid = lo + (hi-lo)/2. A record is kept if its destination lies in the local half and otherwise shipped to a partner in the opposite half. Since a record is always moved into the half containing its destination, the range invariant "`dest in [lo, hi)`" is preserved, and when the range collapses to a single rank that rank is the destination – so every record is delivered exactly once and none is dropped.
For odd-sized ranges the upper half has exactly one more rank than the lower half, leaving one unpaired upper rank (hi-1). That rank still holds records destined for the lower half; it offloads them to rank lo, which performs one extra receive. All other ranks exchange with a single partner via MPI_Sendrecv, and the unpaired transfers use MPI_PROC_NULL for the idle direction, so every stage is fully matched and deadlock-free for any P (not only powers of two). Message sizes are negotiated per stage (a one-integer count exchange precedes each data exchange), so no global maximum buffer is ever allocated.
|
private |
|
private |
| subroutine, public crystal_router::crystal_router_pack | ( | type(stack_i8_t), intent(inout) | out, |
| integer, intent(in) | dest, | ||
| integer(i8), dimension(:), intent(in) | body | ||
| ) |
Writes the self-describing entry [dest, size(body), body...] that crystal_router_transfer consumes. Owning the record format here means call sites only supply a destination rank and a payload, and never encode the [dest, len, ...] envelope themselves.
| out | Stack accumulating the packed records. |
| dest | Destination rank for this record, in \( [0, P) \). |
| body | The record payload (its length becomes the len field). |
Definition at line 98 of file crystal_router.f90.

| subroutine, public crystal_router::crystal_router_transfer | ( | integer(i8), dimension(:), intent(inout), allocatable | buf, |
| integer, intent(inout) | n | ||
| ) |
| buf | Packed records [dest, len, payload...] repeated. On entry, arbitrary destinations in \( [0, P) \); on exit, only the records addressed to pe_rank (may be reallocated). |
| n | Used length of buf (number of integer(i8) words). Updated on exit to the length of the received set. |
Definition at line 121 of file crystal_router.f90.


Definition at line 84 of file crystal_router.f90.