Report device-memory growth since the post-enter_data
baseline. Two allocations land AFTER the setup-time report and
would otherwise stay invisible: the lazy first-call kernel
workspaces (*_workspace_ensure, ~33% of the coastal device
footprint) and the one-off CUDA runtime/kernel reservation at
first launch (GBs — module-header offset 3). Call this in the
end-of-run summary (prints usage + the “grew ~X after setup”
attribution, so even a 10-step run shows the true footprint)
and at the periodic status with quiet=.true. (no info lines).
The one-shot leak WARNING measures PROGRESSIVE growth — past
GROWTH_WARN_FRAC of the steady baseline latched at the first
post-setup sample — so the expected one-offs never trip it.
Silent no-op on CPU builds or when the baseline was never
latched.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | label | |||
| logical, | intent(in), | optional | :: | quiet |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=int64), | private | :: | growth_b | ||||
| logical, | private | :: | quiet_mode | ||||
| integer(kind=int64), | private | :: | used_b |
subroutine mem_log_device_growth(label, quiet) !! Report device-memory growth since the post-`enter_data` !! baseline. Two allocations land AFTER the setup-time report and !! would otherwise stay invisible: the lazy first-call kernel !! workspaces (`*_workspace_ensure`, ~33% of the coastal device !! footprint) and the one-off CUDA runtime/kernel reservation at !! first launch (GBs — module-header offset 3). Call this in the !! end-of-run summary (prints usage + the "grew ~X after setup" !! attribution, so even a 10-step run shows the true footprint) !! and at the periodic status with `quiet=.true.` (no info lines). !! The one-shot leak WARNING measures PROGRESSIVE growth — past !! `GROWTH_WARN_FRAC` of the steady baseline latched at the first !! post-setup sample — so the expected one-offs never trip it. !! Silent no-op on CPU builds or when the baseline was never !! latched. character(len=*), intent(in) :: label logical, intent(in), optional :: quiet integer(int64) :: used_b, growth_b logical :: quiet_mode quiet_mode = .false. if (present(quiet)) quiet_mode = quiet used_b = mem_device_used_bytes() if (used_b < 0_int64 .or. used_after_map < 0_int64) return growth_b = used_b - used_after_map if (.not. quiet_mode) then call logger%info("device memory in use: "//mem_format_bytes(used_b)// & " ("//trim(label)//")") if (growth_b > 0_int64) then call logger%info(" grew ~"//mem_format_bytes(growth_b)// & " after setup (lazy kernel workspaces + one-off "// & "CUDA kernel/runtime reservation)") end if end if if (used_steady < 0_int64) then ! First post-setup sample: the one-off reservations have landed; ! this is the steady baseline for progressive-growth (leak) ! detection. used_steady = used_b else if (.not. growth_warned .and. & real(used_b - used_steady, wp) > & GROWTH_WARN_FRAC*real(used_steady, wp)) then call logger%warning("device memory grew ~"// & mem_format_bytes(used_b - used_steady)// & " past the steady post-setup baseline ("// & mem_format_bytes(used_steady)// & ") — possible device-memory leak ("//trim(label)//")") growth_warned = .true. end if end subroutine mem_log_device_growth