rdb_ocean_chksum Module

Windowed, greppable per-field statistics printed at the split-RK2 phase seams, so (a) two runs can be diffed log-to-log to find the FIRST diverging operator, and (b) a non-finite value is attributed to the phase that MINTED it, not the phase that noticed it (the nan-catch in the truncation / BT fold names the messenger only).

Row format (fixed-width, grep “CHKSUM”): CHKSUM s

bits is a decomposition-INVARIANT POPCNT reduction (int64 sum of the population count of each element’s IEEE-754 bit pattern) — identical across rank counts / loop orders, so a serial log diffs against a decomposed run and the first mismatching bits names the diverging operator. sum/min/max stay per-rank.

All reductions run device-side (!$acc parallel loop reduction, inert on host builds) — no D->H field copies, so a death-window sample cadence is affordable on GPU. NaN semantics: min/max reductions are NaN-blind (comparisons with NaN are FALSE), so a contaminated field can print plausible min/max — nonfin is the authoritative corruption signal; sum goes NaN with the field.

Gated by &ocean_debug_nml chksum with an optional [chksum_start_step, chksum_end_step] outer-step window (mirrors debug_ke_attr). Default off => bit-identical (untaken branches). Single-rank semantics: sums are per-rank (no halo reduction); multi-rank runs print one row set per rank.


Uses

  • module~~rdb_ocean_chksum~~UsesGraph module~rdb_ocean_chksum rdb_ocean_chksum iso_fortran_env iso_fortran_env module~rdb_ocean_chksum->iso_fortran_env module~rdb_barotropic_workstate rdb_barotropic_workstate module~rdb_ocean_chksum->module~rdb_barotropic_workstate module~rdb_constants rdb_constants module~rdb_ocean_chksum->module~rdb_constants module~rdb_grid rdb_grid module~rdb_ocean_chksum->module~rdb_grid module~rdb_halo rdb_halo module~rdb_ocean_chksum->module~rdb_halo module~rdb_multilayer_state rdb_multilayer_state module~rdb_ocean_chksum->module~rdb_multilayer_state module~rdb_barotropic_workstate->iso_fortran_env module~rdb_barotropic_workstate->module~rdb_constants module~rdb_barotropic_workstate->module~rdb_grid module~rdb_mem_report rdb_mem_report module~rdb_barotropic_workstate->module~rdb_mem_report pic_types pic_types module~rdb_constants->pic_types module~rdb_grid->module~rdb_constants module~rdb_halo->iso_fortran_env module~rdb_halo->module~rdb_constants module~rdb_comm_env rdb_comm_env module~rdb_halo->module~rdb_comm_env module~rdb_decomp rdb_decomp module~rdb_halo->module~rdb_decomp module~rdb_efp rdb_efp module~rdb_halo->module~rdb_efp pic_logger pic_logger module~rdb_halo->pic_logger pic_mpi_lib pic_mpi_lib module~rdb_halo->pic_mpi_lib module~rdb_multilayer_state->iso_fortran_env module~rdb_multilayer_state->module~rdb_constants module~rdb_multilayer_state->module~rdb_grid module~rdb_multilayer_state->module~rdb_efp module~rdb_error_ring rdb_error_ring module~rdb_multilayer_state->module~rdb_error_ring module~rdb_multilayer_state->module~rdb_mem_report module~rdb_tracer rdb_tracer module~rdb_multilayer_state->module~rdb_tracer module~rdb_multilayer_state->pic_logger module~rdb_comm_env->iso_fortran_env module~rdb_comm_env->module~rdb_constants module~rdb_comm_env->pic_mpi_lib module~rdb_config rdb_config module~rdb_decomp->module~rdb_config module~rdb_efp->iso_fortran_env ieee_arithmetic ieee_arithmetic module~rdb_efp->ieee_arithmetic module~rdb_error_ring->pic_logger module~rdb_mem_report->iso_fortran_env module~rdb_mem_report->module~rdb_constants module~rdb_mem_report->pic_logger pic_strings pic_strings module~rdb_mem_report->pic_strings module~rdb_tracer->iso_fortran_env module~rdb_tracer->module~rdb_constants module~rdb_tracer->module~rdb_grid module~rdb_tracer->module~rdb_mem_report module~rdb_config->module~rdb_constants module~rdb_config->module~rdb_error_ring module~rdb_config->pic_logger module~rdb_config->pic_strings module~rdb_ice_enthalpy rdb_ice_enthalpy module~rdb_config->module~rdb_ice_enthalpy module~rdb_ice_init rdb_ice_init module~rdb_config->module~rdb_ice_init module~rdb_nml_schema rdb_nml_schema module~rdb_config->module~rdb_nml_schema module~rdb_ocean_status rdb_ocean_status module~rdb_config->module~rdb_ocean_status pic_ascii pic_ascii module~rdb_config->pic_ascii module~rdb_ice_enthalpy->module~rdb_constants module~rdb_ice_init->module~rdb_constants module~rdb_ice_init->module~rdb_grid module~rdb_ice_init->module~rdb_multilayer_state module~rdb_ice_init->module~rdb_ice_enthalpy module~rdb_ice_column rdb_ice_column module~rdb_ice_init->module~rdb_ice_column module~rdb_ice_state rdb_ice_state module~rdb_ice_init->module~rdb_ice_state module~rdb_ocean_metrics rdb_ocean_metrics module~rdb_ice_init->module~rdb_ocean_metrics module~rdb_nml_schema->module~rdb_constants module~rdb_nml_schema->module~rdb_error_ring module~rdb_nml_schema->pic_logger

Used by

  • module~~rdb_ocean_chksum~~UsedByGraph module~rdb_ocean_chksum rdb_ocean_chksum module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_ocean_dyn->module~rdb_ocean_chksum module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_dyn module~rdb_ocean_engine rdb_ocean_engine module~rdb_driver->module~rdb_ocean_engine module~rdb_ocean_state rdb_ocean_state module~rdb_driver->module~rdb_ocean_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_handle rdb_handle module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_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 :: LOC_H = 1

Tracer / thickness cell centre — extents (nx_total, ny_total).

integer, public, parameter :: LOC_Q = 4

Vorticity / corner point — extents (nx_total+1, ny_total+1).

integer, public, parameter :: LOC_U = 2

Arakawa-C u-face (west/east) — extents (nx_total+1, ny_total).

integer, public, parameter :: LOC_V = 3

Arakawa-C v-face (south/north) — extents (nx_total, ny_total+1).


Interfaces

public interface rdb_debug_chksum

Grid-location-aware checksum: derives the array extents from grid + loc (no hand-written bounds at the call site), runs the device-side reductions, and emits one CHKSUM row. Resolves by rank — 3D field trio / 2D BT-work variant.

  • private subroutine rdb_debug_chksum_3d(grid, arr, label, field, stage, step, probe, loc)

    Location-aware 3D checksum: derives (nx, ny) from grid + loc and nz from the array, so a new instrumentation site is one line with no hand-written bounds. Gated by the probe window.

    Arguments

    Type IntentOptional Attributes Name
    type(hgrid_t), intent(in) :: grid
    real(kind=wp), intent(in) :: arr(:,:,:)
    character(len=*), intent(in) :: label
    character(len=*), intent(in) :: field
    integer, intent(in) :: stage
    integer, intent(in) :: step
    type(chksum_probe_t), intent(inout) :: probe
    integer, intent(in) :: loc
  • private subroutine rdb_debug_chksum_2d(grid, arr, label, field, stage, step, probe, loc)

    2D twin of rdb_debug_chksum_3d (BT-work fields).

    Arguments

    Type IntentOptional Attributes Name
    type(hgrid_t), intent(in) :: grid
    real(kind=wp), intent(in) :: arr(:,:)
    character(len=*), intent(in) :: label
    character(len=*), intent(in) :: field
    integer, intent(in) :: stage
    integer, intent(in) :: step
    type(chksum_probe_t), intent(inout) :: probe
    integer, intent(in) :: loc

Derived Types

type, public ::  chksum_probe_t

Config + one-shot header state. Lives on ocean_dyn_t; host-only (never device-mapped).

Components

Type Visibility Attributes Name Initial
logical, public :: enable = .false.

Master gate — &ocean_debug_nml chksum.

integer, public :: end_step = 0

Last outer step to sample (0 = no upper bound).

logical, public :: header_done = .false.

Column-header row emitted.

logical, public :: interior = .false.

Restrict every reduction to PHYSICAL cells (exclude the whole ghost ring). Default .false. = legacy whole-array behaviour, so existing logs are unchanged.

Read more…
integer, public :: start_step = 0

First outer step to sample (0 = from the start).

type, public ::  chksum_stats_t

One field’s reduction bundle.

Components

Type Visibility Attributes Name Initial
integer(kind=int64), public :: bits = 0_int64

Decomposition-invariant bitcount: the wrapped int64 sum of POPCNT over the IEEE-754 bit pattern of every reduced element. Unlike the FP total (only stable within one binary), integer addition is EXACTLY associative + commutative, so this is identical across rank counts and loop orders — the authoritative log-diff signal for a decomposition / halo bug.

real(kind=wp), public :: maxv = 0.0_wp

NaN-blind extrema (see module docstring).

real(kind=wp), public :: minv = 0.0_wp
integer, public :: nonfin = 0

Count of non-finite entries — the corruption signal.

real(kind=wp), public :: total = 0.0_wp

Plain (non-compensated) sum — bitwise-stable per build, so log-diffable between two runs of the SAME binary; NaN when the field is contaminated.


Functions

public pure function chksum_active(probe, step) result(active)

Gate: enabled AND inside the step window.

Arguments

Type IntentOptional Attributes Name
type(chksum_probe_t), intent(in) :: probe
integer, intent(in) :: step

Return Value logical


Subroutines

public pure subroutine chksum_argmax(arr, n1, n2, n3, i0, i1, j0, j1, im, jm, km, amax)

Interior argmax of |arr|: first-encountered strict maximum over i ∈ [i0, i1], j ∈ [j0, j1], all k (the ghost ring is excluded by the caller’s bounds). Host-side (debug-window cadence only).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: arr(n1,n2,n3)
integer, intent(in) :: n1
integer, intent(in) :: n2
integer, intent(in) :: n3
integer, intent(in) :: i0
integer, intent(in) :: i1
integer, intent(in) :: j0
integer, intent(in) :: j1
integer, intent(out) :: im
integer, intent(out) :: jm
integer, intent(out) :: km
real(kind=wp), intent(out) :: amax

public subroutine chksum_bt(grid, bt_work, probe, label, stage, step)

Sample the BT substep’s 2D in/out fields at the fold seam: the fold delta is bt_ubt_end - ubt_at_n - dt*F_bt_u, so these four (+ eta) name which INPUT went non-finite when the fold’s loud count fires — the “what fed it” the nan-catch cannot see.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(in) :: bt_work
type(chksum_probe_t), intent(inout) :: probe
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: step

public subroutine chksum_hotface(grid, ms, visc_rem_u, visc_rem_v, probe, label, stage, step)

Hot-face anatomy at a phase seam: interior argmax |u| and |v| with the local thickness pair (donor/receiver cells), the per-face viscous remnant, and the column context (thickness of the layer below/above at the max face). The forensic question this answers: WHICH face takes the explicit dt·F kick, is it an outcrop edge (massive|vanished thickness pair), and is visc_rem actually small there (i.e. would MOM6’s attenuation have caught it)? Row format (grep “HOTFACE”): HOTFACE s

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: visc_rem_u(:,:,:)
real(kind=wp), intent(in) :: visc_rem_v(:,:,:)
type(chksum_probe_t), intent(inout) :: probe
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: step

public pure subroutine chksum_loc_extents(grid, loc, nx, ny)

Map a grid-location tag (LOC_{H,U,V,Q}) to the field’s 2D extents on the Arakawa-C grid — u/v faces carry the extra wall-normal row/column, the corner both. This is the single place the C-grid extent convention lives; call sites pass loc.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
integer, intent(in) :: loc
integer, intent(out) :: nx
integer, intent(out) :: ny

public subroutine chksum_state(grid, ms, probe, label, stage, step)

Sample the prognostics (h, u, v, every tracer) at a phase seam. Call AFTER the phase named by label; drains device queues first so the async apply chain has landed. Bounds come from the location-aware API (LOC_H / LOC_U / LOC_V), not hand-written.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(in) :: ms
type(chksum_probe_t), intent(inout) :: probe
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: step

public subroutine chksum_stats_2d(arr, nx, ny, stats, i0, i1, j0, j1)

2D twin of chksum_stats_3d (BT work fields).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: arr(nx,ny)
integer, intent(in) :: nx
integer, intent(in) :: ny
type(chksum_stats_t), intent(out) :: stats
integer, intent(in), optional :: i0

Optional index window (default: the whole array) — see the 3D twin.

integer, intent(in), optional :: i1

Optional index window (default: the whole array) — see the 3D twin.

integer, intent(in), optional :: j0

Optional index window (default: the whole array) — see the 3D twin.

integer, intent(in), optional :: j1

Optional index window (default: the whole array) — see the 3D twin.

public subroutine chksum_stats_3d(arr, nx, ny, nz, stats, i0, i1, j0, j1)

Device-side sum/min/max/nonfinite over an explicit-shape 3D field. No present clause: present_or_copyin reads the device copy in production and copies-in host data in unmapped unit tests (same convention as the BT fold’s loud count).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: arr(nx,ny,nz)
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
type(chksum_stats_t), intent(out) :: stats
integer, intent(in), optional :: i0

Optional index window (default: the whole array). Used by the probe’s interior mode to exclude the ghost ring.

integer, intent(in), optional :: i1

Optional index window (default: the whole array). Used by the probe’s interior mode to exclude the ghost ring.

integer, intent(in), optional :: j0

Optional index window (default: the whole array). Used by the probe’s interior mode to exclude the ghost ring.

integer, intent(in), optional :: j1

Optional index window (default: the whole array). Used by the probe’s interior mode to exclude the ghost ring.

private pure subroutine chksum_loc_interior(grid, loc, i0, i1, j0, j1)

Physical-cell index range for a grid-location tag: the ghost ring excluded. Face locations carry one MORE physical entry than cell centres in their staggered direction (an x-face array spans nx_phys + 1 faces), which is why LOC_U/LOC_Q extend i1 by one and LOC_V/LOC_Q extend j1.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
integer, intent(in) :: loc
integer, intent(out) :: i0
integer, intent(out) :: i1
integer, intent(out) :: j0
integer, intent(out) :: j1

private subroutine chksum_row(probe, label, stage, step, field, stats)

Emit one CHKSUM row (write(*,…) like the KE_ATTR probe — probe output bypasses the logger by design: greppable, no prefix, survives logger-level filtering).

Arguments

Type IntentOptional Attributes Name
type(chksum_probe_t), intent(inout) :: probe
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: step
character(len=*), intent(in) :: field
type(chksum_stats_t), intent(in) :: stats

private subroutine hotface_row(label, stage, step, comp, i, j, k, val, h_left, h_right, rem, h_dn, h_up)

One HOTFACE row (see chksum_hotface docstring for columns).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: step
character(len=*), intent(in) :: comp
integer, intent(in) :: i
integer, intent(in) :: j
integer, intent(in) :: k
real(kind=wp), intent(in) :: val
real(kind=wp), intent(in) :: h_left
real(kind=wp), intent(in) :: h_right
real(kind=wp), intent(in) :: rem
real(kind=wp), intent(in) :: h_dn
real(kind=wp), intent(in) :: h_up

private subroutine rdb_debug_chksum_2d(grid, arr, label, field, stage, step, probe, loc)

2D twin of rdb_debug_chksum_3d (BT-work fields).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: arr(:,:)
character(len=*), intent(in) :: label
character(len=*), intent(in) :: field
integer, intent(in) :: stage
integer, intent(in) :: step
type(chksum_probe_t), intent(inout) :: probe
integer, intent(in) :: loc

private subroutine rdb_debug_chksum_3d(grid, arr, label, field, stage, step, probe, loc)

Location-aware 3D checksum: derives (nx, ny) from grid + loc and nz from the array, so a new instrumentation site is one line with no hand-written bounds. Gated by the probe window.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: arr(:,:,:)
character(len=*), intent(in) :: label
character(len=*), intent(in) :: field
integer, intent(in) :: stage
integer, intent(in) :: step
type(chksum_probe_t), intent(inout) :: probe
integer, intent(in) :: loc