compute_total_h_efp Function

private function compute_total_h_efp(h_layer, areaT, nghost) result(total)

EFP twin of compute_total_h: order-invariant fixed-point Sigma h_layer*areaT over PHYSICAL cells. K-SLAB BLOCKED: a host loop over k, one device reduction(+:e1..e6) per slab, then a host-side efp_carry combining the slab into the running total – keeps each device reduction block within EFP_MAX_SUMMANDS (SS3.3/SS6.3 of the plan; MOM6’s i/j block-partition arithmetic is NOT ported – the k-slab is simpler and sufficient at EFP_PREC_WIDTH = 36). Ghost exclusion + extent clamping copied VERBATIM from compute_total_h – a divergence here would silently change what is summed between the FP and EFP paths.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: h_layer(:,:,:)
real(kind=wp), intent(in) :: areaT(:,:)
integer, intent(in) :: nghost

Return Value type(efp_t)


Calls

proc~~compute_total_h_efp~~CallsGraph proc~compute_total_h_efp compute_total_h_efp proc~efp_carry efp_carry proc~compute_total_h_efp->proc~efp_carry proc~efp_decompose_impl efp_decompose_impl proc~compute_total_h_efp->proc~efp_decompose_impl proc~efp_summands_guard efp_summands_guard proc~compute_total_h_efp->proc~efp_summands_guard error error proc~efp_summands_guard->error

Called by

proc~~compute_total_h_efp~~CalledByGraph proc~compute_total_h_efp compute_total_h_efp proc~ocean_console_stats_report ocean_console_stats_report proc~ocean_console_stats_report->proc~compute_total_h_efp proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~ocean_console_stats_report proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer(kind=int64), private :: d1
integer(kind=int64), private :: d2
integer(kind=int64), private :: d3
integer(kind=int64), private :: d4
integer(kind=int64), private :: d5
integer(kind=int64), private :: d6
integer(kind=int64), private :: dpoison
integer(kind=int64), private :: e1
integer(kind=int64), private :: e2
integer(kind=int64), private :: e3
integer(kind=int64), private :: e4
integer(kind=int64), private :: e5
integer(kind=int64), private :: e6
integer(kind=int64), private :: epoison
integer, private :: i
integer, private :: i_hi
integer, private :: i_lo
integer, private :: j
integer, private :: j_hi
integer, private :: j_lo
integer, private :: k
integer, private :: nx
integer, private :: ny
integer, private :: nz
integer(kind=int64), private :: slab_e(EFP_DIGITS)
real(kind=real64), private :: val

Source Code

   function compute_total_h_efp(h_layer, areaT, nghost) result(total)
      !! EFP twin of `compute_total_h`: order-invariant fixed-point
      !! Sigma h_layer*areaT over PHYSICAL cells.  K-SLAB BLOCKED: a host
      !! loop over `k`, one device `reduction(+:e1..e6)` per slab, then a
      !! host-side `efp_carry` combining the slab into the running total
      !! -- keeps each device reduction block within `EFP_MAX_SUMMANDS`
      !! (SS3.3/SS6.3 of the plan; MOM6's i/j block-partition arithmetic is
      !! NOT ported -- the k-slab is simpler and sufficient at
      !! `EFP_PREC_WIDTH = 36`).  Ghost exclusion + extent clamping copied
      !! VERBATIM from `compute_total_h` -- a divergence here would
      !! silently change what is summed between the FP and EFP paths.
      real(wp), intent(in) :: h_layer(:, :, :)
      real(wp), intent(in) :: areaT(:, :)
      integer, intent(in) :: nghost
      type(efp_t) :: total
      integer :: i, j, k, nx, ny, nz, i_lo, i_hi, j_lo, j_hi
      integer(int64) :: e1, e2, e3, e4, e5, e6, epoison
      integer(int64) :: d1, d2, d3, d4, d5, d6, dpoison
      integer(int64) :: slab_e(EFP_DIGITS)
      real(real64) :: val

      nx = min(size(h_layer, 1), size(areaT, 1))
      ny = min(size(h_layer, 2), size(areaT, 2))
      nz = size(h_layer, 3)
      i_lo = nghost + 1
      i_hi = nx - nghost
      j_lo = nghost + 1
      j_hi = ny - nghost
      call efp_summands_guard(i_hi - i_lo + 1, j_hi - j_lo + 1, "compute_total_h_efp")

      total%v = 0_int64
      total%poison = 0_int64
      do k = 1, nz
         e1 = 0_int64
         e2 = 0_int64
         e3 = 0_int64
         e4 = 0_int64
         e5 = 0_int64
         e6 = 0_int64
         epoison = 0_int64
         !$acc parallel loop collapse(2) reduction(+:e1,e2,e3,e4,e5,e6,epoison) &
         !$acc&         private(val, d1, d2, d3, d4, d5, d6, dpoison) present(h_layer, areaT)
         do j = j_lo, j_hi
            do i = i_lo, i_hi
               val = real(h_layer(i, j, k), real64)*real(areaT(i, j), real64)
               call efp_decompose_impl(val, d1, d2, d3, d4, d5, d6, dpoison)
               e1 = e1 + d1
               e2 = e2 + d2
               e3 = e3 + d3
               e4 = e4 + d4
               e5 = e5 + d5
               e6 = e6 + d6
               epoison = epoison + dpoison
            end do
         end do
         slab_e = [e1, e2, e3, e4, e5, e6]
         call efp_carry(slab_e)
         total%v = total%v + slab_e
         call efp_carry(total%v)
         total%poison = total%poison + epoison
      end do
   end function compute_total_h_efp