other/m_timer.F90
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | !> @brief Basic module for MPI-aware timing utilities | ||
| 2 | module m_timer | ||
| 3 | use m_common, only: wp, user_function_1d_interface | ||
| 4 | implicit none | ||
| 5 | |||
| 6 | private | ||
| 7 | public :: SmartTimer, TIMER_METRIC_MIN, TIMER_METRIC_AVG, TIMER_METRIC_MAX, TIMER_METRIC_ALL, TIMER_METRIC_TOTAL | ||
| 8 | |||
| 9 | ! Interface for macro use (see timer.fi as well as the CMake flag bspline_feec_TIMERS) | ||
| 10 | public :: MACRO_USE_ONLY_get_timer, MACRO_USE_ONLY_start_timer, MACRO_USE_ONLY_stop_timer | ||
| 11 | |||
| 12 | character(len=*), parameter :: TIMER_METRIC_MIN = 'min' | ||
| 13 | character(len=*), parameter :: TIMER_METRIC_AVG = 'avg' | ||
| 14 | character(len=*), parameter :: TIMER_METRIC_MAX = 'max' | ||
| 15 | character(len=*), parameter :: TIMER_METRIC_ALL = 'all' | ||
| 16 | character(len=*), parameter :: TIMER_METRIC_TOTAL = 'total' | ||
| 17 | |||
| 18 | type TimerPointer | ||
| 19 | type(SmartTimer), pointer :: p => null() | ||
| 20 | end type TimerPointer | ||
| 21 | |||
| 22 | !> @brief SmartTimer object to measure elapsed time | ||
| 23 | type SmartTimer | ||
| 24 | private | ||
| 25 | |||
| 26 | !> MPI communicator for the timer | ||
| 27 | integer :: comm | ||
| 28 | !> My rank in the communicator | ||
| 29 | integer :: my_rank | ||
| 30 | |||
| 31 | !> Starting time | ||
| 32 | real(wp) :: start_time | ||
| 33 | !> Ending time | ||
| 34 | real(wp) :: end_time | ||
| 35 | !> Elapsed time in seconds on this rank | ||
| 36 | real(wp) :: elapsed_time | ||
| 37 | !> Number of times the timer has been started | ||
| 38 | integer :: start_count | ||
| 39 | !> Elapsed time in seconds on all ranks | ||
| 40 | real(wp), allocatable :: elapsed_times(:) | ||
| 41 | !> User-defined timer name | ||
| 42 | character(len=:), allocatable :: name | ||
| 43 | !> Registry identifier for this timer | ||
| 44 | integer :: timer_id | ||
| 45 | !> Our ID (if allocated by us in get_timer) | ||
| 46 | integer, public :: our_timer_id = -1 | ||
| 47 | !> Whether the timer has been initialized | ||
| 48 | logical :: is_initialized = .false. | ||
| 49 | !> Whether the timer is currently running | ||
| 50 | logical :: is_running | ||
| 51 | !> Whether elapsed_times currently reflect elapsed_time | ||
| 52 | logical :: is_synced | ||
| 53 | !> Child timers in the timing tree | ||
| 54 | type(TimerPointer), allocatable :: children(:) | ||
| 55 | !> Number of active children | ||
| 56 | integer :: nr_children | ||
| 57 | !> Tree depth (root starts at 0) | ||
| 58 | integer :: depth | ||
| 59 | contains | ||
| 60 | procedure :: init => timer_init | ||
| 61 | procedure :: start => timer_start | ||
| 62 | procedure :: stop => timer_stop | ||
| 63 | procedure :: print => timer_print | ||
| 64 | procedure :: nr_ranks => timer_nr_ranks | ||
| 65 | procedure :: total => timer_total | ||
| 66 | procedure :: minval => timer_minval | ||
| 67 | procedure :: maxval => timer_maxval | ||
| 68 | procedure :: avgval => timer_avgval | ||
| 69 | procedure, private :: sync => timer_sync | ||
| 70 | final :: timer_destroy | ||
| 71 | end type SmartTimer | ||
| 72 | |||
| 73 | type(TimerPointer), allocatable, save :: timer_registry(:) | ||
| 74 | integer, save :: nr_timers = 0 | ||
| 75 | integer, save :: next_timer_id = 1 | ||
| 76 | |||
| 77 | type(SmartTimer), allocatable, target, save :: our_timers(:) ! get_timer returns a pointer, but sometimes we need a new timer | ||
| 78 | integer, save :: nr_our_timers = 0 | ||
| 79 | |||
| 80 | ! Module procedure interfaces for submodule | ||
| 81 | interface | ||
| 82 | !> @brief Get a timer by name, creating it if it doesn't exist | ||
| 83 | !> | ||
| 84 | !> @param[in] name Timer name | ||
| 85 | !> | ||
| 86 | !> @return SmartTimer object corresponding to the name | ||
| 87 | module function MACRO_USE_ONLY_get_timer(name) result(timer_id) | ||
| 88 | character(len=*), intent(in) :: name | ||
| 89 | integer :: timer_id | ||
| 90 | end function | ||
| 91 | |||
| 92 | !> @brief Start a timer by our ID | ||
| 93 | !> | ||
| 94 | !> @param[in] our_timer_id Our timer ID | ||
| 95 | module subroutine MACRO_USE_ONLY_start_timer(our_timer_id) | ||
| 96 | integer, intent(in) :: our_timer_id | ||
| 97 | end subroutine | ||
| 98 | |||
| 99 | !> @brief Stop a timer by our ID | ||
| 100 | !> | ||
| 101 | !> @param[in] our_timer_id Our timer ID | ||
| 102 | module subroutine MACRO_USE_ONLY_stop_timer(our_timer_id) | ||
| 103 | integer, intent(in) :: our_timer_id | ||
| 104 | end subroutine | ||
| 105 | |||
| 106 | !> @brief Initialize the timer | ||
| 107 | !> | ||
| 108 | !> @param[inout] this The SmartTimer object to initialize | ||
| 109 | !> @param[in] name Timer name (mandatory) | ||
| 110 | !> @param[in] comm _(optional)_ MPI communicator (default: PETSC_COMM_WORLD) | ||
| 111 | !> @param[in] our_id _(optional)_ Our timer ID when we allocate this timer in get_timer (default: -1) | ||
| 112 | module subroutine timer_init(this, name, comm, our_id) | ||
| 113 | class(SmartTimer), intent(inout), target :: this | ||
| 114 | character(len=*), intent(in) :: name | ||
| 115 | integer, intent(in), optional :: comm | ||
| 116 | integer, intent(in), optional :: our_id | ||
| 117 | end subroutine | ||
| 118 | |||
| 119 | !> @brief Destroy the timer object | ||
| 120 | !> | ||
| 121 | !> @param[inout] this The SmartTimer object to destroy | ||
| 122 | module subroutine timer_destroy(this) | ||
| 123 | type(SmartTimer), intent(inout) :: this | ||
| 124 | end subroutine | ||
| 125 | |||
| 126 | !> @brief Start the timer | ||
| 127 | !> | ||
| 128 | !> @param[inout] this The SmartTimer object to start | ||
| 129 | !> @param[in] reset _(optional)_ Whether to reset the timer (default: .false.) | ||
| 130 | module subroutine timer_start(this, reset) | ||
| 131 | class(SmartTimer), intent(inout), target :: this | ||
| 132 | logical, intent(in), optional :: reset | ||
| 133 | end subroutine | ||
| 134 | |||
| 135 | !> @brief Stop the timer | ||
| 136 | !> | ||
| 137 | !> @param[inout] this The SmartTimer object to stop | ||
| 138 | module subroutine timer_stop(this) | ||
| 139 | class(SmartTimer), intent(inout) :: this | ||
| 140 | end subroutine | ||
| 141 | |||
| 142 | !> @brief Print timer statistics for this timer and its descendants | ||
| 143 | !> | ||
| 144 | !> @param[inout] this The SmartTimer object to print | ||
| 145 | !> @param[in] metric _(optional)_ Which metric to print: min, avg, max, all, or total | ||
| 146 | !> @param[in] file_id _(optional)_ Fortran output unit (default: stdout) | ||
| 147 | !> @param[in] transform _(optional)_ Scalar transform applied to printed time values | ||
| 148 | !> @param[in] show_percentage _(optional)_ Show percentage relative to parent | ||
| 149 | !> @param[in] sort _(optional)_ Sort children at each depth from high to low by the selected metric (default: .false.) | ||
| 150 | !> @param[in] max_depth _(optional)_ Maximum depth to print in the timer tree (default: -1 for unlimited) | ||
| 151 | module subroutine timer_print(this, metric, file_id, transform, show_percentage, sort, max_depth) | ||
| 152 | class(SmartTimer), intent(inout), target :: this | ||
| 153 | character(len=*), intent(in), optional :: metric | ||
| 154 | integer, intent(in), optional :: file_id | ||
| 155 | procedure(user_function_1d_interface), optional :: transform | ||
| 156 | logical, intent(in), optional :: show_percentage | ||
| 157 | logical, intent(in), optional :: sort | ||
| 158 | integer, intent(in), optional :: max_depth | ||
| 159 | end subroutine | ||
| 160 | |||
| 161 | !> @brief Synchronize elapsed time across ranks | ||
| 162 | !> | ||
| 163 | !> @param[inout] this The SmartTimer object to synchronize | ||
| 164 | module subroutine timer_sync(this) | ||
| 165 | class(SmartTimer), intent(inout), target :: this | ||
| 166 | end subroutine | ||
| 167 | |||
| 168 | !> @brief Get number of ranks in timer communicator | ||
| 169 | !> | ||
| 170 | !> @param[in] this The SmartTimer object to query | ||
| 171 | !> | ||
| 172 | !> @return Number of ranks | ||
| 173 | module function timer_nr_ranks(this) result(nr) | ||
| 174 | class(SmartTimer), intent(in) :: this | ||
| 175 | integer :: nr | ||
| 176 | end function | ||
| 177 | |||
| 178 | !> @brief Get total elapsed time across all ranks | ||
| 179 | !> | ||
| 180 | !> @param[in] this The SmartTimer object to query | ||
| 181 | !> | ||
| 182 | !> @return Total elapsed time across all ranks | ||
| 183 | module function timer_total(this) result(total_time) | ||
| 184 | class(SmartTimer), intent(inout) :: this | ||
| 185 | real(wp) :: total_time | ||
| 186 | end function | ||
| 187 | |||
| 188 | !> @brief Get the minimum elapsed time across all ranks | ||
| 189 | !> | ||
| 190 | !> @param[in] this The SmartTimer object to query | ||
| 191 | !> | ||
| 192 | !> @return The minimum elapsed time | ||
| 193 | module function timer_minval(this) result(min_time) | ||
| 194 | class(SmartTimer), intent(inout) :: this | ||
| 195 | real(wp) :: min_time | ||
| 196 | end function | ||
| 197 | |||
| 198 | !> @brief Get the maximum elapsed time across all ranks | ||
| 199 | !> | ||
| 200 | !> @param[in] this The SmartTimer object to query | ||
| 201 | !> | ||
| 202 | !> @return The maximum elapsed time | ||
| 203 | module function timer_maxval(this) result(max_time) | ||
| 204 | class(SmartTimer), intent(inout) :: this | ||
| 205 | real(wp) :: max_time | ||
| 206 | end function | ||
| 207 | |||
| 208 | !> @brief Get the average elapsed time across all ranks | ||
| 209 | !> | ||
| 210 | !> @param[in] this The SmartTimer object to query | ||
| 211 | !> | ||
| 212 | !> @return The average elapsed time | ||
| 213 | module function timer_avgval(this) result(avg_time) | ||
| 214 | class(SmartTimer), intent(inout) :: this | ||
| 215 | real(wp) :: avg_time | ||
| 216 | end function | ||
| 217 | |||
| 218 | end interface | ||
| 219 | |||
| 220 |
10/28__m_timer_MOD___copy_m_timer_Smarttimer:
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 12 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 11 not taken.
__m_timer_MOD___final_m_timer_Smarttimer:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 1 time.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 9 not taken.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 25 taken 1 time.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 20 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 24 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 1 time.
|
3 | end module m_timer |
| 221 |