rdb_ocean_fold_plan Module

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).

Mirror (see the 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).

Owner routing (plan §2.3)

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.

Lists

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.

Fold-line row (v and corner)

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.


Used by

  • module~~rdb_ocean_fold_plan~~UsedByGraph module~rdb_ocean_fold_plan rdb_ocean_fold_plan module~rdb_ocean_fold_exchange rdb_ocean_fold_exchange module~rdb_ocean_fold_exchange->module~rdb_ocean_fold_plan module~rdb_barotropic_substep rdb_barotropic_substep module~rdb_barotropic_substep->module~rdb_ocean_fold_exchange module~rdb_continuity rdb_continuity module~rdb_continuity->module~rdb_ocean_fold_exchange module~rdb_ocean_fold_apply rdb_ocean_fold_apply module~rdb_continuity->module~rdb_ocean_fold_apply module~rdb_ocean_engine rdb_ocean_engine module~rdb_ocean_engine->module~rdb_ocean_fold_exchange module~rdb_ocean_engine->module~rdb_ocean_fold_apply module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ice_transport rdb_ice_transport module~rdb_ocean_engine->module~rdb_ice_transport module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_halo_state rdb_ocean_halo_state module~rdb_ocean_engine->module~rdb_ocean_halo_state module~rdb_ocean_state rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ice_ocean_coupler rdb_ice_ocean_coupler module~rdb_ocean_engine->module~rdb_ice_ocean_coupler module~rdb_ocean_data_forcing rdb_ocean_data_forcing module~rdb_ocean_engine->module~rdb_ocean_data_forcing module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_fold_apply->module~rdb_ocean_fold_exchange module~rdb_ocean_setup->module~rdb_ocean_fold_exchange module~rdb_ocean_setup->module~rdb_ocean_fold_apply module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_halo_state module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_engine module~rdb_driver->module~rdb_ocean_dyn module~rdb_driver->module~rdb_ocean_state module~rdb_handle rdb_handle module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_state module~rdb_ice_transport->module~rdb_continuity module~rdb_ice_transport->module~rdb_ocean_halo_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_ocean_api->module~rdb_ocean_fold_apply module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_bt_wide rdb_ocean_bt_wide module~rdb_ocean_bt_wide->module~rdb_barotropic_substep module~rdb_ocean_dyn->module~rdb_barotropic_substep module~rdb_ocean_dyn->module~rdb_continuity module~rdb_ocean_dyn->module~rdb_ocean_fold_apply module~rdb_ocean_dyn->module~rdb_ocean_bt_wide module~rdb_ocean_dyn->module~rdb_ocean_halo_state module~rdb_ocean_halo_state->module~rdb_ocean_fold_apply module~rdb_ocean_state->module~rdb_continuity module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_ocean_state->module~rdb_ocean_data_forcing module~rdb_ice_ocean_coupler->module~rdb_ocean_halo_state module~rdb_ocean_data_forcing->module~rdb_ocean_halo_state module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state

Variables

Type Visibility Attributes Name Initial
integer, public, parameter :: FOLD_FAM_T = 1

Column family of T and v (mirror ni+1-c).

integer, public, parameter :: FOLD_FAM_U = 2

Column family of u and corner (mirror ni+2-f).

integer, public, parameter :: FOLD_NFAM = 2

Number of column families.

integer, public, parameter :: FOLD_PLAN_ERR_ARGS = 1

fold_plan_build status: ni < px, px < 1, ng < 1 or rx outside 0..px-1.

integer, public, parameter :: FOLD_PLAN_OK = 0

fold_plan_build status: plan built.

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, ng halo rows + the fold-line row.

integer, public, parameter :: FOLD_STAG_T = 1

Cell centre (h, η, tracers): T columns, ng halo rows.

integer, public, parameter :: FOLD_STAG_U = 2

West face (u): U columns, ng halo rows.

integer, public, parameter :: FOLD_STAG_V = 3

South face (v): T columns, ng halo rows + the fold-line row.


Derived Types

type, public ::  fold_plan_t

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).

Components

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 (FOLD_ROW_*), flat.

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 peer_rx of this tile itself (0 if not a peer).

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).

Type-Bound Procedures

procedure, public :: destroy => fold_plan_destroy

Functions

public pure function fold_stagger_family(stagger) result(fam)

Column family of a stagger (FOLD_FAM_T for T/v, FOLD_FAM_U for u/corner).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: stagger

FOLD_STAG_* stagger.

Return Value integer

public pure function fold_stagger_nrows(stagger, ng) result(nrow)

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).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: stagger

FOLD_STAG_* stagger.

integer, intent(in) :: ng

Ghost width.

Return Value integer

public pure function fold_tile_owner(ni, px, c) result(rx)

Tile holding global cell c (1..ni), closed form of the decomp_init split.

Arguments

Type IntentOptional 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, 1..ni).

Return Value integer

Owning tile x-coordinate (0-based).


Subroutines

public pure subroutine fold_plan_build(plan, ni, px, ng, rx, status)

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.

Arguments

Type IntentOptional 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

FOLD_PLAN_OK, or FOLD_PLAN_ERR_ARGS.

public pure subroutine fold_receiver_entries(ni, px, ng, fam, rx, ncol, own, src, cls)

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.

Arguments

Type IntentOptional 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 (FOLD_FAM_T or FOLD_FAM_U).

integer, intent(in) :: rx

Receiving tile x-coordinate (0-based).

integer, intent(out) :: ncol

Destination columns filled (w+2ng for T, w+2ng+1 for U).

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 (FOLD_ROW_*).

public pure subroutine fold_row_map(stagger, ng, nyl, r, src_row, dst_row)

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).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: stagger

FOLD_STAG_* 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, 1..fold_stagger_nrows(stagger, ng)).

integer, intent(out) :: src_row

Local storage row the sender reads.

integer, intent(out) :: dst_row

Local storage row the receiver writes.

public pure subroutine fold_tile_extent(ni, px, rx, a, w)

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).

Arguments

Type IntentOptional 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, 0..px-1).

integer, intent(out) :: a

First global cell of the tile (1-based).

integer, intent(out) :: w

Tile width (cells).

private pure subroutine fold_plan_destroy(this)

Free the plan’s lists and reset it to the empty default. Safe on a plan that was never built.

Arguments

Type IntentOptional Attributes Name
class(fold_plan_t), intent(inout) :: this