Print profiling report If root_region is specified, percentages are relative to that region
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in), | optional | :: | title | ||
| character(len=*), | intent(in), | optional | :: | root_region |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| character(len=256), | private | :: | line | ||||
| integer, | private | :: | n_print | ||||
| real(kind=dp), | private | :: | pct | ||||
| integer, | private | :: | root_idx | ||||
| integer, | private | :: | sorted_idx(MAX_REGIONS) | ||||
| integer, | private | :: | tmp_idx | ||||
| real(kind=dp), | private | :: | total_time |
subroutine profiler_report(title, root_region) !! Print profiling report !! If root_region is specified, percentages are relative to that region character(len=*), intent(in), optional :: title character(len=*), intent(in), optional :: root_region integer :: i, j, root_idx, n_print, tmp_idx integer :: sorted_idx(MAX_REGIONS) real(dp) :: total_time, pct character(len=256) :: line if (state%num_regions == 0) return root_idx = -1 if (present(root_region)) then do i = 1, state%num_regions if (trim(state%regions(i)%name) == trim(root_region)) then root_idx = i exit end if end do end if if (root_idx > 0) then total_time = state%regions(root_idx)%total_time else total_time = 0.0_dp do i = 1, state%num_regions total_time = total_time + state%regions(i)%total_time end do end if n_print = 0 do i = 1, state%num_regions if (i /= root_idx .and. .not. state%regions(i)%nvtx_only) then n_print = n_print + 1 sorted_idx(n_print) = i end if end do ! Sort by time descending (insertion sort) do i = 2, n_print tmp_idx = sorted_idx(i) j = i - 1 ! Guard the sorted_idx(j) read with a SEPARATE bounds check: Fortran ! does not short-circuit `.and.`, so a combined ! `do while (j >= 1 .and. ...sorted_idx(j)...)` reads sorted_idx(0) ! when j reaches 0 (OOB — aborts under -fcheck=bounds). do if (j < 1) exit if (state%regions(sorted_idx(j))%total_time >= & state%regions(tmp_idx)%total_time) exit sorted_idx(j + 1) = sorted_idx(j) j = j - 1 end do sorted_idx(j + 1) = tmp_idx end do call logger%info("") call logger%info("============================================================") if (present(title)) then call logger%info("Profiler Report: "//trim(title)) else call logger%info("Profiler Report") end if call logger%info("============================================================") call logger%info(" Region Time (s) Calls % ") call logger%info("------------------------------------------------------------") do i = 1, n_print j = sorted_idx(i) if (total_time > 0.0_dp) then pct = 100.0_dp*state%regions(j)%total_time/total_time else pct = 0.0_dp end if write (line, "(A,A32,F12.6,I8,F8.1)") " ", & state%regions(j)%name, & state%regions(j)%total_time, & state%regions(j)%call_count, & pct call logger%info(trim(line)) end do call logger%info("------------------------------------------------------------") write (line, "(A,F12.6)") " Total: ", total_time call logger%info(trim(line)) call logger%info("============================================================") #ifdef USE_NVTX call logger%info(" (NVTX enabled - use Nsight Systems for GPU timeline)") #else call logger%info(" (NVTX disabled - compile with -DRDB_ENABLE_NVTX to enable)") #endif end subroutine profiler_report