LCOV - code coverage report
Current view: top level - cicecore/cicedyn/infrastructure/comm/serial - ice_timers.F90 (source / functions) Hit Total Coverage
Test: 231018-211459:8916b9ff2c:1:quick Lines: 125 190 65.79 %
Date: 2023-10-18 15:30:36 Functions: 6 9 66.67 %

          Line data    Source code
       1             : !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
       2             : 
       3             :  module ice_timers
       4             : 
       5             : !  This module contains routine for supporting multiple CPU timers
       6             : !  and accumulates time for each individual block and node (task).
       7             : !
       8             : ! 2005: Adapted from POP by William Lipscomb
       9             : !       Replaced 'stdout' by 'nu_diag'
      10             : 
      11             :    use ice_kinds_mod
      12             :    use ice_constants, only: c0, c1
      13             :    use ice_domain, only: nblocks, distrb_info
      14             :    use ice_global_reductions, only: global_minval, global_maxval, global_sum
      15             :    use ice_exit, only: abort_ice
      16             :    use ice_fileunits, only: nu_diag
      17             :    use ice_communicate, only: my_task, master_task
      18             :    use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted
      19             :    use icepack_intfc, only: icepack_query_parameters
      20             : 
      21             :    implicit none
      22             :    private
      23             : 
      24             :    public :: init_ice_timers,     &
      25             :              get_ice_timer,       &   ! LCOV_EXCL_LINE
      26             :              ice_timer_clear,     &   ! LCOV_EXCL_LINE
      27             :              ice_timer_start,     &   ! LCOV_EXCL_LINE
      28             :              ice_timer_stop,      &   ! LCOV_EXCL_LINE
      29             :              ice_timer_print,     &   ! LCOV_EXCL_LINE
      30             :              ice_timer_print_all, &   ! LCOV_EXCL_LINE
      31             :              ice_timer_check
      32             : 
      33             :    logical(log_kind),  public ::      &
      34             :       timer_stats              ! controls printing of timer statistics
      35             : 
      36             : !-----------------------------------------------------------------------
      37             : ! public timers
      38             : !-----------------------------------------------------------------------
      39             : 
      40             :    integer (int_kind), public ::      &
      41             :       timer_total,            &! total time   ! LCOV_EXCL_LINE
      42             :       timer_step,             &! time stepping   ! LCOV_EXCL_LINE
      43             :       timer_dynamics,         &! dynamics   ! LCOV_EXCL_LINE
      44             :       timer_advect,           &! horizontal advection   ! LCOV_EXCL_LINE
      45             :       timer_column,           &! column   ! LCOV_EXCL_LINE
      46             :       timer_thermo,           &! thermodynamics   ! LCOV_EXCL_LINE
      47             :       timer_sw,               &! radiative transfer   ! LCOV_EXCL_LINE
      48             :       timer_ponds,            &! melt ponds   ! LCOV_EXCL_LINE
      49             :       timer_ridge,            &! ridging   ! LCOV_EXCL_LINE
      50             :       timer_catconv,          &! category conversions   ! LCOV_EXCL_LINE
      51             :       timer_fsd,              &! floe size distribution   ! LCOV_EXCL_LINE
      52             :       timer_couple,           &! coupling   ! LCOV_EXCL_LINE
      53             :       timer_readwrite,        &! read/write   ! LCOV_EXCL_LINE
      54             :       timer_diags,            &! diagnostics/history   ! LCOV_EXCL_LINE
      55             :       timer_hist,             &! diagnostics/history   ! LCOV_EXCL_LINE
      56             :       timer_bound,            &! boundary updates   ! LCOV_EXCL_LINE
      57             :       timer_bundbound,        &! boundary updates   ! LCOV_EXCL_LINE
      58             :       timer_bgc,              &! biogeochemistry   ! LCOV_EXCL_LINE
      59             :       timer_forcing,          &! forcing   ! LCOV_EXCL_LINE
      60             :       timer_evp_1d,           &! timer only loop   ! LCOV_EXCL_LINE
      61             :       timer_evp_2d,           &! timer including conversion 1d/2d   ! LCOV_EXCL_LINE
      62             :       timer_updstate           ! update state
      63             : !      timer_updstate,         &! update state
      64             : !      timer_tmp1,             &! for temporary timings   ! LCOV_EXCL_LINE
      65             : !      timer_tmp2,             &! for temporary timings   ! LCOV_EXCL_LINE
      66             : !      timer_tmp3,             &! for temporary timings   ! LCOV_EXCL_LINE
      67             : !      timer_tmp4,             &! for temporary timings   ! LCOV_EXCL_LINE
      68             : !      timer_tmp5,             &! for temporary timings   ! LCOV_EXCL_LINE
      69             : !      timer_tmp6,             &! for temporary timings   ! LCOV_EXCL_LINE
      70             : !      timer_tmp7,             &! for temporary timings   ! LCOV_EXCL_LINE
      71             : !      timer_tmp8,             &! for temporary timings   ! LCOV_EXCL_LINE
      72             : !      timer_tmp9               ! for temporary timings
      73             : 
      74             : !-----------------------------------------------------------------------
      75             : !
      76             : !  module variables
      77             : !
      78             : !-----------------------------------------------------------------------
      79             : 
      80             :    integer (int_kind), parameter :: &
      81             :       max_timers = 50          ! max number of timers
      82             : 
      83             :    type timer_data
      84             :       character (char_len) :: &
      85             :          name                  ! timer name
      86             : 
      87             :       logical (log_kind) ::   &
      88             :          in_use,              &! true if timer initialized   ! LCOV_EXCL_LINE
      89             :          node_started          ! true if any thread has started timer
      90             : 
      91             :       integer (int_kind) ::   &
      92             :          num_blocks,          &! number of blocks using this timer   ! LCOV_EXCL_LINE
      93             :          num_nodes,           &! number of nodes  using this timer   ! LCOV_EXCL_LINE
      94             :          num_starts,          &! number of start requests   ! LCOV_EXCL_LINE
      95             :          num_stops             ! number of stop requests
      96             : 
      97             :       real (dbl_kind) :: &
      98             :          node_cycles1,        &! cycle number at start for node timer   ! LCOV_EXCL_LINE
      99             :          node_cycles2          ! cycle number at stop  for node timer
     100             : 
     101             :       real (dbl_kind) ::            &
     102             :          node_accum_time       ! accumulated time for node timer
     103             : 
     104             :       logical (log_kind), dimension(:), pointer :: &
     105             :          block_started         ! true if block timer started
     106             : 
     107             :       real (dbl_kind), dimension(:), pointer :: &
     108             :          block_cycles1,        &! cycle number at start for block timers   ! LCOV_EXCL_LINE
     109             :          block_cycles2          ! cycle number at stop  for block timers
     110             : 
     111             :       real (dbl_kind), dimension(:), pointer :: &
     112             :          block_accum_time       ! accumulated time for block timers
     113             : 
     114             :    end type
     115             : 
     116             :    type (timer_data), dimension(max_timers) :: &
     117             :       all_timers               ! timer data for all timers
     118             : 
     119             :    integer (int_kind) ::      &
     120             :       cycles_max               ! max clock cycles allowed by system
     121             : 
     122             :    real (dbl_kind) ::               &
     123             :       clock_rate               ! clock rate in seconds for each cycle
     124             : 
     125             : !***********************************************************************
     126             : 
     127             :  contains
     128             : 
     129             : !***********************************************************************
     130             : 
     131           1 :  subroutine init_ice_timers
     132             : 
     133             : !  This routine initializes machine parameters and timer structures
     134             : !  for computing cpu time from F90 intrinsic timer functions.
     135             : 
     136             : !-----------------------------------------------------------------------
     137             : !
     138             : !  local variables
     139             : !
     140             : !-----------------------------------------------------------------------
     141             : 
     142             :    integer (int_kind) :: &
     143             :       n,                 &! dummy loop counters   ! LCOV_EXCL_LINE
     144             :       cycles              ! count rate returned by sys_clock
     145             : 
     146             :    character(len=*), parameter :: subname = '(init_ice_timers)'
     147             : 
     148             : !-----------------------------------------------------------------------
     149             : !
     150             : !  Call F90 intrinsic system_clock to determine clock rate
     151             : !  and maximum cycles for single-processor runs.  If no clock
     152             : !  available, print message.
     153             : !
     154             : !-----------------------------------------------------------------------
     155             : 
     156           1 :    cycles = 0
     157             : 
     158           1 :    call system_clock(count_rate=cycles, count_max=cycles_max)
     159             : 
     160           1 :    if (cycles /= 0) then
     161           1 :       clock_rate = c1/real(cycles,kind=dbl_kind)
     162             :    else
     163           0 :       clock_rate = c0
     164           0 :       write(nu_diag,'(/,a33,/)') '--- No system clock available ---'
     165             :    endif
     166             : 
     167             : !-----------------------------------------------------------------------
     168             : !
     169             : !  initialize timer structures
     170             : !
     171             : !-----------------------------------------------------------------------
     172             : 
     173          51 :    do n=1,max_timers
     174          50 :       all_timers(n)%name = 'unknown_timer_name'
     175             : 
     176          50 :       all_timers(n)%in_use       = .false.
     177          50 :       all_timers(n)%node_started = .false.
     178             : 
     179          50 :       all_timers(n)%num_blocks   = 0
     180          50 :       all_timers(n)%num_nodes    = 0
     181          50 :       all_timers(n)%num_starts   = 0
     182          50 :       all_timers(n)%num_stops    = 0
     183          50 :       all_timers(n)%node_cycles1 = c0
     184          50 :       all_timers(n)%node_cycles2 = c0
     185             : 
     186          50 :       all_timers(n)%node_accum_time = c0
     187             : 
     188          50 :       nullify(all_timers(n)%block_started)
     189          50 :       nullify(all_timers(n)%block_cycles1)
     190          50 :       nullify(all_timers(n)%block_cycles2)
     191          51 :       nullify(all_timers(n)%block_accum_time)
     192             :    end do
     193             : 
     194           1 :    call get_ice_timer(timer_total,    'Total',    nblocks,distrb_info%nprocs)
     195           1 :    call get_ice_timer(timer_step,     'TimeLoop', nblocks,distrb_info%nprocs)
     196           1 :    call get_ice_timer(timer_dynamics, 'Dynamics', nblocks,distrb_info%nprocs)
     197           1 :    call get_ice_timer(timer_advect,   'Advection',nblocks,distrb_info%nprocs)
     198           1 :    call get_ice_timer(timer_column,   'Column',   nblocks,distrb_info%nprocs)
     199           1 :    call get_ice_timer(timer_thermo,   'Thermo',   nblocks,distrb_info%nprocs)
     200           1 :    call get_ice_timer(timer_sw,       'Shortwave',nblocks,distrb_info%nprocs)
     201             : !   call get_ice_timer(timer_ponds,    'Meltponds',nblocks,distrb_info%nprocs)
     202           1 :    call get_ice_timer(timer_ridge,    'Ridging',  nblocks,distrb_info%nprocs)
     203             : !   call get_ice_timer(timer_catconv,  'Cat Conv', nblocks,distrb_info%nprocs)
     204           1 :    call get_ice_timer(timer_fsd,      'FloeSize', nblocks,distrb_info%nprocs)
     205           1 :    call get_ice_timer(timer_couple,   'Coupling', nblocks,distrb_info%nprocs)
     206           1 :    call get_ice_timer(timer_readwrite,'ReadWrite',nblocks,distrb_info%nprocs)
     207           1 :    call get_ice_timer(timer_diags,    'Diags    ',nblocks,distrb_info%nprocs)
     208           1 :    call get_ice_timer(timer_hist,     'History  ',nblocks,distrb_info%nprocs)
     209           1 :    call get_ice_timer(timer_bound,    'Bound',    nblocks,distrb_info%nprocs)
     210           1 :    call get_ice_timer(timer_bundbound,'Bundbound',nblocks,distrb_info%nprocs)
     211           1 :    call get_ice_timer(timer_bgc,      'BGC',      nblocks,distrb_info%nprocs)
     212           1 :    call get_ice_timer(timer_forcing,  'Forcing',  nblocks,distrb_info%nprocs)
     213           1 :    call get_ice_timer(timer_evp_1d,   '1d-evp',   nblocks,distrb_info%nprocs)
     214           1 :    call get_ice_timer(timer_evp_2d,   '2d-evp',   nblocks,distrb_info%nprocs)
     215           1 :    call get_ice_timer(timer_updstate, 'UpdState', nblocks,distrb_info%nprocs)
     216             : !   call get_ice_timer(timer_tmp1,     'tmp1',     nblocks,distrb_info%nprocs)
     217             : !   call get_ice_timer(timer_tmp2,     'tmp2',     nblocks,distrb_info%nprocs)
     218             : !   call get_ice_timer(timer_tmp3,     'tmp3',     nblocks,distrb_info%nprocs)
     219             : !   call get_ice_timer(timer_tmp4,     'tmp4',     nblocks,distrb_info%nprocs)
     220             : !   call get_ice_timer(timer_tmp5,     'tmp5',     nblocks,distrb_info%nprocs)
     221             : !   call get_ice_timer(timer_tmp6,     'tmp6',     nblocks,distrb_info%nprocs)
     222             : !   call get_ice_timer(timer_tmp7,     'tmp7',     nblocks,distrb_info%nprocs)
     223             : !   call get_ice_timer(timer_tmp8,     'tmp8',     nblocks,distrb_info%nprocs)
     224             : !   call get_ice_timer(timer_tmp9,     'tmp9',     nblocks,distrb_info%nprocs)
     225             : 
     226             : !-----------------------------------------------------------------------
     227             : 
     228           1 :    end subroutine init_ice_timers
     229             : 
     230             : !***********************************************************************
     231             : 
     232          20 :  subroutine get_ice_timer(timer_id, name_choice, num_blocks, num_nodes)
     233             : 
     234             : !  This routine initializes a timer with a given name and returns a
     235             : !  timer id.
     236             : 
     237             :    character (*), intent(in) :: &
     238             :       name_choice               ! input name for this timer
     239             : 
     240             :    integer (int_kind), intent(in) :: &
     241             :       num_nodes,               &! number of nodes(tasks) using this timer   ! LCOV_EXCL_LINE
     242             :       num_blocks                ! number of blocks using this timer
     243             :                                 ! (can be =1 if timer called outside
     244             :                                 !  threaded region)
     245             : 
     246             :    integer (int_kind), intent(out) :: &
     247             :       timer_id           ! timer number assigned to this timer
     248             : 
     249             : !-----------------------------------------------------------------------
     250             : !
     251             : !  local variables
     252             : !
     253             : !-----------------------------------------------------------------------
     254             : 
     255             :    integer (int_kind) :: &
     256             :       n,                 &! dummy loop index   ! LCOV_EXCL_LINE
     257             :       srch_error          ! error flag for search
     258             : 
     259             :    character(len=*), parameter :: subname = '(get_ice_timer)'
     260             : 
     261             : !-----------------------------------------------------------------------
     262             : !
     263             : !  search for next free timer
     264             : !
     265             : !-----------------------------------------------------------------------
     266             : 
     267          20 :    srch_error = 1
     268             : 
     269         210 :    srch_loop: do n=1,max_timers
     270         210 :       if (.not. all_timers(n)%in_use) then
     271          20 :          srch_error = 0
     272          20 :          timer_id = n
     273             : 
     274          20 :          all_timers(n)%name       = ' '
     275          20 :          all_timers(n)%name       = name_choice
     276          20 :          all_timers(n)%in_use     = .true.
     277          20 :          all_timers(n)%num_blocks = num_blocks
     278          20 :          all_timers(n)%num_nodes  = num_nodes
     279             : 
     280             :          allocate(all_timers(n)%block_started   (num_blocks), &
     281             :                   all_timers(n)%block_cycles1   (num_blocks), &   ! LCOV_EXCL_LINE
     282             :                   all_timers(n)%block_cycles2   (num_blocks), &   ! LCOV_EXCL_LINE
     283          20 :                   all_timers(n)%block_accum_time(num_blocks))
     284             : 
     285          40 :          all_timers(n)%block_started    = .false.
     286          40 :          all_timers(n)%block_cycles1    = c0
     287          40 :          all_timers(n)%block_cycles2    = c0
     288          40 :          all_timers(n)%block_accum_time = c0
     289             : 
     290          20 :          exit srch_loop
     291             :       endif
     292             :    end do srch_loop
     293             : 
     294          20 :    if (srch_error /= 0) &
     295           0 :       call abort_ice(subname//'ERROR: Exceeded maximum number of timers')
     296             : 
     297             : 
     298             : !-----------------------------------------------------------------------
     299             : 
     300          20 :  end subroutine get_ice_timer
     301             : 
     302             : !***********************************************************************
     303             : 
     304           0 :  subroutine ice_timer_clear(timer_id)
     305             : 
     306             : !  This routine resets the time for a timer which has already been
     307             : !  defined.  NOTE: This routine must be called from outside a threaded
     308             : !  region to ensure correct reset of block timers.
     309             : 
     310             :    integer (int_kind), intent(in) :: &
     311             :       timer_id                ! timer number
     312             : 
     313             :    character(len=*), parameter :: subname = '(ice_timer_clear)'
     314             : 
     315             : !-----------------------------------------------------------------------
     316             : !
     317             : !  if the timer has been defined, reset all times to 0
     318             : !  otherwise exit with an error
     319             : !
     320             : !-----------------------------------------------------------------------
     321             : 
     322           0 :    if (all_timers(timer_id)%in_use) then
     323           0 :       all_timers(timer_id)%node_started  = .false.
     324           0 :       all_timers(timer_id)%num_starts    = 0
     325           0 :       all_timers(timer_id)%num_stops     = 0
     326           0 :       all_timers(timer_id)%node_cycles1  = c0
     327           0 :       all_timers(timer_id)%node_cycles2  = c0
     328             : 
     329           0 :       all_timers(timer_id)%node_accum_time = c0
     330             : 
     331           0 :       all_timers(timer_id)%block_started(:)    = .false.
     332           0 :       all_timers(timer_id)%block_cycles1(:)    = c0
     333           0 :       all_timers(timer_id)%block_cycles2(:)    = c0
     334           0 :       all_timers(timer_id)%block_accum_time(:) = c0
     335             :    else
     336           0 :       call abort_ice(subname//'ERROR: attempt to reset undefined timer')
     337             : 
     338             :    endif
     339             : 
     340             : !-----------------------------------------------------------------------
     341             : 
     342           0 :  end subroutine ice_timer_clear
     343             : 
     344             : !***********************************************************************
     345             : 
     346        6609 :  subroutine ice_timer_start(timer_id, block_id)
     347             : 
     348             : !  This routine starts a given node timer if it has not already
     349             : !  been started by another thread.  If block information is available,
     350             : !  the appropriate block timer is also started.
     351             : 
     352             :    integer (int_kind), intent(in) :: &
     353             :       timer_id                   ! timer number
     354             : 
     355             :    integer (int_kind), intent(in), optional :: &
     356             :       block_id                 ! optional block id for this block
     357             :                                ! this must be the actual local address
     358             :                                ! of the block in the distribution
     359             :                                ! from which it is called
     360             :                                ! (if timer called outside of block
     361             :                                ! region, no block info required)
     362             : 
     363             :    integer (int_kind) :: &
     364             :       cycles                   ! count rate return by sys_clock
     365             : 
     366             :    character(len=*), parameter :: subname = '(ice_timer_start)'
     367             : 
     368             : !   if (my_task == master_task) write(nu_diag,*) subname,trim(all_timers(timer_id)%name)
     369             : 
     370             : !-----------------------------------------------------------------------
     371             : !
     372             : !  if timer is defined, start it up
     373             : !
     374             : !-----------------------------------------------------------------------
     375             : 
     376        6609 :    if (all_timers(timer_id)%in_use) then
     377             : 
     378             :       !***
     379             :       !*** if called from within a block loop, start block timers
     380             :       !***
     381             : 
     382        6609 :       if (present(block_id)) then
     383             : 
     384             :          !*** if block timer already started, stop it first
     385             : 
     386         120 :          if (all_timers(timer_id)%block_started(block_id)) &
     387           0 :             call ice_timer_stop(timer_id, block_id)
     388             : 
     389             :          !*** start block timer
     390             : 
     391         120 :          all_timers(timer_id)%block_started(block_id) = .true.
     392         120 :          call system_clock(count=cycles)
     393         120 :          all_timers(timer_id)%block_cycles1(block_id) = real(cycles,kind=dbl_kind)
     394             : 
     395             :          !*** start node timer if not already started by
     396             :          !*** another thread.  if already started, keep track
     397             :          !*** of number of start requests in order to match
     398             :          !*** start and stop requests
     399             : 
     400             :          !$OMP CRITICAL
     401             : 
     402         120 :          if (.not. all_timers(timer_id)%node_started) then
     403         120 :             all_timers(timer_id)%node_started = .true.
     404         120 :             all_timers(timer_id)%num_starts   = 1
     405         120 :             all_timers(timer_id)%num_stops    = 0
     406         120 :             call system_clock(count=cycles)
     407         120 :             all_timers(timer_id)%node_cycles1 = real(cycles,kind=dbl_kind)
     408             :          else
     409             :             all_timers(timer_id)%num_starts = &
     410           0 :             all_timers(timer_id)%num_starts + 1
     411             :          endif
     412             : 
     413             :          !$OMP END CRITICAL
     414             : 
     415             :       !***
     416             :       !*** if called from outside a block loop, start node timer
     417             :       !***
     418             : 
     419             :       else
     420             : 
     421             :          !*** stop timer if already started
     422        6489 :          if (all_timers(timer_id)%node_started)  &
     423           0 :                                         call ice_timer_stop(timer_id)
     424             : 
     425             :          !*** start node timer
     426             : 
     427        6489 :          all_timers(timer_id)%node_started = .true.
     428        6489 :          call system_clock(count=cycles)
     429        6489 :          all_timers(timer_id)%node_cycles1 = real(cycles,kind=dbl_kind)
     430             : 
     431             :       endif
     432             :    else
     433           0 :       call abort_ice(subname//'ERROR: attempt to start undefined timer')
     434             : 
     435             :    endif
     436             : 
     437             : !-----------------------------------------------------------------------
     438             : 
     439        6609 :  end subroutine ice_timer_start
     440             : 
     441             : !***********************************************************************
     442             : 
     443        6609 :  subroutine ice_timer_stop(timer_id, block_id)
     444             : 
     445             : !  This routine stops a given node timer if appropriate.  If block
     446             : !  information is available the appropriate block timer is also stopped.
     447             : 
     448             :    integer (int_kind), intent(in) :: &
     449             :       timer_id                   ! timer number
     450             : 
     451             :    integer (int_kind), intent(in), optional :: &
     452             :       block_id                 ! optional block id for this block
     453             :                                ! this must be the actual local address
     454             :                                ! of the block in the distribution
     455             :                                ! from which it is called
     456             :                                ! (if timer called outside of block
     457             :                                ! region, no block info required)
     458             : 
     459             : !-----------------------------------------------------------------------
     460             : !
     461             : !  local variables
     462             : !
     463             : !-----------------------------------------------------------------------
     464             : 
     465             :    real (dbl_kind) :: &
     466             :       cycles1, cycles2   ! temps to hold cycle info before correction
     467             : 
     468             :    integer (int_kind) :: &
     469             :       cycles                   ! count rate returned by sys_clock
     470             : 
     471             :    character(len=*), parameter :: subname = '(ice_timer_stop)'
     472             : 
     473             : !   if (my_task == master_task) write(nu_diag,*) subname,trim(all_timers(timer_id)%name)
     474             : 
     475             : !-----------------------------------------------------------------------
     476             : !
     477             : !  get end cycles
     478             : !
     479             : !-----------------------------------------------------------------------
     480             : 
     481        6609 :    call system_clock(count=cycles)
     482        6609 :    cycles2 = real(cycles,kind=dbl_kind)
     483             : 
     484             : !-----------------------------------------------------------------------
     485             : !
     486             : !  if timer is defined, stop it
     487             : !
     488             : !-----------------------------------------------------------------------
     489             : 
     490        6609 :    if (all_timers(timer_id)%in_use) then
     491             : 
     492             :       !***
     493             :       !*** if called from within a block loop, stop block timer
     494             :       !***
     495             : 
     496        6609 :       if (present(block_id)) then
     497             : 
     498         120 :          all_timers(timer_id)%block_started(block_id) = .false.
     499             : 
     500             :          !*** correct for cycle wraparound and accumulate time
     501             : 
     502         120 :          cycles1 = all_timers(timer_id)%block_cycles1(block_id)
     503         120 :          if (cycles2 >= cycles1) then
     504             :             all_timers(timer_id)%block_accum_time(block_id) = &
     505             :             all_timers(timer_id)%block_accum_time(block_id) + &   ! LCOV_EXCL_LINE
     506         120 :                clock_rate*(cycles2 - cycles1)
     507             :          else
     508             :             all_timers(timer_id)%block_accum_time(block_id) = &
     509             :             all_timers(timer_id)%block_accum_time(block_id) + &   ! LCOV_EXCL_LINE
     510           0 :                clock_rate*(cycles_max + cycles2 - cycles1)
     511             :          endif
     512             : 
     513             :          !*** stop node timer if number of requested stops
     514             :          !*** matches the number of starts (to avoid stopping
     515             :          !*** a node timer started by multiple threads)
     516             : 
     517         120 :          cycles1 = all_timers(timer_id)%node_cycles1
     518             : 
     519             :          !$OMP CRITICAL
     520             : 
     521             :          all_timers(timer_id)%num_stops = &
     522         120 :          all_timers(timer_id)%num_stops + 1
     523             : 
     524         120 :          if (all_timers(timer_id)%num_starts == &
     525             :              all_timers(timer_id)%num_stops) then
     526             : 
     527         120 :             all_timers(timer_id)%node_started = .false.
     528         120 :             if (cycles2 >= cycles1) then
     529             :                all_timers(timer_id)%node_accum_time = &
     530             :                all_timers(timer_id)%node_accum_time + &   ! LCOV_EXCL_LINE
     531         120 :                   clock_rate*(cycles2 - cycles1)
     532             :             else
     533             :                all_timers(timer_id)%node_accum_time = &
     534             :                all_timers(timer_id)%node_accum_time + &   ! LCOV_EXCL_LINE
     535           0 :                   clock_rate*(cycles_max + cycles2 - cycles1)
     536             :             endif
     537             : 
     538         120 :             all_timers(timer_id)%num_starts   = 0
     539         120 :             all_timers(timer_id)%num_stops    = 0
     540             : 
     541             :          endif
     542             : 
     543             :          !$OMP END CRITICAL
     544             : 
     545             :       !***
     546             :       !*** if called from outside a block loop, stop node timer
     547             :       !***
     548             : 
     549             :       else
     550             : 
     551             :          !*** correct for wraparound and accumulate time
     552             : 
     553        6489 :          all_timers(timer_id)%node_started = .false.
     554        6489 :          cycles1 = all_timers(timer_id)%node_cycles1
     555             : 
     556        6489 :          if (cycles2 >= cycles1) then
     557             :             all_timers(timer_id)%node_accum_time = &
     558             :             all_timers(timer_id)%node_accum_time + &   ! LCOV_EXCL_LINE
     559        6489 :                clock_rate*(cycles2 - cycles1)
     560             :          else
     561             :             all_timers(timer_id)%node_accum_time = &
     562             :             all_timers(timer_id)%node_accum_time + &   ! LCOV_EXCL_LINE
     563           0 :                clock_rate*(cycles_max + cycles2 - cycles1)
     564             :          endif
     565             : 
     566             :       endif
     567             :    else
     568           0 :       call abort_ice(subname//'ERROR: attempt to stop undefined timer')
     569             : 
     570             :    endif
     571             : 
     572             : !-----------------------------------------------------------------------
     573             : 
     574        6609 :  end subroutine ice_timer_stop
     575             : 
     576             : !***********************************************************************
     577             : 
     578          20 :  subroutine ice_timer_print(timer_id,stats)
     579             : 
     580             : !  Prints the accumulated time for a given timer and optional
     581             : !  statistics for that timer. It is assumed that this routine
     582             : !  is called outside of a block loop.
     583             : 
     584             :    integer (int_kind), intent(in) :: &
     585             :       timer_id                ! timer number
     586             : 
     587             :    logical (log_kind), intent(in), optional :: &
     588             :       stats                   ! if true, print statistics for node
     589             :                               !   and block times for this timer
     590             : 
     591             : !-----------------------------------------------------------------------
     592             : !
     593             : !  local variables
     594             : !
     595             : !-----------------------------------------------------------------------
     596             : 
     597             :    integer (int_kind) :: &
     598             :       n,icount           ! dummy loop index and counter
     599             : 
     600             :    logical (log_kind) :: &
     601             :       lrestart_timer     ! flag to restart timer if timer is running
     602             :                          ! when this routine is called
     603             : 
     604             :    real (dbl_kind) :: &
     605             :       bignum,           &! big number   ! LCOV_EXCL_LINE
     606             :       local_time,       &! temp space for holding local timer results   ! LCOV_EXCL_LINE
     607             :       min_time,         &! minimum accumulated time   ! LCOV_EXCL_LINE
     608             :       max_time,         &! maximum accumulated time   ! LCOV_EXCL_LINE
     609             :       mean_time          ! mean    accumulated time
     610             : 
     611             :    character (41), parameter :: &
     612             :       timer_format = "('Timer ',i3,': ',a9,f11.2,' seconds')"
     613             : 
     614             :    character (49), parameter :: &
     615             :       stats_fmt1 = "('  Timer stats (node): min = ',f11.2,' seconds')",&   ! LCOV_EXCL_LINE
     616             :       stats_fmt2 = "('                      max = ',f11.2,' seconds')",&   ! LCOV_EXCL_LINE
     617             :       stats_fmt3 = "('                      mean= ',f11.2,' seconds')",&   ! LCOV_EXCL_LINE
     618             :       stats_fmt4 = "('  Timer stats(block): min = ',f11.2,' seconds')"
     619             : 
     620             :    character(len=*), parameter :: subname = '(ice_timer_print)'
     621             : 
     622             : !-----------------------------------------------------------------------
     623             : !
     624             : !  if timer has been defined, check to see whether it is currently
     625             : !  running.  If it is, stop the timer and print the info.
     626             : !
     627             : !-----------------------------------------------------------------------
     628             : 
     629          20 :    call icepack_query_parameters(bignum_out=bignum)
     630          20 :    call icepack_warnings_flush(nu_diag)
     631          20 :    if (icepack_warnings_aborted()) call abort_ice(error_message=subname, &
     632           0 :        file=__FILE__, line=__LINE__)
     633             : 
     634          20 :    if (all_timers(timer_id)%in_use) then
     635          20 :       if (all_timers(timer_id)%node_started) then
     636           0 :         call ice_timer_stop(timer_id)
     637           0 :         lrestart_timer = .true.
     638             :       else
     639          20 :         lrestart_timer = .false.
     640             :       endif
     641             : 
     642             :       !*** Find max node time and print that time as default timer
     643             :       !*** result
     644             : 
     645          20 :       if (my_task < all_timers(timer_id)%num_nodes) then
     646          20 :          local_time = all_timers(timer_id)%node_accum_time
     647             :       else
     648           0 :          local_time = c0
     649             :       endif
     650          20 :       max_time = global_maxval(local_time,distrb_info)
     651             : 
     652          20 :       if (my_task == master_task) then
     653          20 :         write (nu_diag,timer_format) timer_id, &
     654          40 :               trim(all_timers(timer_id)%name),max_time
     655             :       endif
     656             : 
     657          20 :       if (present(stats)) then
     658          20 :       if (stats) then
     659             : 
     660             :          !*** compute and print statistics for node timer
     661             : 
     662           0 :          min_time = global_minval(local_time,distrb_info)
     663             :          mean_time = global_sum(local_time,distrb_info)/ &
     664           0 :                      real(all_timers(timer_id)%num_nodes,kind=dbl_kind)
     665           0 :          if (my_task == master_task) then
     666           0 :             write (nu_diag,stats_fmt1) min_time
     667           0 :             write (nu_diag,stats_fmt2) max_time
     668           0 :             write (nu_diag,stats_fmt3) mean_time
     669             :          endif
     670             : 
     671             :          !*** compute and print statistics for block timers
     672             :          !*** min block time
     673             : 
     674           0 :          local_time = bignum
     675           0 :          do n=1,all_timers(timer_id)%num_blocks
     676             :             local_time = min(local_time, &
     677           0 :                              all_timers(timer_id)%block_accum_time(n))
     678             :          end do
     679           0 :          min_time = global_minval(local_time,distrb_info)
     680           0 :          if (min_time == bignum) min_time = c0
     681             : 
     682             :          !*** max block time
     683             : 
     684           0 :          local_time = -bignum
     685           0 :          do n=1,all_timers(timer_id)%num_blocks
     686             :             local_time = max(local_time, &
     687           0 :                              all_timers(timer_id)%block_accum_time(n))
     688             :          end do
     689           0 :          max_time = global_maxval(local_time,distrb_info)
     690           0 :          if (max_time == -bignum) min_time = c0
     691             : 
     692             :          !*** mean block time
     693             : 
     694           0 :          local_time = c0
     695           0 :          do n=1,all_timers(timer_id)%num_blocks
     696             :             local_time = local_time + &
     697           0 :                          all_timers(timer_id)%block_accum_time(n)
     698             :          end do
     699             :          icount = global_sum(all_timers(timer_id)%num_blocks, &
     700           0 :                              distrb_info)
     701           0 :          if (icount > 0) mean_time=global_sum(local_time,distrb_info)&
     702           0 :                                    /real(icount,kind=dbl_kind)
     703             : 
     704           0 :          if (my_task == master_task) then
     705           0 :             write (nu_diag,stats_fmt4) min_time
     706           0 :             write (nu_diag,stats_fmt2) max_time
     707           0 :             write (nu_diag,stats_fmt3) mean_time
     708             :          endif
     709             : 
     710             :       endif
     711             :       endif
     712             : 
     713          20 :       if (lrestart_timer) call ice_timer_start(timer_id)
     714             :    else
     715           0 :       call abort_ice(subname//'ERROR: attempt to print undefined timer')
     716             : 
     717             :    endif
     718             : 
     719             : !-----------------------------------------------------------------------
     720             : 
     721          20 :  end subroutine ice_timer_print
     722             : 
     723             : !***********************************************************************
     724             : 
     725           1 :  subroutine ice_timer_print_all(stats)
     726             : 
     727             : !  Prints the accumulated time for a all timers and optional
     728             : !  statistics for that timer. It is assumed that this routine
     729             : !  is called outside of a block loop.
     730             : 
     731             :    logical (log_kind), intent(in), optional :: &
     732             :       stats                   ! if true, print statistics for node
     733             :                               !   and block times for this timer
     734             : 
     735             : !-----------------------------------------------------------------------
     736             : !
     737             : !  local variables
     738             : !
     739             : !-----------------------------------------------------------------------
     740             : 
     741             :    integer (int_kind) :: n ! dummy loop index
     742             : 
     743             :    character(len=*), parameter :: subname = '(ice_timer_print_all)'
     744             : 
     745             : !-----------------------------------------------------------------------
     746             : !
     747             : !  loop through timers anc call timer_print for each defined timer
     748             : !
     749             : !-----------------------------------------------------------------------
     750             : 
     751           1 :    if (my_task == master_task) then
     752           1 :       write(nu_diag,'(/,a19,/)') 'Timing information:'
     753             :    endif
     754             : 
     755          51 :    do n=1,max_timers
     756          51 :       if (all_timers(n)%in_use) then
     757          20 :          if (present(stats)) then
     758          20 :             call ice_timer_print(n,stats)
     759             :          else
     760           0 :             call ice_timer_print(n)
     761             :          endif
     762             :       endif
     763             :    end do
     764             : 
     765             : !-----------------------------------------------------------------------
     766             : 
     767           1 :  end subroutine ice_timer_print_all
     768             : 
     769             : !***********************************************************************
     770             : 
     771           0 :  subroutine ice_timer_check(timer_id,block_id)
     772             : 
     773             : !  This routine checks a given timer by stopping and restarting the
     774             : !  timer.  This is primarily used to periodically accumulate time in
     775             : !  the timer to prevent timer cycles from wrapping around max_cycles.
     776             : 
     777             :    integer (int_kind), intent(in) :: &
     778             :       timer_id                   ! timer number
     779             : 
     780             :    integer (int_kind), intent(in), optional :: &
     781             :       block_id                 ! optional block id for this block
     782             :                                ! this must be the actual local address
     783             :                                ! of the block in the distribution
     784             :                                ! from which it is called
     785             :                                ! (if timer called outside of block
     786             :                                ! region, no block info required)
     787             : 
     788             :    character(len=*), parameter :: subname = '(ice_timer_check)'
     789             : 
     790             : !-----------------------------------------------------------------------
     791             : !
     792             : !  stop and restart the requested timer
     793             : !
     794             : !-----------------------------------------------------------------------
     795             : 
     796           0 :    if (present(block_id)) then
     797           0 :       call ice_timer_stop (timer_id,block_id)
     798           0 :       call ice_timer_start(timer_id,block_id)
     799             :    else
     800           0 :       call ice_timer_stop (timer_id)
     801           0 :       call ice_timer_start(timer_id)
     802             :    endif
     803             : 
     804             : !-----------------------------------------------------------------------
     805             : 
     806           0 :  end subroutine ice_timer_check
     807             : 
     808             : !***********************************************************************
     809             : 
     810           0 :  end module ice_timers
     811             : 
     812             : !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Generated by: LCOV version 1.14-6-g40580cd