Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Timing routines for accounting
10 : !> \par History
11 : !> 02.2004 made a stacked version (of stacks...) [Joost VandeVondele]
12 : !> 11.2004 storable timer_envs (for f77 interface) [fawzi]
13 : !> 10.2005 binary search to speed up lookup in timeset [fawzi]
14 : !> 12.2012 Complete rewrite based on dictionaries. [ole]
15 : !> \author JGH
16 : ! **************************************************************************************************
17 : MODULE timings
18 : USE base_hooks, ONLY: timeset_hook,&
19 : timestop_hook
20 : USE callgraph, ONLY: callgraph_destroy,&
21 : callgraph_get,&
22 : callgraph_init,&
23 : callgraph_item_type,&
24 : callgraph_items,&
25 : callgraph_set
26 : USE kinds, ONLY: default_string_length,&
27 : dp,&
28 : int_8
29 : USE list, ONLY: &
30 : list_destroy, list_get, list_init, list_isready, list_peek, list_pop, list_push, &
31 : list_size, list_timerenv_type
32 : USE machine, ONLY: m_energy,&
33 : m_flush,&
34 : m_memory,&
35 : m_walltime
36 : USE offload_api, ONLY: offload_mem_info,&
37 : offload_timeset,&
38 : offload_timestop
39 : USE routine_map, ONLY: routine_map_destroy,&
40 : routine_map_get,&
41 : routine_map_init,&
42 : routine_map_set,&
43 : routine_map_size
44 : USE timings_base_type, ONLY: call_stat_type,&
45 : callstack_entry_type,&
46 : routine_stat_type
47 : USE timings_types, ONLY: timer_env_type
48 : #include "../base/base_uses.f90"
49 :
50 : IMPLICIT NONE
51 : PRIVATE
52 :
53 : PUBLIC :: print_stack, timings_register_hooks
54 :
55 : ! these routines are currently only used by environment.F and f77_interface.F
56 : PUBLIC :: add_timer_env, rm_timer_env, get_timer_env
57 : PUBLIC :: timer_env_retain, timer_env_release
58 : PUBLIC :: timings_setup_tracing
59 :
60 : ! global variables
61 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'timings'
62 : TYPE(list_timerenv_type), SAVE, PRIVATE :: timers_stack
63 :
64 : !API (via pointer assignment to hook, PR67982, not meant to be called directly)
65 : PUBLIC :: timeset_handler, timestop_handler
66 :
67 : INTEGER, PUBLIC, PARAMETER :: default_timings_level = 1
68 : INTEGER, PUBLIC, SAVE :: global_timings_level = default_timings_level
69 :
70 : CHARACTER(LEN=default_string_length), PUBLIC, PARAMETER :: root_cp2k_name = 'CP2K'
71 :
72 : CONTAINS
73 :
74 : ! **************************************************************************************************
75 : !> \brief Registers handlers with base_hooks.F
76 : !> \author Ole Schuett
77 : ! **************************************************************************************************
78 10486 : SUBROUTINE timings_register_hooks()
79 10486 : timeset_hook => timeset_handler
80 10486 : timestop_hook => timestop_handler
81 10486 : END SUBROUTINE timings_register_hooks
82 :
83 : ! **************************************************************************************************
84 : !> \brief adds the given timer_env to the top of the stack
85 : !> \param timer_env ...
86 : !> \par History
87 : !> 02.2004 created [Joost VandeVondele]
88 : !> \note
89 : !> for each init_timer_env there should be the symmetric call to
90 : !> rm_timer_env
91 : ! **************************************************************************************************
92 118921 : SUBROUTINE add_timer_env(timer_env)
93 : TYPE(timer_env_type), OPTIONAL, POINTER :: timer_env
94 :
95 : TYPE(timer_env_type), POINTER :: timer_env_
96 :
97 118921 : IF (PRESENT(timer_env)) timer_env_ => timer_env
98 21573 : IF (.NOT. PRESENT(timer_env)) CALL timer_env_create(timer_env_)
99 118921 : IF (.NOT. ASSOCIATED(timer_env_)) THEN
100 0 : CPABORT("add_timer_env: not associated")
101 : END IF
102 :
103 118921 : CALL timer_env_retain(timer_env_)
104 118921 : IF (.NOT. list_isready(timers_stack)) CALL list_init(timers_stack)
105 118921 : CALL list_push(timers_stack, timer_env_)
106 118921 : END SUBROUTINE add_timer_env
107 :
108 : ! **************************************************************************************************
109 : !> \brief creates a new timer env
110 : !> \param timer_env ...
111 : !> \author fawzi
112 : ! **************************************************************************************************
113 21573 : SUBROUTINE timer_env_create(timer_env)
114 : TYPE(timer_env_type), POINTER :: timer_env
115 :
116 21573 : ALLOCATE (timer_env)
117 21573 : timer_env%ref_count = 0
118 : timer_env%trace_max = -1 ! tracing disabled by default
119 : timer_env%trace_all = .FALSE.
120 21573 : CALL routine_map_init(timer_env%routine_names)
121 21573 : CALL callgraph_init(timer_env%callgraph)
122 21573 : CALL list_init(timer_env%routine_stats)
123 21573 : CALL list_init(timer_env%callstack)
124 21573 : END SUBROUTINE timer_env_create
125 :
126 : ! **************************************************************************************************
127 : !> \brief removes the current timer env from the stack
128 : !> \par History
129 : !> 02.2004 created [Joost VandeVondele]
130 : !> \note
131 : !> for each rm_timer_env there should have been the symmetric call to
132 : !> add_timer_env
133 : ! **************************************************************************************************
134 118921 : SUBROUTINE rm_timer_env()
135 : TYPE(timer_env_type), POINTER :: timer_env
136 :
137 118921 : timer_env => list_pop(timers_stack)
138 118921 : CALL timer_env_release(timer_env)
139 118921 : IF (list_size(timers_stack) == 0) CALL list_destroy(timers_stack)
140 118921 : END SUBROUTINE rm_timer_env
141 :
142 : ! **************************************************************************************************
143 : !> \brief returns the current timer env from the stack
144 : !> \return ...
145 : !> \author fawzi
146 : ! **************************************************************************************************
147 118999 : FUNCTION get_timer_env() RESULT(timer_env)
148 : TYPE(timer_env_type), POINTER :: timer_env
149 :
150 118999 : timer_env => list_peek(timers_stack)
151 118999 : END FUNCTION get_timer_env
152 :
153 : ! **************************************************************************************************
154 : !> \brief retains the given timer env
155 : !> \param timer_env the timer env to retain
156 : !> \author fawzi
157 : ! **************************************************************************************************
158 129484 : SUBROUTINE timer_env_retain(timer_env)
159 : TYPE(timer_env_type), POINTER :: timer_env
160 :
161 129484 : IF (.NOT. ASSOCIATED(timer_env)) THEN
162 0 : CPABORT("timer_env_retain: not associated")
163 : END IF
164 129484 : IF (timer_env%ref_count < 0) THEN
165 0 : CPABORT("timer_env_retain: negativ ref_count")
166 : END IF
167 129484 : timer_env%ref_count = timer_env%ref_count + 1
168 129484 : END SUBROUTINE timer_env_retain
169 :
170 : ! **************************************************************************************************
171 : !> \brief releases the given timer env
172 : !> \param timer_env the timer env to release
173 : !> \author fawzi
174 : ! **************************************************************************************************
175 129484 : SUBROUTINE timer_env_release(timer_env)
176 : TYPE(timer_env_type), POINTER :: timer_env
177 :
178 : INTEGER :: i
179 129484 : TYPE(callgraph_item_type), DIMENSION(:), POINTER :: ct_items
180 : TYPE(routine_stat_type), POINTER :: r_stat
181 :
182 129484 : IF (.NOT. ASSOCIATED(timer_env)) THEN
183 0 : CPABORT("timer_env_release: not associated")
184 : END IF
185 129484 : IF (timer_env%ref_count < 0) THEN
186 0 : CPABORT("timer_env_release: negativ ref_count")
187 : END IF
188 129484 : timer_env%ref_count = timer_env%ref_count - 1
189 129484 : IF (timer_env%ref_count > 0) RETURN
190 :
191 : ! No more references left - let's tear down this timer_env...
192 :
193 4780272 : DO i = 1, list_size(timer_env%routine_stats)
194 4758699 : r_stat => list_get(timer_env%routine_stats, i)
195 4780272 : DEALLOCATE (r_stat)
196 : END DO
197 :
198 21573 : ct_items => callgraph_items(timer_env%callgraph)
199 8008350 : DO i = 1, SIZE(ct_items)
200 8008350 : DEALLOCATE (ct_items(i)%value)
201 : END DO
202 21573 : DEALLOCATE (ct_items)
203 :
204 21573 : CALL routine_map_destroy(timer_env%routine_names)
205 21573 : CALL callgraph_destroy(timer_env%callgraph)
206 21573 : CALL list_destroy(timer_env%callstack)
207 21573 : CALL list_destroy(timer_env%routine_stats)
208 21573 : DEALLOCATE (timer_env)
209 129484 : END SUBROUTINE timer_env_release
210 :
211 : ! **************************************************************************************************
212 : !> \brief Start timer
213 : !> \param routineN ...
214 : !> \param handle ...
215 : !> \par History
216 : !> none
217 : !> \author JGH
218 : ! **************************************************************************************************
219 2015688125 : SUBROUTINE timeset_handler(routineN, handle)
220 : CHARACTER(LEN=*), INTENT(IN) :: routineN
221 : INTEGER, INTENT(OUT) :: handle
222 :
223 : CHARACTER(LEN=400) :: line, mystring
224 : CHARACTER(LEN=60) :: sformat
225 : CHARACTER(LEN=default_string_length) :: routine_name_dsl
226 : INTEGER :: routine_id, stack_size
227 : INTEGER(KIND=int_8) :: cpumem, gpumem_free, gpumem_total
228 : INTEGER, SAVE :: root_cp2k_id
229 : TYPE(callstack_entry_type) :: cs_entry
230 : TYPE(routine_stat_type), POINTER :: r_stat
231 : TYPE(timer_env_type), POINTER :: timer_env
232 :
233 2015688125 : !$OMP MASTER
234 :
235 : ! Default value, using a negative value when timing is not taken
236 2015688125 : cs_entry%walltime_start = -HUGE(1.0_dp)
237 2015688125 : cs_entry%energy_start = -HUGE(1.0_dp)
238 2015688125 : root_cp2k_id = routine_name2id(root_cp2k_name)
239 : !
240 2015688125 : routine_name_dsl = routineN ! converte to default_string_length
241 2015688125 : routine_id = routine_name2id(routine_name_dsl)
242 : !
243 : ! Take timings when the timings_level is appropriated
244 2015688125 : IF (global_timings_level /= 0 .OR. routine_id == root_cp2k_id) THEN
245 2015688125 : cs_entry%walltime_start = m_walltime()
246 2015688125 : cs_entry%energy_start = m_energy()
247 : END IF
248 2015688125 : timer_env => list_peek(timers_stack)
249 :
250 2015688125 : IF (LEN_TRIM(routineN) > default_string_length) THEN
251 0 : CPABORT('timings_timeset: routineN too long: "'//TRIM(routineN)//"'")
252 : END IF
253 :
254 : ! update routine r_stats
255 2015688125 : r_stat => list_get(timer_env%routine_stats, routine_id)
256 2015688125 : stack_size = list_size(timer_env%callstack)
257 2015688125 : r_stat%total_calls = r_stat%total_calls + 1
258 2015688125 : r_stat%active_calls = r_stat%active_calls + 1
259 2015688125 : r_stat%stackdepth_accu = r_stat%stackdepth_accu + stack_size + 1
260 :
261 : ! add routine to callstack
262 2015688125 : cs_entry%routine_id = routine_id
263 2015688125 : CALL list_push(timer_env%callstack, cs_entry)
264 :
265 : !..if debug mode echo the subroutine name
266 2015688125 : IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
267 : (r_stat%total_calls < timer_env%trace_max)) THEN
268 0 : WRITE (sformat, *) "(A,A,", MAX(1, 3*stack_size - 4), "X,I4,1X,I6,1X,A,A)"
269 0 : WRITE (mystring, sformat) timer_env%trace_str, ">>", stack_size + 1, &
270 0 : r_stat%total_calls, TRIM(r_stat%routineN), " start"
271 0 : CALL offload_mem_info(gpumem_free, gpumem_total)
272 0 : CALL m_memory(cpumem)
273 0 : WRITE (line, '(A,A,I0,A,A,I0,A)') TRIM(mystring), &
274 0 : " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024), " MB", &
275 0 : " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024), " MB"
276 0 : WRITE (timer_env%trace_unit, *) TRIM(line)
277 0 : CALL m_flush(timer_env%trace_unit)
278 : END IF
279 :
280 2015688125 : handle = routine_id
281 :
282 2015688125 : CALL offload_timeset(routineN)
283 :
284 : !$OMP END MASTER
285 :
286 2015688125 : END SUBROUTINE timeset_handler
287 :
288 : ! **************************************************************************************************
289 : !> \brief End timer
290 : !> \param handle ...
291 : !> \par History
292 : !> none
293 : !> \author JGH
294 : ! **************************************************************************************************
295 2015688125 : SUBROUTINE timestop_handler(handle)
296 : INTEGER, INTENT(in) :: handle
297 :
298 : CHARACTER(LEN=400) :: line, mystring
299 : CHARACTER(LEN=60) :: sformat
300 : INTEGER :: routine_id, stack_size
301 : INTEGER(KIND=int_8) :: cpumem, gpumem_free, gpumem_total
302 : INTEGER, DIMENSION(2) :: routine_tuple
303 : REAL(KIND=dp) :: en_elapsed, en_now, wt_elapsed, wt_now
304 : TYPE(call_stat_type), POINTER :: c_stat
305 : TYPE(callstack_entry_type) :: cs_entry, prev_cs_entry
306 : TYPE(routine_stat_type), POINTER :: prev_stat, r_stat
307 : TYPE(timer_env_type), POINTER :: timer_env
308 :
309 2015688125 : routine_id = handle
310 :
311 2015688125 : !$OMP MASTER
312 :
313 2015688125 : CALL offload_timestop()
314 :
315 2015688125 : timer_env => list_peek(timers_stack)
316 2015688125 : cs_entry = list_pop(timer_env%callstack)
317 2015688125 : r_stat => list_get(timer_env%routine_stats, cs_entry%routine_id)
318 :
319 2015688125 : IF (handle /= cs_entry%routine_id) THEN
320 0 : PRINT *, "list_size(timer_env%callstack) ", list_size(timer_env%callstack), &
321 0 : " handle ", handle, " list_size(timers_stack) ", list_size(timers_stack)
322 0 : CPABORT('mismatched timestop '//TRIM(r_stat%routineN)//' in routine timestop')
323 : END IF
324 :
325 2015688125 : wt_elapsed = 0
326 2015688125 : en_elapsed = 0
327 : ! Take timings only when the start time is >=0, i.e. the timings_level is appropriated
328 2015688125 : IF (cs_entry%walltime_start >= 0) THEN
329 2015688125 : wt_now = m_walltime()
330 2015688125 : en_now = m_energy()
331 : ! add the elapsed time for this timeset/timestop to the time accumulator
332 2015688125 : wt_elapsed = wt_now - cs_entry%walltime_start
333 2015688125 : en_elapsed = en_now - cs_entry%energy_start
334 : END IF
335 2015688125 : r_stat%active_calls = r_stat%active_calls - 1
336 :
337 : ! if we're the last instance in the stack, we do the accounting of the total time
338 2015688125 : IF (r_stat%active_calls == 0) THEN
339 2012709701 : r_stat%incl_walltime_accu = r_stat%incl_walltime_accu + wt_elapsed
340 2012709701 : r_stat%incl_energy_accu = r_stat%incl_energy_accu + en_elapsed
341 : END IF
342 :
343 : ! exclusive time we always sum, since children will correct this time with their total time
344 2015688125 : r_stat%excl_walltime_accu = r_stat%excl_walltime_accu + wt_elapsed
345 2015688125 : r_stat%excl_energy_accu = r_stat%excl_energy_accu + en_elapsed
346 :
347 2015688125 : stack_size = list_size(timer_env%callstack)
348 2015688125 : IF (stack_size > 0) THEN
349 1974356125 : prev_cs_entry = list_peek(timer_env%callstack)
350 1974356125 : prev_stat => list_get(timer_env%routine_stats, prev_cs_entry%routine_id)
351 : ! we fixup the clock of the caller
352 1974356125 : prev_stat%excl_walltime_accu = prev_stat%excl_walltime_accu - wt_elapsed
353 1974356125 : prev_stat%excl_energy_accu = prev_stat%excl_energy_accu - en_elapsed
354 :
355 : !update callgraph
356 5923068375 : routine_tuple = [prev_cs_entry%routine_id, routine_id]
357 1974356125 : c_stat => callgraph_get(timer_env%callgraph, routine_tuple, default_value=Null(c_stat))
358 1974356125 : IF (.NOT. ASSOCIATED(c_stat)) THEN
359 7986777 : ALLOCATE (c_stat)
360 : c_stat%total_calls = 0
361 : c_stat%incl_walltime_accu = 0.0_dp
362 : c_stat%incl_energy_accu = 0.0_dp
363 7986777 : CALL callgraph_set(timer_env%callgraph, routine_tuple, c_stat)
364 : END IF
365 1974356125 : c_stat%total_calls = c_stat%total_calls + 1
366 1974356125 : c_stat%incl_walltime_accu = c_stat%incl_walltime_accu + wt_elapsed
367 1974356125 : c_stat%incl_energy_accu = c_stat%incl_energy_accu + en_elapsed
368 : END IF
369 :
370 : !..if debug mode echo the subroutine name
371 2015688125 : IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
372 : (r_stat%total_calls < timer_env%trace_max)) THEN
373 0 : WRITE (sformat, *) "(A,A,", MAX(1, 3*stack_size - 4), "X,I4,1X,I6,1X,A,F12.3)"
374 0 : WRITE (mystring, sformat) timer_env%trace_str, "<<", stack_size + 1, &
375 0 : r_stat%total_calls, TRIM(r_stat%routineN), wt_elapsed
376 0 : CALL offload_mem_info(gpumem_free, gpumem_total)
377 0 : CALL m_memory(cpumem)
378 0 : WRITE (line, '(A,A,I0,A,A,I0,A)') TRIM(mystring), &
379 0 : " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024), " MB", &
380 0 : " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024), " MB"
381 0 : WRITE (timer_env%trace_unit, *) TRIM(line)
382 0 : CALL m_flush(timer_env%trace_unit)
383 : END IF
384 :
385 : !$OMP END MASTER
386 :
387 2015688125 : END SUBROUTINE timestop_handler
388 :
389 : ! **************************************************************************************************
390 : !> \brief Set routine tracer
391 : !> \param trace_max maximum number of calls reported per routine.
392 : !> Setting this to zero disables tracing.
393 : !> \param unit_nr output unit used for printing the trace-messages
394 : !> \param trace_str short info-string which is printed along with every message
395 : !> \param routine_names List of routine-names.
396 : !> If provided only these routines will be traced.
397 : !> If not present all routines will traced.
398 : !> \par History
399 : !> 12.2012 added ability to trace only certain routines [ole]
400 : !> \author JGH
401 : ! **************************************************************************************************
402 0 : SUBROUTINE timings_setup_tracing(trace_max, unit_nr, trace_str, routine_names)
403 : INTEGER, INTENT(IN) :: trace_max, unit_nr
404 : CHARACTER(len=13), INTENT(IN) :: trace_str
405 : CHARACTER(len=default_string_length), &
406 : DIMENSION(:), INTENT(IN), OPTIONAL :: routine_names
407 :
408 : INTEGER :: i, routine_id
409 : TYPE(routine_stat_type), POINTER :: r_stat
410 : TYPE(timer_env_type), POINTER :: timer_env
411 :
412 0 : timer_env => list_peek(timers_stack)
413 0 : timer_env%trace_max = trace_max
414 0 : timer_env%trace_unit = unit_nr
415 0 : timer_env%trace_str = trace_str
416 0 : timer_env%trace_all = .TRUE.
417 0 : IF (.NOT. PRESENT(routine_names)) RETURN
418 :
419 : ! setup routine-specific tracing
420 0 : timer_env%trace_all = .FALSE.
421 0 : DO i = 1, SIZE(routine_names)
422 0 : routine_id = routine_name2id(routine_names(i))
423 0 : r_stat => list_get(timer_env%routine_stats, routine_id)
424 0 : r_stat%trace = .TRUE.
425 : END DO
426 :
427 : END SUBROUTINE timings_setup_tracing
428 :
429 : ! **************************************************************************************************
430 : !> \brief Print current routine stack
431 : !> \param unit_nr ...
432 : !> \par History
433 : !> none
434 : !> \author JGH
435 : ! **************************************************************************************************
436 598 : SUBROUTINE print_stack(unit_nr)
437 : INTEGER, INTENT(IN) :: unit_nr
438 :
439 : INTEGER :: i
440 : TYPE(callstack_entry_type) :: cs_entry
441 : TYPE(routine_stat_type), POINTER :: r_stat
442 : TYPE(timer_env_type), POINTER :: timer_env
443 :
444 : ! catch edge cases where timer_env is not yet/anymore available
445 598 : IF (.NOT. list_isready(timers_stack)) THEN
446 0 : RETURN
447 : END IF
448 598 : IF (list_size(timers_stack) == 0) THEN
449 : RETURN
450 : END IF
451 :
452 598 : timer_env => list_peek(timers_stack)
453 598 : WRITE (unit_nr, '(/,A,/)') " ===== Routine Calling Stack ===== "
454 3593 : DO i = list_size(timer_env%callstack), 1, -1
455 2995 : cs_entry = list_get(timer_env%callstack, i)
456 2995 : r_stat => list_get(timer_env%routine_stats, cs_entry%routine_id)
457 3593 : WRITE (unit_nr, '(T10,I4,1X,A)') i, TRIM(r_stat%routineN)
458 : END DO
459 598 : CALL m_flush(unit_nr)
460 :
461 598 : END SUBROUTINE print_stack
462 :
463 : ! **************************************************************************************************
464 : !> \brief Internal routine used by timestet and timings_setup_tracing.
465 : !> If no routine with given name is found in timer_env%routine_names
466 : !> then a new entiry is created.
467 : !> \param routineN ...
468 : !> \return ...
469 : !> \author Ole Schuett
470 : ! **************************************************************************************************
471 4031376250 : FUNCTION routine_name2id(routineN) RESULT(routine_id)
472 : CHARACTER(LEN=default_string_length), INTENT(IN) :: routineN
473 : INTEGER :: routine_id
474 :
475 : TYPE(routine_stat_type), POINTER :: r_stat
476 : TYPE(timer_env_type), POINTER :: timer_env
477 :
478 4031376250 : timer_env => list_peek(timers_stack)
479 4031376250 : routine_id = routine_map_get(timer_env%routine_names, routineN, default_value=-1)
480 :
481 4031376250 : IF (routine_id /= -1) RETURN ! found an id - let's return it
482 : ! routine not found - let's create it
483 :
484 : ! enforce space free timer names, to make the output of trace/timings of a fixed number fields
485 4758699 : IF (INDEX(routineN(1:LEN_TRIM(routineN)), ' ') /= 0) THEN
486 0 : CPABORT("timings_name2id: routineN contains spaces: "//routineN)
487 : END IF
488 :
489 : ! register routine_name_dsl with new routine_id
490 4758699 : routine_id = routine_map_size(timer_env%routine_names) + 1
491 4758699 : CALL routine_map_set(timer_env%routine_names, routineN, routine_id)
492 :
493 4758699 : ALLOCATE (r_stat)
494 4758699 : r_stat%routine_id = routine_id
495 4758699 : r_stat%routineN = routineN
496 : r_stat%active_calls = 0
497 : r_stat%excl_walltime_accu = 0.0_dp
498 : r_stat%incl_walltime_accu = 0.0_dp
499 : r_stat%excl_energy_accu = 0.0_dp
500 : r_stat%incl_energy_accu = 0.0_dp
501 : r_stat%total_calls = 0
502 : r_stat%stackdepth_accu = 0
503 : r_stat%trace = .FALSE.
504 4758699 : CALL list_push(timer_env%routine_stats, r_stat)
505 4758699 : CPASSERT(list_size(timer_env%routine_stats) == routine_map_size(timer_env%routine_names))
506 : END FUNCTION routine_name2id
507 :
508 : END MODULE timings
509 :
|