ocean_halo_reserve Subroutine

public subroutine ocean_halo_reserve(nz, ng_wide, ierr)

Pre-size the pack/recv buffers to the worst-case capacity for this run at init time, so that NO device reallocation fires mid-run.

Worst-case capacity derivation:

E/W buffers: (a) 2D face-x send-east: (ng+1)nyt (standard init) (b) batched 3D face-x: (ng+1)nytnz (ensure_nz path) (c) wide 2D face-x: (ng_wide+1)(ny_local+2*ng_wide) (ensure_wide path) worst = max(a, b, c)

N/S buffers: symmetric (transpose x↔y).

Call AFTER ocean_halo_init; calling before init is a programming error (error stop with a clear message). Passing nz = 0 or ng_wide = 0 means “not used” — those arms are skipped. If the computed capacity is already covered by the current allocation, this is a no-op.

Arguments

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

Layer count for 3D batched exchanges (0 = not used)

integer, intent(in) :: ng_wide

Wide-ghost width for the barotropic march-in (0 = not used)

integer, intent(out), optional :: ierr

Non-zero (OCEAN_STATUS_ERR_SETUP) when called before ocean_halo_init when present; absent behaves as today (error stop). (F5 residual, P2.4)


Calls

proc~~ocean_halo_reserve~~CallsGraph proc~ocean_halo_reserve ocean_halo_reserve proc~fail fail proc~ocean_halo_reserve->proc~fail error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push

Called by

proc~~ocean_halo_reserve~~CalledByGraph proc~ocean_halo_reserve ocean_halo_reserve proc~engine_setup engine_setup proc~engine_setup->proc~ocean_halo_reserve proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Variables

Type Visibility Attributes Name Initial
integer, private :: need_ew
integer, private :: need_ns
integer, private :: ng
integer, private :: nxl
integer, private :: nxt
integer, private :: nyl
integer, private :: nyt
integer, private :: w_ew
integer, private :: w_ns

Source Code

   subroutine ocean_halo_reserve(nz, ng_wide, ierr)
      !! Pre-size the pack/recv buffers to the worst-case capacity for this
      !! run at init time, so that NO device reallocation fires mid-run.
      !!
      !! Worst-case capacity derivation:
      !!
      !!   E/W buffers:
      !!     (a) 2D face-x send-east:  (ng+1)*nyt            (standard init)
      !!     (b) batched 3D face-x:    (ng+1)*nyt*nz          (ensure_nz path)
      !!     (c) wide 2D face-x:       (ng_wide+1)*(ny_local+2*ng_wide) (ensure_wide path)
      !!     worst = max(a, b, c)
      !!
      !!   N/S buffers: symmetric (transpose x↔y).
      !!
      !! Call AFTER ocean_halo_init; calling before init is a programming error
      !! (error stop with a clear message).  Passing nz = 0 or ng_wide = 0
      !! means "not used" — those arms are skipped.  If the computed capacity
      !! is already covered by the current allocation, this is a no-op.
      integer, intent(in) :: nz
         !! Layer count for 3D batched exchanges (0 = not used)
      integer, intent(in) :: ng_wide
         !! Wide-ghost width for the barotropic march-in (0 = not used)
      integer, intent(out), optional :: ierr
         !! Non-zero (`OCEAN_STATUS_ERR_SETUP`) when called before
         !! `ocean_halo_init` when present; absent behaves as today
         !! (`error stop`). (F5 residual, P2.4)

      integer :: need_ew, need_ns
      integer :: w_ew, w_ns
      integer :: ng, nyt, nxt, nyl, nxl

      if (present(ierr)) ierr = OCEAN_STATUS_OK
      if (.not. oh_initialised) then
         call fail("ocean_halo_reserve: called before ocean_halo_init. "// &
                   "Call ocean_halo_reserve immediately after ocean_halo_init.", &
                   ierr, OCEAN_STATUS_ERR_SETUP)
         return
      end if

      ng = oh_nghost
      nyt = oh_ny_total
      nxt = oh_nx_total
      nyl = oh_ny_local
      nxl = oh_nx_local

      ! (a) 2D base capacity (already set by init, replicated here for clarity)
      need_ew = (ng + 1)*nyt
      need_ns = (ng + 1)*nxt

      ! (b) 3D batched capacity
      if (nz > 0) then
         need_ew = max(need_ew, (ng + 1)*nyt*nz)
         need_ns = max(need_ns, (ng + 1)*nxt*nz)
      end if

      ! (c) Wide-ghost 2D capacity
      if (ng_wide > 0) then
         w_ew = (ng_wide + 1)*(nyl + 2*ng_wide)
         w_ns = (ng_wide + 1)*(nxl + 2*ng_wide)
         need_ew = max(need_ew, w_ew)
         need_ns = max(need_ns, w_ns)
      end if

      if (need_ew <= oh_cap_ew .and. need_ns <= oh_cap_ns) return

      ! Grow E/W if needed (exit-delete / dealloc / alloc / enter-create)
      if (need_ew > oh_cap_ew) then
         !$acc exit data delete(oh_buf_send_east, oh_buf_recv_east, &
         !$acc&                 oh_buf_send_west, oh_buf_recv_west)
         deallocate (oh_buf_send_east, oh_buf_recv_east)
         deallocate (oh_buf_send_west, oh_buf_recv_west)
         allocate (oh_buf_send_east(need_ew), oh_buf_recv_east(need_ew))
         allocate (oh_buf_send_west(need_ew), oh_buf_recv_west(need_ew))
         !$acc enter data create(oh_buf_send_east, oh_buf_recv_east, &
         !$acc&                  oh_buf_send_west, oh_buf_recv_west)
         oh_cap_ew = need_ew
      end if

      ! Grow N/S if needed
      if (need_ns > oh_cap_ns) then
         !$acc exit data delete(oh_buf_send_north, oh_buf_recv_north, &
         !$acc&                 oh_buf_send_south, oh_buf_recv_south)
         deallocate (oh_buf_send_north, oh_buf_recv_north)
         deallocate (oh_buf_send_south, oh_buf_recv_south)
         allocate (oh_buf_send_north(need_ns), oh_buf_recv_north(need_ns))
         allocate (oh_buf_send_south(need_ns), oh_buf_recv_south(need_ns))
         !$acc enter data create(oh_buf_send_north, oh_buf_recv_north, &
         !$acc&                  oh_buf_send_south, oh_buf_recv_south)
         oh_cap_ns = need_ns
      end if

   end subroutine ocean_halo_reserve