LCOV - code coverage report
Current view: top level - src/common - timings.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 75.8 % 178 135
Test Date: 2026-07-25 06:35:44 Functions: 91.7 % 12 11

            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              : 
        

Generated by: LCOV version 2.0-1