ocean_halo_buffers_ensure_nz Subroutine

private 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.

Arguments

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

Number of vertical layers required


Calls

proc~~ocean_halo_buffers_ensure_nz~~CallsGraph proc~ocean_halo_buffers_ensure_nz ocean_halo_buffers_ensure_nz to_string to_string proc~ocean_halo_buffers_ensure_nz->to_string warning warning proc~ocean_halo_buffers_ensure_nz->warning

Called by

proc~~ocean_halo_buffers_ensure_nz~~CalledByGraph proc~ocean_halo_buffers_ensure_nz ocean_halo_buffers_ensure_nz proc~ocean_halo_centre_3d ocean_halo_centre_3d proc~ocean_halo_centre_3d->proc~ocean_halo_buffers_ensure_nz proc~ocean_halo_face_x_3d ocean_halo_face_x_3d proc~ocean_halo_face_x_3d->proc~ocean_halo_buffers_ensure_nz proc~ocean_halo_face_y_3d ocean_halo_face_y_3d proc~ocean_halo_face_y_3d->proc~ocean_halo_buffers_ensure_nz interface~ocean_halo_centre ocean_halo_centre interface~ocean_halo_centre->proc~ocean_halo_centre_3d interface~ocean_halo_face_x ocean_halo_face_x interface~ocean_halo_face_x->proc~ocean_halo_face_x_3d interface~ocean_halo_face_y ocean_halo_face_y interface~ocean_halo_face_y->proc~ocean_halo_face_y_3d proc~barotropic_substep_nonlinear barotropic_substep_nonlinear proc~barotropic_substep_nonlinear->interface~ocean_halo_face_x proc~configure_ocean_closed_faces configure_ocean_closed_faces proc~configure_ocean_closed_faces->interface~ocean_halo_face_x proc~configure_ocean_closed_faces->interface~ocean_halo_face_y proc~configure_ocean_k_bot configure_ocean_k_bot proc~configure_ocean_k_bot->interface~ocean_halo_face_x proc~configure_ocean_k_bot->interface~ocean_halo_face_y proc~configure_ocean_land_mask configure_ocean_land_mask proc~configure_ocean_land_mask->interface~ocean_halo_centre proc~continuity_gm_apply continuity_gm_apply proc~continuity_gm_apply->interface~ocean_halo_centre proc~continuity_tracer_step_split continuity_tracer_step_split proc~continuity_tracer_step_split->interface~ocean_halo_centre proc~engine_enter_data engine_enter_data proc~engine_enter_data->interface~ocean_halo_face_x proc~ocean_halo_exchange_ml_state ocean_halo_exchange_ml_state proc~engine_enter_data->proc~ocean_halo_exchange_ml_state proc~engine_setup engine_setup proc~engine_setup->interface~ocean_halo_centre proc~engine_setup->interface~ocean_halo_face_x proc~engine_setup->proc~configure_ocean_closed_faces proc~engine_setup->proc~configure_ocean_k_bot proc~engine_setup->proc~configure_ocean_land_mask proc~engine_setup->proc~ocean_halo_exchange_ml_state proc~configure_ocean_forcing configure_ocean_forcing proc~engine_setup->proc~configure_ocean_forcing proc~ocean_data_forcing_configure ocean_data_forcing_configure proc~engine_setup->proc~ocean_data_forcing_configure proc~ocean_halo_exchange_ice_state ocean_halo_exchange_ice_state proc~engine_setup->proc~ocean_halo_exchange_ice_state proc~ice_evp_dynamics_impl ice_evp_dynamics_impl proc~ice_evp_dynamics_impl->interface~ocean_halo_face_x proc~ice_evp_dynamics_impl->interface~ocean_halo_face_y proc~ice_halo_centre_flat ice_halo_centre_flat proc~ice_halo_centre_flat->interface~ocean_halo_centre proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->interface~ocean_halo_centre proc~run_stage_split run_stage_split proc~ocean_dyn_step_split->proc~run_stage_split proc~run_gm_step run_gm_step proc~ocean_dyn_step_split->proc~run_gm_step proc~ocean_halo_exchange_ice_fluxes ocean_halo_exchange_ice_fluxes proc~ocean_halo_exchange_ice_fluxes->interface~ocean_halo_centre proc~ocean_halo_exchange_ml_state->interface~ocean_halo_centre proc~ocean_halo_exchange_ml_state->interface~ocean_halo_face_x proc~ocean_halo_exchange_ml_state->interface~ocean_halo_face_y proc~ocean_seam_refresh_surface_stress ocean_seam_refresh_surface_stress proc~ocean_seam_refresh_surface_stress->interface~ocean_halo_face_x proc~ocean_seam_refresh_surface_stress->interface~ocean_halo_face_y proc~refresh_tracer_ghosts refresh_tracer_ghosts proc~refresh_tracer_ghosts->interface~ocean_halo_centre proc~run_continuity_chain run_continuity_chain proc~run_continuity_chain->interface~ocean_halo_centre proc~run_continuity_chain->proc~continuity_tracer_step_split proc~run_continuity_chain->proc~ocean_halo_exchange_ml_state proc~run_continuity_chain->proc~refresh_tracer_ghosts proc~run_stage_split->interface~ocean_halo_centre proc~run_stage_split->interface~ocean_halo_face_x proc~run_stage_split->interface~ocean_halo_face_y proc~run_stage_split->proc~ocean_halo_exchange_ml_state proc~run_stage_split->proc~refresh_tracer_ghosts proc~run_stage_split->proc~run_continuity_chain proc~barotropic_substep_nonlinear_interior barotropic_substep_nonlinear_interior proc~run_stage_split->proc~barotropic_substep_nonlinear_interior proc~bt_wide_substep bt_wide_substep proc~run_stage_split->proc~bt_wide_substep proc~visc_rem_precompute visc_rem_precompute proc~run_stage_split->proc~visc_rem_precompute proc~vmix_apply_in_stage vmix_apply_in_stage proc~run_stage_split->proc~vmix_apply_in_stage proc~visc_rem_halo_refresh visc_rem_halo_refresh proc~visc_rem_halo_refresh->interface~ocean_halo_face_x proc~visc_rem_halo_refresh->interface~ocean_halo_face_y proc~barotropic_substep_nonlinear_interior->proc~barotropic_substep_nonlinear proc~bt_wide_substep->proc~barotropic_substep_nonlinear proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_enter_data proc~complete_ocean_create->proc~engine_setup proc~configure_ocean_forcing->proc~ocean_seam_refresh_surface_stress proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_enter_data proc~driver_run_ocean->proc~engine_setup proc~engine_step engine_step proc~driver_run_ocean->proc~engine_step proc~engine_step_ice engine_step_ice proc~driver_run_ocean->proc~engine_step_ice proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~engine_step->proc~ocean_dyn_step_split proc~ocean_data_forcing_apply ocean_data_forcing_apply proc~engine_step->proc~ocean_data_forcing_apply proc~engine_step_ice->proc~ocean_halo_exchange_ice_fluxes proc~ice_ocean_stress_flux ice_ocean_stress_flux proc~engine_step_ice->proc~ice_ocean_stress_flux proc~engine_step_ice->proc~ocean_halo_exchange_ice_state proc~ice_evp_dynamics ice_evp_dynamics proc~ice_evp_dynamics->proc~ice_evp_dynamics_impl proc~ice_ocean_stress_flux->proc~ocean_seam_refresh_surface_stress proc~ocean_data_forcing_apply->proc~ocean_seam_refresh_surface_stress proc~ocean_data_forcing_configure->proc~ocean_seam_refresh_surface_stress proc~ocean_halo_exchange_ice_state->proc~ice_halo_centre_flat proc~ocean_halo_exchange_ice_transport ocean_halo_exchange_ice_transport proc~ocean_halo_exchange_ice_transport->proc~ice_halo_centre_flat proc~run_gm_step->proc~continuity_gm_apply proc~run_gm_step->proc~ocean_halo_exchange_ml_state proc~run_stage run_stage proc~run_stage->proc~continuity_tracer_step_split proc~run_stage->proc~vmix_apply_in_stage proc~visc_rem_precompute->proc~visc_rem_halo_refresh proc~vmix_apply_in_stage->proc~visc_rem_halo_refresh proc~vmix_apply_in_stage->proc~visc_rem_precompute proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~ice_evp_step ice_evp_step proc~ice_evp_step->proc~ice_evp_dynamics proc~ice_transport_step ice_transport_step proc~ice_transport_step->proc~ocean_halo_exchange_ice_transport proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage 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 proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~rdb_ocean_step->proc~engine_step_ice

Variables

Type Visibility Attributes Name Initial
integer, private :: need_ew
integer, private :: need_ns

Source Code

   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