Pack a list of efp_t values into a flat
real64(EFP_TRANSPORT_WIDTH*n) buffer for a single collective
(halo_allreduce_efp_list). Each bin, PLUS the poison counter,
is transported as an EXACTLY-representable double (see
EFP_MAX_RANKS):
buf((i-1)*EFP_TRANSPORT_WIDTH + n) = real(list(i)%v(n)) for
n = 1..EFP_DIGITS, and
buf((i-1)*EFP_TRANSPORT_WIDTH + EFP_DIGITS+1) = real(list(i)%poison).
Summing poison through the SAME MPI_SUM collective as the bins
is what makes a poisoned rank’s contribution reach every other
rank identically – see efp_t’s docstring.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(efp_t), | intent(in) | :: | list(:) | |||
| real(kind=real64), | intent(out) | :: | buf(:) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | n |
pure subroutine efp_to_transport(list, buf) !! Pack a list of `efp_t` values into a flat !! `real64(EFP_TRANSPORT_WIDTH*n)` buffer for a single collective !! (`halo_allreduce_efp_list`). Each bin, PLUS the `poison` counter, !! is transported as an EXACTLY-representable double (see !! `EFP_MAX_RANKS`): !! `buf((i-1)*EFP_TRANSPORT_WIDTH + n) = real(list(i)%v(n))` for !! `n = 1..EFP_DIGITS`, and !! `buf((i-1)*EFP_TRANSPORT_WIDTH + EFP_DIGITS+1) = real(list(i)%poison)`. !! Summing `poison` through the SAME `MPI_SUM` collective as the bins !! is what makes a poisoned rank's contribution reach every other !! rank identically -- see `efp_t`'s docstring. type(efp_t), intent(in) :: list(:) real(real64), intent(out) :: buf(:) integer :: i, n do i = 1, size(list) do n = 1, EFP_DIGITS buf((i - 1)*EFP_TRANSPORT_WIDTH + n) = real(list(i)%v(n), real64) end do buf((i - 1)*EFP_TRANSPORT_WIDTH + EFP_DIGITS + 1) = real(list(i)%poison, real64) end do end subroutine efp_to_transport