Skip to content

adam_seam_exchange ​

ADAM, inter-realm seam ghost fill across ranks (issue #40).

A seam ghost of realm is is filled from the interior cell of its peer realm that contains the ghost centre. The realms are partitioned over the ranks independently, so that cell may be owned by another rank. The forest splits the seam rows of every realm at topology time:

  • local rows (maps%seam_local_map_ghost_cell): ghost and peer cell on this rank, copied by the realm's own fill_seam_from_peer_forest;
  • cross-rank rows (maps%seam_mpi_recv_cell on the realm owning the ghosts, maps%seam_mpi_send_cell on the realm owning the cells), enumerated in one canonical order on every rank, so the rows rank A sends to rank B for a seam and the rows B receives from A match one to one.

Across a 2:1 seam (coupling = refined, issue #52) a send row carries a kind: copy, interpolate (the coarse anchor cell and the packed octant and anchor shifts of seam_meta_pack, evaluated by interp_seam_ghost, the intra-realm coarse->fine fill) or restrict (the base fine cell, mean of its 2x2x2 block, the intra-realm fine->coarse fill), so the owner of the cells sends the ghost values. Same-rank copy rows keep the local path; same-rank interpolate and restrict rows travel as messages to self (rank = this rank in the send/receive rows), without MPI.

seam_fill moves both kinds for one (realm, peer slot) pair: the local copy, then the owner of the cells packs (pack_seam_cells_forest), the buffers travel point to point, the owner of the ghosts unpacks (unpack_seam_cells_forest). Each rank calls it for the same pairs in the same order (the peer slots come from the manifest, not from the rows a rank holds); a rank with no rows of a pair returns at once, so the exchange is not collective, but a rank that skipped a pair it has rows for would leave its partners waiting.

Source: src/lib/common/adam_seam_exchange.F90

Dependencies

Contents ​

Variables ​

NameTypeAttributesDescription
SEAM_TAGinteger(kind=I4P)parameterMPI tag of the cross-rank seam messages.
SEAM_ROW_COPYinteger(kind=I4P)parameterSame cell size: copy the cell.
SEAM_ROW_INTERPOLATEinteger(kind=I4P)parameterCoarse cell to a fine ghost: interpolate (interp_seam_ghost).
SEAM_ROW_RESTRICTinteger(kind=I4P)parameterFine cells to a coarse ghost: mean of the 2x2x2 fine cells.

Derived Types ​

seam_post_object ​

A posted seam fill of one (realm, peer slot) pair (issue #53, F3): its buffers and requests live until the wait.

Components ​

NameTypeAttributesDescription
isinteger(kind=I4P)Realm owning the ghosts.
pinteger(kind=I4P)Peer slot.
n_recvinteger(kind=I4P)Cross-rank receive rows.
n_reqinteger(kind=I4P)Posted requests.
activelogicalCross-rank (or to-self) rows were posted.
timinglogicalAccumulate the phase timers.
reqinteger(kind=I4P)allocatableMPI requests.
send_bufreal(kind=R8P)allocatablePacked values sent (alive until the wait).
recv_bufreal(kind=R8P)allocatableValues received.

Subroutines ​

seam_fill ​

Fill the seam ghosts of self (the forest realm self%realm_index) from its peer slot p: local rows, then cross-rank rows. Only self is written; realm(:) (which contains self) is read for the peer.

fortran
subroutine seam_fill(self, realm, p)

Arguments

NameTypeIntentAttributesDescription
selfclass(realm_object)inouttargetRealm owning the ghosts.
realmclass(realm_object)intargetForest realms.
pinteger(kind=I4P)inPeer slot of self.

Call graph

seam_fill_batch ​

Fill the seam ghosts of every (realm, peer slot) pair of seam cadence cadence with one wait (issue #53, F3): post every pair (local rows, pack, receives and sends), wait once on all the requests, then unpack every pair in pair order. Every rank reaches the same pairs in the same order (the slots come from the manifest), and each pair has its own tag. Batching moves every pack before every unpack: the packs read real (interior) cells only, never a seam ghost, so the values sent are the ones the pair-by-pair exchange sends. wtime (timing only) accumulates the wait at a barrier put before the posts (the partners' arrival skew, load imbalance) and the single wait.

fortran
subroutine seam_fill_batch(realm, cadence, wtime)

Arguments

NameTypeIntentAttributesDescription
realmclass(realm_object)inouttargetForest realms.
cadenceinteger(kind=I4P)inSeam cadence of the pairs to fill.
wtimereal(kind=R8P)inoutTiming: imbalance before the posts, wait.

Call graph

seam_fill_post ​

Post the fill of the seam ghosts of self from its peer slot p: the local rows (copied now), the pack of the rows self's ghosts receive from the cells this rank owns, the receives and the sends (one message per partner rank, tagged by the pair) and the message to self. seam_fill_complete unpacks once the requests are complete.

fortran
subroutine seam_fill_post(self, realm, p, post)

Arguments

NameTypeIntentAttributesDescription
selfclass(realm_object)inouttargetRealm owning the ghosts.
realmclass(realm_object)intargetForest realms.
pinteger(kind=I4P)inPeer slot of self.
posttype(seam_post_object)outThe posted exchange.

Call graph

seam_fill_complete ​

Complete a posted fill (seam_fill_post), its requests complete: unpack the received rows into self's ghosts.

fortran
subroutine seam_fill_complete(self, post)

Arguments

NameTypeIntentAttributesDescription
selfclass(realm_object)inoutRealm owning the ghosts.
posttype(seam_post_object)inThe posted exchange.

Call graph

seam_fill_all ​

Fill the seam ghosts of self from every peer slot, whatever the cadence (diagnostics on the committed state).

fortran
subroutine seam_fill_all(self, realm)

Arguments

NameTypeIntentAttributesDescription
selfclass(realm_object)inouttargetRealm owning the ghosts.
realmclass(realm_object)intargetForest realms.

Call graph

pack_seam_rows ​

Pack the ghost values of the send rows [rank, b, i, j, k, kind, meta] row_start..row_start+row_count-1 from the field q (the cells' owner active buffer), nv values per row in row order (issue #40, #52): a copy of the cell, the coarse->fine interpolant of interp_seam_ghost (the intra-realm fill; injection copies the anchor) or the restriction from the base cell: the mean of the 2x2x2 fine cells (summed in the intra-realm order, then scaled) when the meta is 0, otherwise the 6-point Lagrange or the WENO restriction of its packed codes and regime ([amr] seam_restriction, #68 C2, C3).

fortran
subroutine pack_seam_rows(rows, row_start, row_count, regime, ngc, q, buf)

Arguments

NameTypeIntentAttributesDescription
rowsinteger(kind=I4P)inSend rows.
row_startinteger(kind=I4P)inFirst row.
row_countinteger(kind=I4P)inNumber of rows.
regimeinteger(kind=I4P)inCoarse->fine fill regime (maps%seam_ghost_fill).
ngcinteger(kind=I4P)inGhost cells number.
qreal(kind=R8P)inField (v, i, j, k, b).
bufreal(kind=R8P)outPacked values.

Call graph

unpack_seam_rows ​

Unpack buf (nv values per row in row order) into the ghost cells of the receive rows [rank, b, i, j, k]row_start..row_start+row_count-1 of the field q (issue #40).

fortran
subroutine unpack_seam_rows(rows, row_start, row_count, ngc, buf, q)

Arguments

NameTypeIntentAttributesDescription
rowsinteger(kind=I4P)inReceive rows.
row_startinteger(kind=I4P)inFirst row.
row_countinteger(kind=I4P)inNumber of rows.
ngcinteger(kind=I4P)inGhost cells number.
bufreal(kind=R8P)inPacked values.
qreal(kind=R8P)inoutField (v, i, j, k, b).

Call graph

Functions ​

seam_peer_slot ​

Return the slot of realm is in the peer slots of peer (0 if is is not a peer of it).

Attributes: pure

Returns: integer(kind=I4P)

fortran
function seam_peer_slot(peer, is) result(q)

Arguments

NameTypeIntentAttributesDescription
peerclass(realm_object)inRealm whose slots are searched.
isinteger(kind=I4P)inRealm index looked up.

Call graph