LCOV - code coverage report
Current view: top level - src/common - timings.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 75.8 % 178 135
Test Date: 2025-12-04 06:27:48 Functions: 91.7 % 12 11

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 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         9284 :    SUBROUTINE timings_register_hooks()
      79         9284 :       timeset_hook => timeset_handler
      80         9284 :       timestop_hook => timestop_handler
      81         9284 :    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       110811 :    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       110811 :       IF (PRESENT(timer_env)) timer_env_ => timer_env
      98        19165 :       IF (.NOT. PRESENT(timer_env)) CALL timer_env_create(timer_env_)
      99       110811 :       IF (.NOT. ASSOCIATED(timer_env_)) &
     100            0 :          CPABORT("add_timer_env: not associated")
     101              : 
     102       110811 :       CALL timer_env_retain(timer_env_)
     103       110811 :       IF (.NOT. list_isready(timers_stack)) CALL list_init(timers_stack)
     104       110811 :       CALL list_push(timers_stack, timer_env_)
     105       110811 :    END SUBROUTINE add_timer_env
     106              : 
     107              : ! **************************************************************************************************
     108              : !> \brief creates a new timer env
     109              : !> \param timer_env ...
     110              : !> \author fawzi
     111              : ! **************************************************************************************************
     112        19165 :    SUBROUTINE timer_env_create(timer_env)
     113              :       TYPE(timer_env_type), POINTER                      :: timer_env
     114              : 
     115        19165 :       ALLOCATE (timer_env)
     116        19165 :       timer_env%ref_count = 0
     117              :       timer_env%trace_max = -1 ! tracing disabled by default
     118              :       timer_env%trace_all = .FALSE.
     119        19165 :       CALL routine_map_init(timer_env%routine_names)
     120        19165 :       CALL callgraph_init(timer_env%callgraph)
     121        19165 :       CALL list_init(timer_env%routine_stats)
     122        19165 :       CALL list_init(timer_env%callstack)
     123        19165 :    END SUBROUTINE timer_env_create
     124              : 
     125              : ! **************************************************************************************************
     126              : !> \brief removes the current timer env from the stack
     127              : !> \par History
     128              : !>      02.2004 created [Joost VandeVondele]
     129              : !> \note
     130              : !>      for each rm_timer_env there should have been the symmetric call to
     131              : !>      add_timer_env
     132              : ! **************************************************************************************************
     133       110811 :    SUBROUTINE rm_timer_env()
     134              :       TYPE(timer_env_type), POINTER                      :: timer_env
     135              : 
     136       110811 :       timer_env => list_pop(timers_stack)
     137       110811 :       CALL timer_env_release(timer_env)
     138       110811 :       IF (list_size(timers_stack) == 0) CALL list_destroy(timers_stack)
     139       110811 :    END SUBROUTINE rm_timer_env
     140              : 
     141              : ! **************************************************************************************************
     142              : !> \brief returns the current timer env from the stack
     143              : !> \return ...
     144              : !> \author fawzi
     145              : ! **************************************************************************************************
     146       110887 :    FUNCTION get_timer_env() RESULT(timer_env)
     147              :       TYPE(timer_env_type), POINTER                      :: timer_env
     148              : 
     149       110887 :       timer_env => list_peek(timers_stack)
     150       110887 :    END FUNCTION get_timer_env
     151              : 
     152              : ! **************************************************************************************************
     153              : !> \brief retains the given timer env
     154              : !> \param timer_env the timer env to retain
     155              : !> \author fawzi
     156              : ! **************************************************************************************************
     157       120170 :    SUBROUTINE timer_env_retain(timer_env)
     158              :       TYPE(timer_env_type), POINTER                      :: timer_env
     159              : 
     160       120170 :       IF (.NOT. ASSOCIATED(timer_env)) &
     161            0 :          CPABORT("timer_env_retain: not associated")
     162       120170 :       IF (timer_env%ref_count < 0) &
     163            0 :          CPABORT("timer_env_retain: negativ ref_count")
     164       120170 :       timer_env%ref_count = timer_env%ref_count + 1
     165       120170 :    END SUBROUTINE timer_env_retain
     166              : 
     167              : ! **************************************************************************************************
     168              : !> \brief releases the given timer env
     169              : !> \param timer_env the timer env to release
     170              : !> \author fawzi
     171              : ! **************************************************************************************************
     172       120170 :    SUBROUTINE timer_env_release(timer_env)
     173              :       TYPE(timer_env_type), POINTER                      :: timer_env
     174              : 
     175              :       INTEGER                                            :: i
     176       120170 :       TYPE(callgraph_item_type), DIMENSION(:), POINTER   :: ct_items
     177              :       TYPE(routine_stat_type), POINTER                   :: r_stat
     178              : 
     179       120170 :       IF (.NOT. ASSOCIATED(timer_env)) &
     180            0 :          CPABORT("timer_env_release: not associated")
     181       120170 :       IF (timer_env%ref_count < 0) &
     182            0 :          CPABORT("timer_env_release: negativ ref_count")
     183       120170 :       timer_env%ref_count = timer_env%ref_count - 1
     184       120170 :       IF (timer_env%ref_count > 0) RETURN
     185              : 
     186              :       ! No more references left - let's tear down this timer_env...
     187              : 
     188      4147882 :       DO i = 1, list_size(timer_env%routine_stats)
     189      4128717 :          r_stat => list_get(timer_env%routine_stats, i)
     190      4147882 :          DEALLOCATE (r_stat)
     191              :       END DO
     192              : 
     193        19165 :       ct_items => callgraph_items(timer_env%callgraph)
     194      6929698 :       DO i = 1, SIZE(ct_items)
     195      6929698 :          DEALLOCATE (ct_items(i)%value)
     196              :       END DO
     197        19165 :       DEALLOCATE (ct_items)
     198              : 
     199        19165 :       CALL routine_map_destroy(timer_env%routine_names)
     200        19165 :       CALL callgraph_destroy(timer_env%callgraph)
     201        19165 :       CALL list_destroy(timer_env%callstack)
     202        19165 :       CALL list_destroy(timer_env%routine_stats)
     203        19165 :       DEALLOCATE (timer_env)
     204       120170 :    END SUBROUTINE timer_env_release
     205              : 
     206              : ! **************************************************************************************************
     207              : !> \brief Start timer
     208              : !> \param routineN ...
     209              : !> \param handle ...
     210              : !> \par History
     211              : !>      none
     212              : !> \author JGH
     213              : ! **************************************************************************************************
     214   1641700905 :    SUBROUTINE timeset_handler(routineN, handle)
     215              :       CHARACTER(LEN=*), INTENT(IN)                       :: routineN
     216              :       INTEGER, INTENT(OUT)                               :: handle
     217              : 
     218              :       CHARACTER(LEN=400)                                 :: line, mystring
     219              :       CHARACTER(LEN=60)                                  :: sformat
     220              :       CHARACTER(LEN=default_string_length)               :: routine_name_dsl
     221              :       INTEGER                                            :: routine_id, stack_size
     222              :       INTEGER(KIND=int_8)                                :: cpumem, gpumem_free, gpumem_total
     223              :       INTEGER, SAVE                                      :: root_cp2k_id
     224              :       TYPE(callstack_entry_type)                         :: cs_entry
     225              :       TYPE(routine_stat_type), POINTER                   :: r_stat
     226              :       TYPE(timer_env_type), POINTER                      :: timer_env
     227              : 
     228   1641700905 : !$OMP MASTER
     229              : 
     230              :       ! Default value, using a negative value when timing is not taken
     231   1641700905 :       cs_entry%walltime_start = -HUGE(1.0_dp)
     232   1641700905 :       cs_entry%energy_start = -HUGE(1.0_dp)
     233   1641700905 :       root_cp2k_id = routine_name2id(root_cp2k_name)
     234              :       !
     235   1641700905 :       routine_name_dsl = routineN ! converte to default_string_length
     236   1641700905 :       routine_id = routine_name2id(routine_name_dsl)
     237              :       !
     238              :       ! Take timings when the timings_level is appropriated
     239   1641700905 :       IF (global_timings_level /= 0 .OR. routine_id == root_cp2k_id) THEN
     240   1641700905 :          cs_entry%walltime_start = m_walltime()
     241   1641700905 :          cs_entry%energy_start = m_energy()
     242              :       END IF
     243   1641700905 :       timer_env => list_peek(timers_stack)
     244              : 
     245   1641700905 :       IF (LEN_TRIM(routineN) > default_string_length) THEN
     246            0 :          CPABORT('timings_timeset: routineN too long: "'//TRIM(routineN)//"'")
     247              :       END IF
     248              : 
     249              :       ! update routine r_stats
     250   1641700905 :       r_stat => list_get(timer_env%routine_stats, routine_id)
     251   1641700905 :       stack_size = list_size(timer_env%callstack)
     252   1641700905 :       r_stat%total_calls = r_stat%total_calls + 1
     253   1641700905 :       r_stat%active_calls = r_stat%active_calls + 1
     254   1641700905 :       r_stat%stackdepth_accu = r_stat%stackdepth_accu + stack_size + 1
     255              : 
     256              :       ! add routine to callstack
     257   1641700905 :       cs_entry%routine_id = routine_id
     258   1641700905 :       CALL list_push(timer_env%callstack, cs_entry)
     259              : 
     260              :       !..if debug mode echo the subroutine name
     261   1641700905 :       IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
     262              :           (r_stat%total_calls < timer_env%trace_max)) THEN
     263            0 :          WRITE (sformat, *) "(A,A,", MAX(1, 3*stack_size - 4), "X,I4,1X,I6,1X,A,A)"
     264            0 :          WRITE (mystring, sformat) timer_env%trace_str, ">>", stack_size + 1, &
     265            0 :             r_stat%total_calls, TRIM(r_stat%routineN), "       start"
     266            0 :          CALL offload_mem_info(gpumem_free, gpumem_total)
     267            0 :          CALL m_memory(cpumem)
     268            0 :          WRITE (line, '(A,A,I0,A,A,I0,A)') TRIM(mystring), &
     269            0 :             " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024), " MB", &
     270            0 :             " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024), " MB"
     271            0 :          WRITE (timer_env%trace_unit, *) TRIM(line)
     272            0 :          CALL m_flush(timer_env%trace_unit)
     273              :       END IF
     274              : 
     275   1641700905 :       handle = routine_id
     276              : 
     277   1641700905 :       CALL offload_timeset(routineN)
     278              : 
     279              : !$OMP END MASTER
     280              : 
     281   1641700905 :    END SUBROUTINE timeset_handler
     282              : 
     283              : ! **************************************************************************************************
     284              : !> \brief End timer
     285              : !> \param handle ...
     286              : !> \par History
     287              : !>      none
     288              : !> \author JGH
     289              : ! **************************************************************************************************
     290   1641700905 :    SUBROUTINE timestop_handler(handle)
     291              :       INTEGER, INTENT(in)                                :: handle
     292              : 
     293              :       CHARACTER(LEN=400)                                 :: line, mystring
     294              :       CHARACTER(LEN=60)                                  :: sformat
     295              :       INTEGER                                            :: routine_id, stack_size
     296              :       INTEGER(KIND=int_8)                                :: cpumem, gpumem_free, gpumem_total
     297              :       INTEGER, DIMENSION(2)                              :: routine_tuple
     298              :       REAL(KIND=dp)                                      :: en_elapsed, en_now, wt_elapsed, wt_now
     299              :       TYPE(call_stat_type), POINTER                      :: c_stat
     300              :       TYPE(callstack_entry_type)                         :: cs_entry, prev_cs_entry
     301              :       TYPE(routine_stat_type), POINTER                   :: prev_stat, r_stat
     302              :       TYPE(timer_env_type), POINTER                      :: timer_env
     303              : 
     304   1641700905 :       routine_id = handle
     305              : 
     306   1641700905 : !$OMP MASTER
     307              : 
     308   1641700905 :       CALL offload_timestop()
     309              : 
     310   1641700905 :       timer_env => list_peek(timers_stack)
     311   1641700905 :       cs_entry = list_pop(timer_env%callstack)
     312   1641700905 :       r_stat => list_get(timer_env%routine_stats, cs_entry%routine_id)
     313              : 
     314   1641700905 :       IF (handle /= cs_entry%routine_id) THEN
     315            0 :          PRINT *, "list_size(timer_env%callstack) ", list_size(timer_env%callstack), &
     316            0 :             " handle ", handle, " list_size(timers_stack) ", list_size(timers_stack)
     317            0 :          CPABORT('mismatched timestop '//TRIM(r_stat%routineN)//' in routine timestop')
     318              :       END IF
     319              : 
     320   1641700905 :       wt_elapsed = 0
     321   1641700905 :       en_elapsed = 0
     322              :       ! Take timings only when the start time is >=0, i.e. the timings_level is appropriated
     323   1641700905 :       IF (cs_entry%walltime_start >= 0) THEN
     324   1641700905 :          wt_now = m_walltime()
     325   1641700905 :          en_now = m_energy()
     326              :          ! add the elapsed time for this timeset/timestop to the time accumulator
     327   1641700905 :          wt_elapsed = wt_now - cs_entry%walltime_start
     328   1641700905 :          en_elapsed = en_now - cs_entry%energy_start
     329              :       END IF
     330   1641700905 :       r_stat%active_calls = r_stat%active_calls - 1
     331              : 
     332              :       ! if we're the last instance in the stack, we do the accounting of the total time
     333   1641700905 :       IF (r_stat%active_calls == 0) THEN
     334   1638602361 :          r_stat%incl_walltime_accu = r_stat%incl_walltime_accu + wt_elapsed
     335   1638602361 :          r_stat%incl_energy_accu = r_stat%incl_energy_accu + en_elapsed
     336              :       END IF
     337              : 
     338              :       ! exclusive time we always sum, since children will correct this time with their total time
     339   1641700905 :       r_stat%excl_walltime_accu = r_stat%excl_walltime_accu + wt_elapsed
     340   1641700905 :       r_stat%excl_energy_accu = r_stat%excl_energy_accu + en_elapsed
     341              : 
     342   1641700905 :       stack_size = list_size(timer_env%callstack)
     343   1641700905 :       IF (stack_size > 0) THEN
     344   1605866990 :          prev_cs_entry = list_peek(timer_env%callstack)
     345   1605866990 :          prev_stat => list_get(timer_env%routine_stats, prev_cs_entry%routine_id)
     346              :          ! we fixup the clock of the caller
     347   1605866990 :          prev_stat%excl_walltime_accu = prev_stat%excl_walltime_accu - wt_elapsed
     348   1605866990 :          prev_stat%excl_energy_accu = prev_stat%excl_energy_accu - en_elapsed
     349              : 
     350              :          !update callgraph
     351   4817600970 :          routine_tuple = [prev_cs_entry%routine_id, routine_id]
     352   1605866990 :          c_stat => callgraph_get(timer_env%callgraph, routine_tuple, default_value=Null(c_stat))
     353   1605866990 :          IF (.NOT. ASSOCIATED(c_stat)) THEN
     354      6910533 :             ALLOCATE (c_stat)
     355              :             c_stat%total_calls = 0
     356              :             c_stat%incl_walltime_accu = 0.0_dp
     357              :             c_stat%incl_energy_accu = 0.0_dp
     358      6910533 :             CALL callgraph_set(timer_env%callgraph, routine_tuple, c_stat)
     359              :          END IF
     360   1605866990 :          c_stat%total_calls = c_stat%total_calls + 1
     361   1605866990 :          c_stat%incl_walltime_accu = c_stat%incl_walltime_accu + wt_elapsed
     362   1605866990 :          c_stat%incl_energy_accu = c_stat%incl_energy_accu + en_elapsed
     363              :       END IF
     364              : 
     365              :       !..if debug mode echo the subroutine name
     366   1641700905 :       IF ((timer_env%trace_all .OR. r_stat%trace) .AND. &
     367              :           (r_stat%total_calls < timer_env%trace_max)) THEN
     368            0 :          WRITE (sformat, *) "(A,A,", MAX(1, 3*stack_size - 4), "X,I4,1X,I6,1X,A,F12.3)"
     369            0 :          WRITE (mystring, sformat) timer_env%trace_str, "<<", stack_size + 1, &
     370            0 :             r_stat%total_calls, TRIM(r_stat%routineN), wt_elapsed
     371            0 :          CALL offload_mem_info(gpumem_free, gpumem_total)
     372            0 :          CALL m_memory(cpumem)
     373            0 :          WRITE (line, '(A,A,I0,A,A,I0,A)') TRIM(mystring), &
     374            0 :             " Hostmem: ", (cpumem + 1024*1024 - 1)/(1024*1024), " MB", &
     375            0 :             " GPUmem: ", (gpumem_total - gpumem_free)/(1024*1024), " MB"
     376            0 :          WRITE (timer_env%trace_unit, *) TRIM(line)
     377            0 :          CALL m_flush(timer_env%trace_unit)
     378              :       END IF
     379              : 
     380              : !$OMP END MASTER
     381              : 
     382   1641700905 :    END SUBROUTINE timestop_handler
     383              : 
     384              : ! **************************************************************************************************
     385              : !> \brief Set routine tracer
     386              : !> \param trace_max  maximum number of calls reported per routine.
     387              : !>           Setting this to zero disables tracing.
     388              : !> \param unit_nr output unit used for printing the trace-messages
     389              : !> \param trace_str short info-string which is printed along with every message
     390              : !> \param routine_names List of routine-names.
     391              : !>                     If provided only these routines will be traced.
     392              : !>                     If not present all routines will traced.
     393              : !> \par History
     394              : !>       12.2012  added ability to trace only certain routines [ole]
     395              : !> \author JGH
     396              : ! **************************************************************************************************
     397            0 :    SUBROUTINE timings_setup_tracing(trace_max, unit_nr, trace_str, routine_names)
     398              :       INTEGER, INTENT(IN)                                :: trace_max, unit_nr
     399              :       CHARACTER(len=13), INTENT(IN)                      :: trace_str
     400              :       CHARACTER(len=default_string_length), &
     401              :          DIMENSION(:), INTENT(IN), OPTIONAL              :: routine_names
     402              : 
     403              :       INTEGER                                            :: i, routine_id
     404              :       TYPE(routine_stat_type), POINTER                   :: r_stat
     405              :       TYPE(timer_env_type), POINTER                      :: timer_env
     406              : 
     407            0 :       timer_env => list_peek(timers_stack)
     408            0 :       timer_env%trace_max = trace_max
     409            0 :       timer_env%trace_unit = unit_nr
     410            0 :       timer_env%trace_str = trace_str
     411            0 :       timer_env%trace_all = .TRUE.
     412            0 :       IF (.NOT. PRESENT(routine_names)) RETURN
     413              : 
     414              :       ! setup routine-specific tracing
     415            0 :       timer_env%trace_all = .FALSE.
     416            0 :       DO i = 1, SIZE(routine_names)
     417            0 :          routine_id = routine_name2id(routine_names(i))
     418            0 :          r_stat => list_get(timer_env%routine_stats, routine_id)
     419            0 :          r_stat%trace = .TRUE.
     420              :       END DO
     421              : 
     422              :    END SUBROUTINE timings_setup_tracing
     423              : 
     424              : ! **************************************************************************************************
     425              : !> \brief Print current routine stack
     426              : !> \param unit_nr ...
     427              : !> \par History
     428              : !>      none
     429              : !> \author JGH
     430              : ! **************************************************************************************************
     431          567 :    SUBROUTINE print_stack(unit_nr)
     432              :       INTEGER, INTENT(IN)                                :: unit_nr
     433              : 
     434              :       INTEGER                                            :: i
     435              :       TYPE(callstack_entry_type)                         :: cs_entry
     436              :       TYPE(routine_stat_type), POINTER                   :: r_stat
     437              :       TYPE(timer_env_type), POINTER                      :: timer_env
     438              : 
     439              :       ! catch edge cases where timer_env is not yet/anymore available
     440          567 :       IF (.NOT. list_isready(timers_stack)) &
     441            0 :          RETURN
     442          567 :       IF (list_size(timers_stack) == 0) &
     443              :          RETURN
     444              : 
     445          567 :       timer_env => list_peek(timers_stack)
     446          567 :       WRITE (unit_nr, '(/,A,/)') " ===== Routine Calling Stack ===== "
     447         3377 :       DO i = list_size(timer_env%callstack), 1, -1
     448         2810 :          cs_entry = list_get(timer_env%callstack, i)
     449         2810 :          r_stat => list_get(timer_env%routine_stats, cs_entry%routine_id)
     450         3377 :          WRITE (unit_nr, '(T10,I4,1X,A)') i, TRIM(r_stat%routineN)
     451              :       END DO
     452          567 :       CALL m_flush(unit_nr)
     453              : 
     454          567 :    END SUBROUTINE print_stack
     455              : 
     456              : ! **************************************************************************************************
     457              : !> \brief Internal routine used by timestet and timings_setup_tracing.
     458              : !>        If no routine with given name is found in timer_env%routine_names
     459              : !>        then a new entiry is created.
     460              : !> \param routineN ...
     461              : !> \return ...
     462              : !> \author Ole Schuett
     463              : ! **************************************************************************************************
     464   3283401810 :    FUNCTION routine_name2id(routineN) RESULT(routine_id)
     465              :       CHARACTER(LEN=default_string_length), INTENT(IN)   :: routineN
     466              :       INTEGER                                            :: routine_id
     467              : 
     468              :       TYPE(routine_stat_type), POINTER                   :: r_stat
     469              :       TYPE(timer_env_type), POINTER                      :: timer_env
     470              : 
     471   3283401810 :       timer_env => list_peek(timers_stack)
     472   3283401810 :       routine_id = routine_map_get(timer_env%routine_names, routineN, default_value=-1)
     473              : 
     474   3283401810 :       IF (routine_id /= -1) RETURN ! found an id - let's return it
     475              :       ! routine not found - let's create it
     476              : 
     477              :       ! enforce space free timer names, to make the output of trace/timings of a fixed number fields
     478      4128717 :       IF (INDEX(routineN(1:LEN_TRIM(routineN)), ' ') /= 0) THEN
     479            0 :          CPABORT("timings_name2id: routineN contains spaces: "//routineN)
     480              :       END IF
     481              : 
     482              :       ! register routine_name_dsl with new routine_id
     483      4128717 :       routine_id = routine_map_size(timer_env%routine_names) + 1
     484      4128717 :       CALL routine_map_set(timer_env%routine_names, routineN, routine_id)
     485              : 
     486      4128717 :       ALLOCATE (r_stat)
     487      4128717 :       r_stat%routine_id = routine_id
     488      4128717 :       r_stat%routineN = routineN
     489              :       r_stat%active_calls = 0
     490              :       r_stat%excl_walltime_accu = 0.0_dp
     491              :       r_stat%incl_walltime_accu = 0.0_dp
     492              :       r_stat%excl_energy_accu = 0.0_dp
     493              :       r_stat%incl_energy_accu = 0.0_dp
     494              :       r_stat%total_calls = 0
     495              :       r_stat%stackdepth_accu = 0
     496              :       r_stat%trace = .FALSE.
     497      4128717 :       CALL list_push(timer_env%routine_stats, r_stat)
     498      4128717 :       CPASSERT(list_size(timer_env%routine_stats) == routine_map_size(timer_env%routine_names))
     499              :    END FUNCTION routine_name2id
     500              : 
     501              : END MODULE timings
     502              : 
        

Generated by: LCOV version 2.0-1