Owner-routed north-fold exchange for an east-west split north rank
row, plus the px-dispatching single-field fold entry points
(ocean_fold_north_*): px = 1 keeps the local kernels of
rdb_ocean_fold verbatim, px > 1 always uses the exchange (the
self-mirror tile through a local copy).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private, | parameter | :: | TAG_OC_FOLD | = | 15 |
Fold message tag (halo: 11-14, |
| logical, | private | :: | fx_active | = | .false. |
This rank takes part in a distributed fold (px > 1, folded north edge, north rank row). |
|
| integer, | private | :: | fx_cap | = | 0 |
Per-peer capacity (values). |
|
| logical, | private | :: | fx_initialised | = | .false. |
True after |
|
| integer, | private | :: | fx_ng | = | 0 |
Ghost width. |
|
| integer, | private | :: | fx_nmax | = | 1 |
Largest (peer, family) entry count. |
|
| integer, | private | :: | fx_npeer | = | 0 |
Peers (self included when it routes to itself). |
|
| integer, | private | :: | fx_nr(FOLD_NFAM) | = | 0 |
Receive entries per family. |
|
| integer, | private | :: | fx_ns(FOLD_NFAM) | = | 0 |
Send entries per family. |
|
| integer, | private | :: | fx_nxl | = | 0 |
Tile physical width. |
|
| integer, | private | :: | fx_nyl | = | 0 |
Tile physical height (identical on every north-row tile). |
|
| logical, | private | :: | fx_open | = | .false. |
A group is open (between begin and end). |
|
| integer, | private, | allocatable | :: | fx_peer_rank(:) |
Compute-comm rank of each peer. |
||
| type(fold_plan_t), | private | :: | fx_plan |
Host copy of the routing plan. |
|||
| integer, | private | :: | fx_poff(FOLD_NFAM) | = | 0 |
Pack cursor: slabs packed per family in the open group. |
|
| integer, | private | :: | fx_px | = | 1 |
Tiles along x. |
|
| integer, | private | :: | fx_r0(FOLD_NFAM) | = | 0 |
Start of each family’s block in the flat receive arrays. |
|
| real(kind=wp), | private, | allocatable | :: | fx_rbuf(:) |
Send / receive buffers, |
||
| integer, | private, | allocatable | :: | fx_rcls(:) |
Receive entries: destination column, peer, position, fold-row class. |
||
| integer, | private, | allocatable | :: | fx_rcol(:) |
Receive entries: destination column, peer, position, fold-row class. |
||
| integer, | private, | allocatable | :: | fx_re(:) |
Receive entries: destination column, peer, position, fold-row class. |
||
| type(request_t), | private, | allocatable | :: | fx_reqs(:) |
MPI requests (2 per peer). |
||
| integer, | private, | allocatable | :: | fx_rn(:,:) |
Receive counts (npeer, FOLD_NFAM). |
||
| integer, | private, | allocatable | :: | fx_rpeer(:) |
Receive entries: destination column, peer, position, fold-row class. |
||
| integer, | private | :: | fx_ry | = | 0 |
This rank’s y coordinate (the north row). |
|
| integer, | private | :: | fx_s0(FOLD_NFAM) | = | 0 |
Start of each family’s block in the flat send arrays. |
|
| real(kind=wp), | private, | allocatable | :: | fx_sbuf(:) |
Send / receive buffers, |
||
| integer, | private, | allocatable | :: | fx_scol(:) |
Send entries: source column, peer index, position in its list. |
||
| integer, | private, | allocatable | :: | fx_se(:) |
Send entries: source column, peer index, position in its list. |
||
| integer, | private | :: | fx_self | = | 0 |
Peer index of this tile (0 if not a peer). |
|
| logical, | private | :: | fx_sent | = | .false. |
The open group has been exchanged (packing closed). |
|
| integer, | private | :: | fx_slab_cap | = | 0 |
Per-peer capacity in (row x layer) slabs of |
|
| integer, | private, | allocatable | :: | fx_sn(:,:) |
Send counts (npeer, FOLD_NFAM). |
||
| integer, | private, | allocatable | :: | fx_speer(:) |
Send entries: source column, peer index, position in its list. |
||
| type(MPI_Status), | private, | allocatable | :: | fx_stats(:) |
MPI statuses (2 per peer). |
||
| integer, | private | :: | fx_uoff(FOLD_NFAM) | = | 0 |
Unpack cursor: slabs unpacked per family in the open group. |
Cell-centred 2D north fold (copy).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyt) |
Cell-centred field (nx_total, ny_total). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
Cell-centred 3D north fold (copy).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyt,nz) |
Cell-centred field (nx_total, ny_total, nz). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
SW-corner 2D north fold (+ fold-line projection); negate for a
true-vector component, copy for a scalar / vorticity.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyf) |
Corner field (nx_total+1, ny_total+1). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
x-face (u) 2D north fold (negate).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyt) |
x-face field (nx_total+1, ny_total). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
x-face (u) 3D north fold (negate).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyt,nz) |
x-face field (nx_total+1, ny_total, nz). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
y-face (v) 2D north fold (negate + fold-line projection).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyf) |
y-face field (nx_total, ny_total+1). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
y-face (v) 3D north fold (negate + fold-line projection).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyf,nz) |
y-face field (nx_total, ny_total+1, nz). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
Pack a 2D field of storage shape (nxa, nya) into the open group.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | fld(nxa,nya) |
Field (T: nxt x nyt; u: nxt+1 x nyt; v: nxt x nyt+1; corner: nxt+1 x nyt+1). |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Pack every layer of a 3D field into the open group: the sender’s owned mirror-source points, rows below (and, for v / corner, on) the fold line.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | fld(nxa,nya,nz) |
Field; see |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | nz |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Unpack the next field of the exchanged group into a 2D field.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxa,nya) |
Field; same stagger and order as at pack. |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Unpack the next field of the exchanged group: write every north ghost row (all storage columns) and, for v / corner, the fold-line row’s west half (self-conjugate column → 0 for a vector).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxa,nya,nz) |
Field; same stagger and order as at pack. |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | nz |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
True iff this rank folds through the exchange (px > 1 and a
folded north edge on this rank). False on every px = 1 run and
on ranks off the north row.
Open a group of nslab (rows x layers) slabs in total (an upper
bound is fine). Grows the buffers, with a warning, if the run did
not reserve enough. No-op when inactive.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nslab |
Sum over the group’s fields of rows x layers. |
Close the group: every packed slab must have been unpacked.
Move every packed message: one isend + irecv per non-self peer
with a non-empty message, the self pair as a local copy, then
waitall. Collective over the north rank row.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| logical, | intent(in), | optional | :: | device_resident |
|
Release the plan, buffers and topology. Idempotent.
Record the topology and, on a north-row rank of an east-west split
folded grid, build the routing plan and map it to the device.
Every rank may call it (it is not collective); a rank that does
not fold, or a px = 1 run, keeps the exchange inactive.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(in) | :: | decomp |
Domain decomposition. |
||
| integer, | intent(in) | :: | nghost |
Ghost width. |
||
| logical, | intent(in) | :: | north_fold |
This rank folds its north edge ( |
||
| integer, | intent(out), | optional | :: | ierr |
|
Pre-size the buffers for the largest group of the run, in
(row x layer) slabs summed over its fields — e.g. the
ml_state group is (3 + ntracer)*nz fields of at most ng+1
rows — so no device reallocation fires mid-run. No-op when
inactive or already large enough.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nslab |
Total (rows x layers) over the fields of the largest group. |
Cell-centred 2D north fold (copy).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyt) |
Cell-centred field (nx_total, ny_total). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
Cell-centred 3D north fold (copy).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyt,nz) |
Cell-centred field (nx_total, ny_total, nz). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
SW-corner 2D north fold (+ fold-line projection); negate for a
true-vector component, copy for a scalar / vorticity.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyf) |
Corner field (nx_total+1, ny_total+1). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
x-face (u) 2D north fold (negate).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyt) |
x-face field (nx_total+1, ny_total). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
x-face (u) 3D north fold (negate).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxf,nyt,nz) |
x-face field (nx_total+1, ny_total, nz). |
||
| integer, | intent(in) | :: | nxf | |||
| integer, | intent(in) | :: | nyt | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
y-face (v) 2D north fold (negate + fold-line projection).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyf) |
y-face field (nx_total, ny_total+1). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
y-face (v) 3D north fold (negate + fold-line projection).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxt,nyf,nz) |
y-face field (nx_total, ny_total+1, nz). |
||
| integer, | intent(in) | :: | nxt | |||
| integer, | intent(in) | :: | nyf | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx_phys | |||
| integer, | intent(in) | :: | ny_phys | |||
| integer, | intent(in) | :: | ng | |||
| logical, | intent(in), | optional | :: | device_resident |
Exchange path only: |
(Re)allocate both buffers for nslab slabs per peer
(exit-delete / dealloc / alloc / enter-create, as
ocean_halo_buffers_ensure_nz). Never while a group is open.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nslab |
Pack a 2D field of storage shape (nxa, nya) into the open group.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | fld(nxa,nya) |
Field (T: nxt x nyt; u: nxt+1 x nyt; v: nxt x nyt+1; corner: nxt+1 x nyt+1). |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Pack every layer of a 3D field into the open group: the sender’s owned mirror-source points, rows below (and, for v / corner, on) the fold line.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | fld(nxa,nya,nz) |
Field; see |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | nz |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Unpack the next field of the exchanged group into a 2D field.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxa,nya) |
Field; same stagger and order as at pack. |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|
Unpack the next field of the exchanged group: write every north ghost row (all storage columns) and, for v / corner, the fold-line row’s west half (self-conjugate column → 0 for a vector).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(nxa,nya,nz) |
Field; same stagger and order as at pack. |
||
| integer, | intent(in) | :: | nxa |
Storage extents of |
||
| integer, | intent(in) | :: | nya |
Storage extents of |
||
| integer, | intent(in) | :: | nz |
Storage extents of |
||
| integer, | intent(in) | :: | stagger |
|
||
| logical, | intent(in) | :: | negate |
|
||
| logical, | intent(in), | optional | :: | device_resident |
|