GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 33.3% 1 / 0 / 3
Functions: 33.3% 1 / 0 / 3
Branches: 35.7% 10 / 0 / 28

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