scratch_3d_buffer_enter_data_impl Subroutine

public subroutine scratch_3d_buffer_enter_data_impl(this)

Attach the scratch payload to the device holding the HOST payload: zero from init (allocate(..., source = 0.0_wp)), or whatever a warm-restart read restored into it before the map. The zero half is a contract, not an implementation detail: a consumer whose producer was SKIPPED this step is entitled to read zero on a cold start, and it must read zero on BOTH toolchains (see the inline note below for the pred_corr predictor that does exactly that). type(...) (not class) dummy on purpose: a by-reference non-polymorphic dummy aliases the heap object, so copyin(this%data) attaches against a heap base — no polymorphic stack box for AMD to reject.

No-op when the payload was never allocated. Slots may GATE a buffer’s init on a runtime knob (see ocean_pressure_force_t%scratch_gated) and still call this unconditionally from their enter_data walk; mapping an unallocated allocatable is not defined behaviour, so the guard lives here rather than at each call site.

Arguments

Type IntentOptional Attributes Name
type(scratch_3d_buffer_t), intent(inout) :: this

Called by

proc~~scratch_3d_buffer_enter_data_impl~~CalledByGraph proc~scratch_3d_buffer_enter_data_impl scratch_3d_buffer_enter_data_impl proc~continuity_enter_data_impl continuity_enter_data_impl proc~continuity_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~coriolis_adv_enter_data_impl coriolis_adv_enter_data_impl proc~coriolis_adv_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_bdrag_enter_data_impl ocean_bdrag_enter_data_impl proc~ocean_bdrag_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_epbl_enter_data_impl ocean_epbl_enter_data_impl proc~ocean_epbl_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_hdiff_tracer_enter_data_impl ocean_hdiff_tracer_enter_data_impl proc~ocean_hdiff_tracer_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_hvisc_enter_data_impl ocean_hvisc_enter_data_impl proc~ocean_hvisc_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_lateral_mix_enter_data_impl ocean_lateral_mix_enter_data_impl proc~ocean_lateral_mix_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_pressure_force_enter_data_impl ocean_pressure_force_enter_data_impl proc~ocean_pressure_force_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_surfstress_enter_data_impl ocean_surfstress_enter_data_impl proc~ocean_surfstress_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_top_drag_enter_data_impl ocean_top_drag_enter_data_impl proc~ocean_top_drag_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_vdiff_enter_data_impl ocean_vdiff_enter_data_impl proc~ocean_vdiff_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~ocean_vert_adv_enter_data_impl ocean_vert_adv_enter_data_impl proc~ocean_vert_adv_enter_data_impl->proc~scratch_3d_buffer_enter_data_impl proc~scratch_3d_buffer_enter_data scratch_3d_buffer_t%scratch_3d_buffer_enter_data proc~scratch_3d_buffer_enter_data->proc~scratch_3d_buffer_enter_data_impl proc~continuity_enter_data continuity_t%continuity_enter_data proc~continuity_enter_data->proc~continuity_enter_data_impl proc~coriolis_adv_enter_data coriolis_adv_t%coriolis_adv_enter_data proc~coriolis_adv_enter_data->proc~coriolis_adv_enter_data_impl proc~ocean_bdrag_enter_data ocean_bottom_drag_t%ocean_bdrag_enter_data proc~ocean_bdrag_enter_data->proc~ocean_bdrag_enter_data_impl proc~ocean_epbl_enter_data ocean_epbl_t%ocean_epbl_enter_data proc~ocean_epbl_enter_data->proc~ocean_epbl_enter_data_impl proc~ocean_hdiff_tracer_enter_data ocean_hdiff_tracer_t%ocean_hdiff_tracer_enter_data proc~ocean_hdiff_tracer_enter_data->proc~ocean_hdiff_tracer_enter_data_impl proc~ocean_hvisc_enter_data ocean_horizontal_viscosity_t%ocean_hvisc_enter_data proc~ocean_hvisc_enter_data->proc~ocean_hvisc_enter_data_impl proc~ocean_lateral_mix_enter_data ocean_lateral_mix_t%ocean_lateral_mix_enter_data proc~ocean_lateral_mix_enter_data->proc~ocean_lateral_mix_enter_data_impl proc~ocean_pressure_force_enter_data ocean_pressure_force_t%ocean_pressure_force_enter_data proc~ocean_pressure_force_enter_data->proc~ocean_pressure_force_enter_data_impl proc~ocean_surfstress_enter_data ocean_surface_stress_t%ocean_surfstress_enter_data proc~ocean_surfstress_enter_data->proc~ocean_surfstress_enter_data_impl proc~ocean_top_drag_enter_data ocean_top_drag_t%ocean_top_drag_enter_data proc~ocean_top_drag_enter_data->proc~ocean_top_drag_enter_data_impl proc~ocean_vdiff_enter_data ocean_vdiff_t%ocean_vdiff_enter_data proc~ocean_vdiff_enter_data->proc~ocean_vdiff_enter_data_impl proc~ocean_vert_adv_enter_data ocean_vertical_advection_t%ocean_vert_adv_enter_data proc~ocean_vert_adv_enter_data->proc~ocean_vert_adv_enter_data_impl

Source Code

   subroutine scratch_3d_buffer_enter_data_impl(this)
      !! Attach the scratch payload to the device holding the HOST
      !! payload: zero from `init` (`allocate(..., source = 0.0_wp)`), or
      !! whatever a warm-restart read restored into it before the map.
      !! The zero half is a contract, not an implementation detail: a
      !! consumer whose producer was SKIPPED this step is entitled to read
      !! zero on a cold start, and it must read zero on BOTH toolchains
      !! (see the inline note below for the `pred_corr` predictor that
      !! does exactly that).  `type(...)` (not `class`) dummy on purpose:
      !! a by-reference non-polymorphic dummy aliases the heap object, so
      !! `copyin(this%data)` attaches against a heap base — no polymorphic
      !! stack box for AMD to reject.
      !!
      !! No-op when the payload was never allocated.  Slots may GATE a
      !! buffer's `init` on a runtime knob (see
      !! `ocean_pressure_force_t%scratch_gated`) and still call this
      !! unconditionally from their `enter_data` walk; mapping an
      !! unallocated allocatable is not defined behaviour, so the guard
      !! lives here rather than at each call site.
      type(scratch_3d_buffer_t), intent(inout) :: this
      if (.not. allocated(this%data)) return
      ! `copyin`, not `create`: `create` attaches UNINITIALISED device
      ! memory, so the zero `init` put in the host allocation never
      ! crosses.  Most consumers write every element before reading, but
      ! a producer is allowed to be SKIPPED for a step and leave its
      ! buffer to be read as "what the previous step produced" — MOM6's
      ! predictor does exactly that with `diffu` (`split_scheme =
      ! "pred_corr"` skips the viscous recompute in stage 1), and on step
      ! 1 there is no previous producer.  On `-gpu=...,mem:separate` a
      ! bare `create` yielded whatever the allocator handed back, which is
      ! why a uniform, perfectly balanced periodic jet once acquired an
      ! O(0.25 m/s²) viscous tendency out of nothing.  The fix for that
      ! was a device-side zero-fill after the `create`; it is `copyin` now
      ! because those buffers are also RESTART state (`hvisc_du_visc`/
      ! `hvisc_dv_visc` in `ocean_state_build_restart_registry`), and the
      ! restart read lands on the host BEFORE the map — a zero-fill wiped
      ! the restored tendency on both toolchains (host builds run the
      ! `do concurrent` on the host array itself), so the first
      ! post-restart predictor ran with no lateral viscosity in any column.
      ! One H2D of each buffer at setup; nothing per step.
      !$acc enter data copyin(this%data)
   end subroutine scratch_3d_buffer_enter_data_impl