48#include "../base/base_uses.f90"
61 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'timings'
62 TYPE(list_timerenv_type),
SAVE,
PRIVATE :: timers_stack
70 CHARACTER(LEN=default_string_length),
PUBLIC,
PARAMETER ::
root_cp2k_name =
'CP2K'
97 IF (
PRESENT(timer_env)) timer_env_ => timer_env
98 IF (.NOT.
PRESENT(timer_env))
CALL timer_env_create(timer_env_)
99 IF (.NOT.
ASSOCIATED(timer_env_))
THEN
100 cpabort(
"add_timer_env: not associated")
113 SUBROUTINE timer_env_create(timer_env)
117 timer_env%ref_count = 0
118 timer_env%trace_max = -1
119 timer_env%trace_all = .false.
124 END SUBROUTINE timer_env_create
161 IF (.NOT.
ASSOCIATED(timer_env))
THEN
162 cpabort(
"timer_env_retain: not associated")
164 IF (timer_env%ref_count < 0)
THEN
165 cpabort(
"timer_env_retain: negativ ref_count")
167 timer_env%ref_count = timer_env%ref_count + 1
182 IF (.NOT.
ASSOCIATED(timer_env))
THEN
183 cpabort(
"timer_env_release: not associated")
185 IF (timer_env%ref_count < 0)
THEN
186 cpabort(
"timer_env_release: negativ ref_count")
188 timer_env%ref_count = timer_env%ref_count - 1
189 IF (timer_env%ref_count > 0)
RETURN
193 DO i = 1,
list_size(timer_env%routine_stats)
194 r_stat =>
list_get(timer_env%routine_stats, i)
199 DO i = 1,
SIZE(ct_items)
200 DEALLOCATE (ct_items(i)%value)
202 DEALLOCATE (ct_items)
208 DEALLOCATE (timer_env)
220 CHARACTER(LEN=*),
INTENT(IN) :: routinen
221 INTEGER,
INTENT(OUT) :: handle
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
236 cs_entry%walltime_start = -huge(1.0_dp)
237 cs_entry%energy_start = -huge(1.0_dp)
240 routine_name_dsl = routinen
241 routine_id = routine_name2id(routine_name_dsl)
251 cpabort(
'timings_timeset: routineN too long: "'//trim(routinen)//
"'")
255 r_stat =>
list_get(timer_env%routine_stats, routine_id)
256 stack_size =
list_size(timer_env%callstack)
257 r_stat%total_calls = r_stat%total_calls + 1
258 r_stat%active_calls = r_stat%active_calls + 1
259 r_stat%stackdepth_accu = r_stat%stackdepth_accu + stack_size + 1
262 cs_entry%routine_id = routine_id
263 CALL list_push(timer_env%callstack, cs_entry)
266 IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
267 (r_stat%total_calls < timer_env%trace_max))
THEN
268 WRITE (sformat, *)
"(A,A,", max(1, 3*stack_size - 4),
"X,I4,1X,I6,1X,A,A)"
269 WRITE (mystring, sformat) timer_env%trace_str,
">>", stack_size + 1, &
270 r_stat%total_calls, trim(r_stat%routineN),
" start"
273 WRITE (line,
'(A,A,I0,A,A,I0,A)') trim(mystring), &
274 " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024),
" MB", &
275 " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024),
" MB"
276 WRITE (timer_env%trace_unit, *) trim(line)
277 CALL m_flush(timer_env%trace_unit)
296 INTEGER,
INTENT(in) :: handle
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
316 cs_entry =
list_pop(timer_env%callstack)
317 r_stat =>
list_get(timer_env%routine_stats, cs_entry%routine_id)
319 IF (handle /= cs_entry%routine_id)
THEN
320 print *,
"list_size(timer_env%callstack) ",
list_size(timer_env%callstack), &
321 " handle ", handle,
" list_size(timers_stack) ",
list_size(timers_stack)
322 cpabort(
'mismatched timestop '//trim(r_stat%routineN)//
' in routine timestop')
328 IF (cs_entry%walltime_start >= 0)
THEN
332 wt_elapsed = wt_now - cs_entry%walltime_start
333 en_elapsed = en_now - cs_entry%energy_start
335 r_stat%active_calls = r_stat%active_calls - 1
338 IF (r_stat%active_calls == 0)
THEN
339 r_stat%incl_walltime_accu = r_stat%incl_walltime_accu + wt_elapsed
340 r_stat%incl_energy_accu = r_stat%incl_energy_accu + en_elapsed
344 r_stat%excl_walltime_accu = r_stat%excl_walltime_accu + wt_elapsed
345 r_stat%excl_energy_accu = r_stat%excl_energy_accu + en_elapsed
347 stack_size =
list_size(timer_env%callstack)
348 IF (stack_size > 0)
THEN
349 prev_cs_entry =
list_peek(timer_env%callstack)
350 prev_stat =>
list_get(timer_env%routine_stats, prev_cs_entry%routine_id)
352 prev_stat%excl_walltime_accu = prev_stat%excl_walltime_accu - wt_elapsed
353 prev_stat%excl_energy_accu = prev_stat%excl_energy_accu - en_elapsed
356 routine_tuple = [prev_cs_entry%routine_id, routine_id]
357 c_stat =>
callgraph_get(timer_env%callgraph, routine_tuple, default_value=null(c_stat))
358 IF (.NOT.
ASSOCIATED(c_stat))
THEN
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 CALL callgraph_set(timer_env%callgraph, routine_tuple, c_stat)
365 c_stat%total_calls = c_stat%total_calls + 1
366 c_stat%incl_walltime_accu = c_stat%incl_walltime_accu + wt_elapsed
367 c_stat%incl_energy_accu = c_stat%incl_energy_accu + en_elapsed
371 IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
372 (r_stat%total_calls < timer_env%trace_max))
THEN
373 WRITE (sformat, *)
"(A,A,", max(1, 3*stack_size - 4),
"X,I4,1X,I6,1X,A,F12.3)"
374 WRITE (mystring, sformat) timer_env%trace_str,
"<<", stack_size + 1, &
375 r_stat%total_calls, trim(r_stat%routineN), wt_elapsed
378 WRITE (line,
'(A,A,I0,A,A,I0,A)') trim(mystring), &
379 " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024),
" MB", &
380 " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024),
" MB"
381 WRITE (timer_env%trace_unit, *) trim(line)
382 CALL m_flush(timer_env%trace_unit)
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
408 INTEGER :: i, routine_id
413 timer_env%trace_max = trace_max
414 timer_env%trace_unit = unit_nr
415 timer_env%trace_str = trace_str
416 timer_env%trace_all = .true.
417 IF (.NOT.
PRESENT(routine_names))
RETURN
420 timer_env%trace_all = .false.
421 DO i = 1,
SIZE(routine_names)
422 routine_id = routine_name2id(routine_names(i))
423 r_stat =>
list_get(timer_env%routine_stats, routine_id)
424 r_stat%trace = .true.
437 INTEGER,
INTENT(IN) :: unit_nr
453 WRITE (unit_nr,
'(/,A,/)')
" ===== Routine Calling Stack ===== "
454 DO i =
list_size(timer_env%callstack), 1, -1
455 cs_entry =
list_get(timer_env%callstack, i)
456 r_stat =>
list_get(timer_env%routine_stats, cs_entry%routine_id)
457 WRITE (unit_nr,
'(T10,I4,1X,A)') i, trim(r_stat%routineN)
471 FUNCTION routine_name2id(routineN)
RESULT(routine_id)
472 CHARACTER(LEN=default_string_length),
INTENT(IN) :: routinen
473 INTEGER :: routine_id
479 routine_id =
routine_map_get(timer_env%routine_names, routinen, default_value=-1)
481 IF (routine_id /= -1)
RETURN
485 IF (index(routinen(1:len_trim(routinen)),
' ') /= 0)
THEN
486 cpabort(
"timings_name2id: routineN contains spaces: "//routinen)
494 r_stat%routine_id = routine_id
495 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 CALL list_push(timer_env%routine_stats, r_stat)
506 END FUNCTION routine_name2id
Central dispatch for basic hooks.
procedure(timeset_interface), pointer, public timeset_hook
procedure(timestop_interface), pointer, public timestop_hook
subroutine, public callgraph_destroy(hash_map)
Deallocated the internal data-structures if the given hash map. Caution: If the stored keys or values...
subroutine, public callgraph_init(hash_map, initial_capacity)
Allocates the internal data-structures of the given hash map.
type(callgraph_item_type) function, dimension(:), pointer, public callgraph_items(hash_map)
Returns a pointer to an array of all key/value-items stored in the hash map. Caution: The caller is r...
type(call_stat_type) function, pointer, public callgraph_get(hash_map, key, default_value)
Gets a value for a given key from the hash map. If the key is not found the default_value will be ret...
subroutine, public callgraph_set(hash_map, key, value)
Stores, and possibly overwrites, a given value under a given key.
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_energy()
returns the energy used since some time in the past. The precise meaning depends on the infrastructur...
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Fortran API for the offload package, which is written in C.
subroutine, public offload_timestop()
Ends a timing range.
subroutine, public offload_timeset(routinen)
Starts a timing range.
subroutine, public offload_mem_info(free, total)
Gets free and total device memory.
integer(kind=int_4) function, public routine_map_get(hash_map, key, default_value)
Gets a value for a given key from the hash map. If the key is not found the default_value will be ret...
integer function, public routine_map_size(hash_map)
Returns the number of key/value-items currently stored in the hash map.
subroutine, public routine_map_init(hash_map, initial_capacity)
Allocates the internal data-structures of the given hash map.
subroutine, public routine_map_destroy(hash_map)
Deallocated the internal data-structures if the given hash map. Caution: If the stored keys or values...
subroutine, public routine_map_set(hash_map, key, value)
Stores, and possibly overwrites, a given value under a given key.
Types used by timings.F and timings_report.F The types in this module are used within dict or list,...
Types used by timings.F and timings_report.F Due to the fortran restriction on cicular module-depende...
Timing routines for accounting.
subroutine, public timings_register_hooks()
Registers handlers with base_hooks.F.
subroutine, public print_stack(unit_nr)
Print current routine stack.
type(timer_env_type) function, pointer, public get_timer_env()
returns the current timer env from the stack
subroutine, public timeset_handler(routinen, handle)
Start timer.
integer, save, public global_timings_level
subroutine, public timings_setup_tracing(trace_max, unit_nr, trace_str, routine_names)
Set routine tracer.
subroutine, public add_timer_env(timer_env)
adds the given timer_env to the top of the stack
subroutine, public rm_timer_env()
removes the current timer env from the stack
subroutine, public timer_env_release(timer_env)
releases the given timer env
subroutine, public timestop_handler(handle)
End timer.
subroutine, public timer_env_retain(timer_env)
retains the given timer env
integer, parameter, public default_timings_level
character(len=default_string_length), parameter, public root_cp2k_name