An order-invariant fixed-point value: Sum_n v(n) * pr(n). The
component is PUBLIC (unlike MOM6’s private EFP_type%v) so the
comm facade (halo_allreduce_efp_list) can pack/unpack it without
an accessor procedure – Roundabout splits the arithmetic module
(here) from the collective (in src/comm/), so the layering
requires v to be reachable from both. Tests asserting bit-
identity compare v(:) directly, never the reconstructed real.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=int64), | public | :: | poison | = | 0_int64 |
Non-finite “poison” counter – the number of NaN / +-Inf /
bin-1-overflow summands folded into this value so far (0 =
clean). |
|
| integer(kind=int64), | public | :: | v(EFP_DIGITS) | = | 0_int64 |
type :: efp_t !! An order-invariant fixed-point value: `Sum_n v(n) * pr(n)`. The !! component is PUBLIC (unlike MOM6's private `EFP_type%v`) so the !! comm facade (`halo_allreduce_efp_list`) can pack/unpack it without !! an accessor procedure -- Roundabout splits the arithmetic module !! (here) from the collective (in `src/comm/`), so the layering !! requires `v` to be reachable from both. Tests asserting bit- !! identity compare `v(:)` directly, never the reconstructed real. integer(int64) :: v(EFP_DIGITS) = 0_int64 integer(int64) :: poison = 0_int64 !! Non-finite "poison" counter -- the number of NaN / +-Inf / !! bin-1-overflow summands folded into this value so far (0 = !! clean). `efp_decompose`/`efp_from_real` seed it from `is_nan !! .or. is_ovf`; `efp_plus`/`efp_minus` add it forward (never !! reset it); `efp_to_real` returns a quiet NaN whenever it is !! nonzero, INSTEAD OF reconstructing a value from `v(:)`. This !! is the fix for the EFP fixed-point path laundering a non-finite !! summand into a plausible finite number (0 comes out of a NaN !! decompose's zeroed bins, a saturated bin 1 comes out of an !! overflowing one) -- the exact hazard class CLAUDE.md's !! NaN-blind-clamp gotcha describes, just in the reduction layer !! instead of a clamp. `efp_to_transport`/`efp_from_transport` !! carry it in the SAME collective as the bins (see !! `EFP_TRANSPORT_WIDTH`), summed by the same `MPI_SUM`: one !! poisoned rank makes the transported count nonzero on every !! rank, so every rank's `efp_to_real` reports NaN identically -- !! never a rank-dependent branch. A plain count (not a saturating !! flag) because it costs nothing extra (still an exact double !! under `MPI_SUM` at any realistic magnitude) and is simpler to !! reason about than a boolean OR chain. end type efp_t