Pure index math for the owner-routed north-fold exchange — no MPI,
no field data. Given the global fold-row width ni, the x process
count px, the ghost width ng and a north-row tile rx, it lists,
per peer tile and per column FAMILY, which local storage columns this
tile sends and which it receives. The exchange engine
(rdb_ocean_fold_exchange) moves the values; this module only says
where they come from and where they go, so the routing is testable
serially (tests/test_ocean_fold_plan.F90).
rdb_ocean_fold header for the derivation)Global physical columns, reduced periodically into 1..ni:
* T and v (cell columns, family FOLD_FAM_T): column c mirrors
to ni+1-c.
* u and corner (WEST-face / SW-vertex columns, family
FOLD_FAM_U): face f (f = 1 ≡ ni+1) mirrors to ni+2-f.
Rows: the receiver’s north ghost row d (and, for v / corner, the
fold-line row itself) reads the sender’s row d below the fold line;
both are north-row tiles of the same height, so the row map needs no
global j offset (fold_row_map).
Every value comes from the tile that OWNS the mirror point, never
from a halo copy, so the fold needs no preceding x exchange:
* T / v column m: the tile whose cells contain m.
* u / corner face mf: the EAST face of cell mf-1, which under
the halo’s D1 rule (the west/south rank owns a seam face) belongs
to the tile holding cell mf-1. The sender reads its owned faces
ng+2 .. ng+w+1, never the west-seam copy at ng+1.
A receiver’s destination columns are EVERY storage column of its
window: 1..w+2ng (family T) or 1..w+2ng+1 (family U). The
canonical entry order of a (sender, receiver) pair is the receiver’s
destination columns in increasing order, filtered to that sender;
both ends evaluate the same pure function, so their lists agree with
no handshake. Lists are index lists, not ranges: a peer’s columns
can wrap modulo ni.
Each receive entry carries the fold-row class of its destination
column (the serial projection rule of fold_north_v_face_* /
fold_north_corner_2d): FOLD_ROW_WEST takes the (sign-applied)
mirror value, FOLD_ROW_SELF is zeroed for a true vector and left
for a scalar, FOLD_ROW_EAST is the authoritative half and is never
written. The v class uses the T-family columns, the corner class the
U-family columns, so each family carries exactly one class.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | FOLD_FAM_T | = | 1 |
Column family of T and v (mirror |
| integer, | public, | parameter | :: | FOLD_FAM_U | = | 2 |
Column family of u and corner (mirror |
| integer, | public, | parameter | :: | FOLD_NFAM | = | 2 |
Number of column families. |
| integer, | public, | parameter | :: | FOLD_PLAN_ERR_ARGS | = | 1 |
|
| integer, | public, | parameter | :: | FOLD_PLAN_OK | = | 0 |
|
| integer, | public, | parameter | :: | FOLD_ROW_EAST | = | -1 |
Fold-row slot in the authoritative (east) half: never written. |
| integer, | public, | parameter | :: | FOLD_ROW_SELF | = | 0 |
Self-conjugate fold-row slot: zeroed for vectors, left for scalars. |
| integer, | public, | parameter | :: | FOLD_ROW_WEST | = | 1 |
Fold-row slot in the west half: takes the sign-applied mirror. |
| integer, | public, | parameter | :: | FOLD_STAG_CORNER | = | 4 |
SW vertex: U columns, |
| integer, | public, | parameter | :: | FOLD_STAG_T | = | 1 |
Cell centre (h, η, tracers): T columns, |
| integer, | public, | parameter | :: | FOLD_STAG_U | = | 2 |
West face (u): U columns, |
| integer, | public, | parameter | :: | FOLD_STAG_V | = | 3 |
South face (v): T columns, |
One north-row tile’s routing for the distributed fold. Entries of
family f for peer p live at start(p,f)+1 .. start(p,f)+n(p,f)
of the flat entry arrays (send and receive separately).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | ng | = | 0 |
Ghost width. |
|
| integer, | public | :: | ni | = | 0 |
Global physical width of the fold row. |
|
| integer, | public | :: | nmax | = | 0 |
Largest entry count of any (peer, family) list, send or receive. |
|
| integer, | public | :: | npeer | = | 0 |
Peer tiles this tile sends to or receives from (self included when its own mirror falls in its window). |
|
| integer, | public | :: | nrecv(FOLD_NFAM) | = | 0 |
Total receive entries per family. |
|
| integer, | public | :: | nsend(FOLD_NFAM) | = | 0 |
Total send entries per family. |
|
| integer, | public, | allocatable | :: | peer_rx(:) |
Peer tile x-coordinates, ascending, shape (npeer). |
||
| integer, | public | :: | px | = | 0 |
Tiles along the fold row. |
|
| integer, | public, | allocatable | :: | recv_cls(:) |
Fold-row class of each receive entry ( |
||
| integer, | public, | allocatable | :: | recv_col(:) |
Local storage column this tile writes, flat (all families). |
||
| integer, | public, | allocatable | :: | recv_e(:) |
1-based position within its (peer, family) list, flat. |
||
| integer, | public, | allocatable | :: | recv_n(:,:) |
Receive entry counts, shape (npeer, FOLD_NFAM). |
||
| integer, | public, | allocatable | :: | recv_peer(:) |
Peer index of each receive entry, flat. |
||
| integer, | public, | allocatable | :: | recv_start(:,:) |
Offsets into the flat receive arrays, shape (npeer, FOLD_NFAM). |
||
| integer, | public | :: | rx | = | -1 |
This tile’s x-coordinate (0-based). |
|
| integer, | public | :: | self_peer | = | 0 |
Index into |
|
| integer, | public, | allocatable | :: | send_col(:) |
Local storage column this tile reads, flat (all families). |
||
| integer, | public, | allocatable | :: | send_e(:) |
1-based position of each send entry within its (peer, family) list, flat. |
||
| integer, | public, | allocatable | :: | send_n(:,:) |
Send entry counts, shape (npeer, FOLD_NFAM). |
||
| integer, | public, | allocatable | :: | send_peer(:) |
Peer index of each send entry, flat. |
||
| integer, | public, | allocatable | :: | send_start(:,:) |
Offsets into the flat send arrays, shape (npeer, FOLD_NFAM). |
| procedure, public :: destroy => fold_plan_destroy |
Column family of a stagger (FOLD_FAM_T for T/v, FOLD_FAM_U for
u/corner).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | stagger |
|
Rows a stagger moves per column: ng (T, u) or ng+1 (v, corner:
the fold-line row is always sent, the receiver uses it only where
recv_cls == FOLD_ROW_WEST).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | stagger |
|
||
| integer, | intent(in) | :: | ng |
Ghost width. |
Tile holding global cell c (1..ni), closed form of the
decomp_init split.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | ni |
Global physical width of the fold row (cells). |
||
| integer, | intent(in) | :: | px |
Tiles along the fold row. |
||
| integer, | intent(in) | :: | c |
Global cell index (1-based, |
Owning tile x-coordinate (0-based).
Build tile rx’s send/receive lists for every peer and both
column families. Pure: every north-row rank computes every tile’s
receive lists itself (decomp_init arithmetic), so no handshake.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(fold_plan_t), | intent(out) | :: | plan | |||
| integer, | intent(in) | :: | ni |
Global physical width of the fold row. |
||
| integer, | intent(in) | :: | px |
Tiles along the fold row. |
||
| integer, | intent(in) | :: | ng |
Ghost width. |
||
| integer, | intent(in) | :: | rx |
This tile’s x-coordinate (0-based). |
||
| integer, | intent(out) | :: | status |
|
Every destination column i = 1..ncol of tile rx’s window for a
column family: the owning tile own(i) of its mirror, the owner’s
local storage column src(i) to read, and the fold-row class
cls(i). ncol = w+2ng (T) or w+2ng+1 (U); the arrays must
hold at least that many entries.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | ni |
Global physical width of the fold row (cells). |
||
| integer, | intent(in) | :: | px |
Tiles along the fold row. |
||
| integer, | intent(in) | :: | ng |
Ghost width. |
||
| integer, | intent(in) | :: | fam |
Column family ( |
||
| integer, | intent(in) | :: | rx |
Receiving tile x-coordinate (0-based). |
||
| integer, | intent(out) | :: | ncol |
Destination columns filled ( |
||
| integer, | intent(out) | :: | own(:) |
Owning tile x-coordinate (0-based) of each column’s mirror. |
||
| integer, | intent(out) | :: | src(:) |
Owner’s local storage column to read (1-based, ghosts included). |
||
| integer, | intent(out) | :: | cls(:) |
Fold-row class of each column ( |
Storage rows of message row r (1..fold_stagger_nrows) on a
north-row tile of nyl physical rows: the sender reads
src_row, the receiver writes dst_row.
* T, u: r = d = 1..ng: src ng+nyl+1-d, dst ng+nyl+d.
* v, corner: r = d+1, d = 0..ng: src ng+nyl+1-d, dst ng+nyl+1+d
(d = 0 is the fold-line row, src = dst = ng+nyl+1).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | stagger |
|
||
| integer, | intent(in) | :: | ng |
Ghost width. |
||
| integer, | intent(in) | :: | nyl |
Physical rows of the north-row tile. |
||
| integer, | intent(in) | :: | r |
Message row (1-based, |
||
| integer, | intent(out) | :: | src_row |
Local storage row the sender reads. |
||
| integer, | intent(out) | :: | dst_row |
Local storage row the receiver writes. |
First global cell a and width w of tile rx — the
decomp_init split (remainder to the WEST tiles), restated here so
the plan stays pure and dependency-free (cross-checked against
decomp_init by the unit test).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | ni |
Global physical width of the fold row (cells). |
||
| integer, | intent(in) | :: | px |
Tiles along the fold row. |
||
| integer, | intent(in) | :: | rx |
Tile x-coordinate (0-based, |
||
| integer, | intent(out) | :: | a |
First global cell of the tile (1-based). |
||
| integer, | intent(out) | :: | w |
Tile width (cells). |
Free the plan’s lists and reset it to the empty default. Safe on a plan that was never built.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(fold_plan_t), | intent(inout) | :: | this |