Grow the persistent send/recv buffers to hold at least nz layers. Called at the top of each 3D exchange routine before pack/unpack. The 2D routines use the same buffers and always need <= any 3D capacity, so they are unaffected.
Grow policy: exit data delete → deallocate → reallocate at new capacity → enter data create. The current 2D capacity (initialised in ocean_halo_init as (ng+1)ny_total / (ng+1)nx_total) covers nz=1; any call with nz>1 that needs more space triggers a one-time grow.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nz |
Number of vertical layers required |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | need_ew | ||||
| integer, | private | :: | need_ns |
subroutine ocean_halo_buffers_ensure_nz(nz) !! Grow the persistent send/recv buffers to hold at least nz layers. !! Called at the top of each 3D exchange routine before pack/unpack. !! The 2D routines use the same buffers and always need <= any 3D !! capacity, so they are unaffected. !! !! Grow policy: exit data delete → deallocate → reallocate at new !! capacity → enter data create. The current 2D capacity (initialised !! in ocean_halo_init as (ng+1)*ny_total / (ng+1)*nx_total) covers nz=1; !! any call with nz>1 that needs more space triggers a one-time grow. integer, intent(in) :: nz !! Number of vertical layers required integer :: need_ew, need_ns ! Worst-case 3D capacity: ! E/W: face-x send-east uses (ng+1)*nyt per layer ⇒ (ng+1)*nyt*nz ! N/S: face-y send-north uses (ng+1)*nxt per layer ⇒ (ng+1)*nxt*nz need_ew = (oh_nghost + 1)*oh_ny_total*nz need_ns = (oh_nghost + 1)*oh_nx_total*nz if (need_ew <= oh_cap_ew .and. need_ns <= oh_cap_ns) return call logger%warning("ocean_halo_buffers_ensure_nz: growing halo buffers "// & "mid-run (E/W: "//to_string(oh_cap_ew)//" -> "// & to_string(need_ew)//", N/S: "//to_string(oh_cap_ns)//" -> "// & to_string(need_ns)//"). "// & "Call ocean_halo_reserve(nz, ng_wide) at init to avoid "// & "a mid-run device reallocation (breaks UCX IPC handle reuse).") ! Grow E/W buffers if needed 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 buffers 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_buffers_ensure_nz