CGpop mini-Application (2-sided MPI 1D data structure version) 0.1
timers.F90
Go to the documentation of this file.
00001 !==============================================================================
00002 ! Copyright (C) 2010, University Corporation for Atmospheric Research,
00003 !                     Colorado State University,
00004 !                     Los Alamos National Security, LLC,
00005 !                     United States Department of Energy
00006 !
00007 ! All rights reserved.  See ../COPYING for copyright details
00008 !==============================================================================
00009 
00010 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
00011 !>
00012 !! This module contains routine for supporting multiple CPU timers
00013 !! and accumulates time for each individual block and node (task).
00014 !<
00015  module timers
00016 
00017 ! !USES:
00018    use kinds_mod, only: i4, r8, char_len, log_kind
00019    use constants, only: c0, c1, blank_fmt, bignum, delim_fmt, char_blank
00020    use reductions, only: global_sum, global_minval, global_maxval
00021    use communicate, only: my_task,master_task
00022    use IOUnitsMod, only: stdout
00023    use exit_mod, only: sigAbort, exit_POP
00024 
00025    implicit none
00026    private
00027    save
00028 
00029 ! !PUBLIC MEMBER FUNCTIONS:
00030 
00031    public :: init_timers,     &
00032              get_timer,       &
00033              release_timer,   &
00034              timer_clear,     &
00035              timer_start,     &
00036              timer_stop,      &
00037              timer_print,     &
00038              timer_print_all, &
00039              timer_check
00040 
00041 !-----------------------------------------------------------------------
00042 !
00043 !  module variables
00044 !
00045 !-----------------------------------------------------------------------
00046 
00047    integer (i4), parameter :: 
00048       max_timers    = 100       ! max number of timers
00049 
00050    type timer_data
00051       character (char_len) :: 
00052          name                  ! timer name
00053 
00054       logical (log_kind) ::   
00055          in_use,              ! true if timer initialized
00056          node_started          ! true if any thread has started timer
00057 
00058       integer (i4) ::   
00059          num_blocks,          ! number of blocks using this timer
00060          num_nodes,           ! number of nodes  using this timer
00061          num_starts,          ! number of start requests
00062          num_stops,           ! number of stop requests
00063          node_cycles1,        ! cycle number at start for node timer
00064          node_cycles2          ! cycle number at stop  for node timer
00065 
00066       real (r8) ::            
00067          node_accum_time       ! accumulated time for node timer
00068 
00069       logical (log_kind), dimension(:), pointer :: 
00070          block_started         ! true if block timer started
00071 
00072       integer (i4), dimension(:), pointer :: 
00073          block_cycles1,        ! cycle number at start for block timers
00074          block_cycles2          ! cycle number at stop  for block timers
00075 
00076       real (r8), dimension(:), pointer :: 
00077          block_accum_time       ! accumulated time for block timers
00078 
00079    end type
00080 
00081    type (timer_data), dimension(max_timers) :: 
00082       all_timers               ! timer data for all timers
00083 
00084    integer (i4) ::       
00085       cycles_max               ! max clock cycles allowed by system
00086 
00087    real (r8) ::               
00088       clock_rate               ! clock rate in seconds for each cycle
00089 
00090 !***********************************************************************
00091 
00092  contains
00093 
00094 !***********************************************************************
00095 
00096 !>
00097 !! This routine initializes machine parameters and timer structures
00098 !! for computing cpu time from F90 intrinsic timer functions.
00099 !<
00100  subroutine init_timers
00101 
00102 !-----------------------------------------------------------------------
00103 !
00104 !  local variables
00105 !
00106 !-----------------------------------------------------------------------
00107 
00108    integer (i4) :: 
00109       n,                 ! dummy loop counters
00110       cycles              ! count rate return by sys_clock
00111 
00112 !-----------------------------------------------------------------------
00113 !
00114 !  Call F90 intrinsic system_clock to determine clock rate
00115 !  and maximum cycles.  If no clock available, print message.
00116 !
00117 !-----------------------------------------------------------------------
00118 
00119    call system_clock(count_rate=cycles, count_max=cycles_max)
00120 
00121    if (cycles /= 0) then
00122       clock_rate = c1/real(cycles,kind=r8)
00123    else
00124       clock_rate = c0
00125       write(stdout,delim_fmt)
00126       write(stdout,blank_fmt)
00127       write(stdout,'(a33)') '--- No system clock available ---'
00128       write(stdout,blank_fmt)
00129       write(stdout,delim_fmt)
00130    endif
00131 
00132 !-----------------------------------------------------------------------
00133 !
00134 !  initialize timer structures
00135 !
00136 !-----------------------------------------------------------------------
00137 
00138    do n=1,max_timers
00139       all_timers(n)%name = 'unknown_timer_name'
00140 
00141       all_timers(n)%in_use       = .false.
00142       all_timers(n)%node_started = .false.
00143 
00144       all_timers(n)%num_blocks   = 0
00145       all_timers(n)%num_nodes    = 0
00146       all_timers(n)%num_starts   = 0
00147       all_timers(n)%num_stops    = 0
00148       all_timers(n)%node_cycles1 = 0
00149       all_timers(n)%node_cycles2 = 0
00150 
00151       all_timers(n)%node_accum_time = c0
00152 
00153       nullify(all_timers(n)%block_started)
00154       nullify(all_timers(n)%block_cycles1)
00155       nullify(all_timers(n)%block_cycles2)
00156       nullify(all_timers(n)%block_accum_time)
00157    end do
00158 
00159 !-----------------------------------------------------------------------
00160 
00161    end subroutine init_timers
00162 
00163 !***********************************************************************
00164 
00165 !>
00166 !! This routine initializes a timer with a given name and returns a 
00167 !! timer id.
00168 !!
00169 !! @param timer_id      timer number assigned to this timer 
00170 !! @param name_choice   input name for this timer
00171 !! @param num_blocks    number of blocks using this timer (can be = 1 if timer
00172 !!                      called outside threaded region)
00173 !! @param num_nodes     number of nodes(tasks) using this timer
00174 !<
00175  subroutine get_timer(timer_id, name_choice, num_blocks, num_nodes)
00176 
00177    character (*), intent(in) :: 
00178       name_choice
00179 
00180    integer (i4), intent(in) :: 
00181       num_nodes,                
00182       num_blocks
00183 
00184 ! !OUTPUT PARAMETERS:
00185 
00186    integer (i4), intent(out) :: 
00187       timer_id
00188 
00189 !-----------------------------------------------------------------------
00190 !
00191 !  local variables
00192 !
00193 !-----------------------------------------------------------------------
00194 
00195    integer (i4) :: 
00196       n,                 ! dummy loop index
00197       srch_error          ! error flag for search
00198 
00199 !-----------------------------------------------------------------------
00200 !
00201 !  search for next free timer
00202 !
00203 !-----------------------------------------------------------------------
00204 
00205    srch_error = 1
00206 
00207    srch_loop: do n=1,max_timers
00208       if (.not. all_timers(n)%in_use) then
00209          srch_error = 0
00210          timer_id = n
00211 
00212          all_timers(n)%name       = char_blank
00213          all_timers(n)%name       = name_choice
00214          all_timers(n)%in_use     = .true.
00215          all_timers(n)%num_blocks = num_blocks
00216          all_timers(n)%num_nodes  = num_nodes 
00217 
00218          allocate(all_timers(n)%block_started   (num_blocks), &
00219                   all_timers(n)%block_cycles1   (num_blocks), &
00220                   all_timers(n)%block_cycles2   (num_blocks), &
00221                   all_timers(n)%block_accum_time(num_blocks))
00222 
00223          all_timers(n)%block_started    = .false.
00224          all_timers(n)%block_cycles1    = 0
00225          all_timers(n)%block_cycles2    = 0
00226          all_timers(n)%block_accum_time = c0
00227 
00228          exit srch_loop
00229       endif
00230    end do srch_loop
00231 
00232    if (srch_error /= 0) &
00233       call exit_POP(sigAbort, &
00234                     'get_timer: Exceeded maximum number of timers')
00235 
00236 !-----------------------------------------------------------------------
00237 
00238  end subroutine get_timer
00239 
00240 !>
00241 !! This routine frees up a timer which is no longer used.
00242 !! NOTE: This routine must be called from outside a threaded
00243 !! region.
00244 !!
00245 !! @param timer_id      timer number
00246 !<
00247  subroutine release_timer(timer_id)
00248 
00249 ! !INPUT PARAMETERS:
00250 
00251    integer (i4), intent(in) :: 
00252       timer_id
00253 
00254 !-----------------------------------------------------------------------
00255 !
00256 !  if the timer has been defined, mark as not in use and re-initialize
00257 !  values. otherwise exit with an error
00258 !
00259 !-----------------------------------------------------------------------
00260 
00261    if (all_timers(timer_id)%in_use) then
00262      
00263       all_timers(timer_id)%name = 'unknown_timer_name'
00264 
00265       all_timers(timer_id)%in_use       = .false.
00266       all_timers(timer_id)%node_started = .false.
00267 
00268       all_timers(timer_id)%num_blocks   = 0
00269       all_timers(timer_id)%num_nodes    = 0
00270       all_timers(timer_id)%num_starts   = 0
00271       all_timers(timer_id)%num_stops    = 0
00272       all_timers(timer_id)%node_cycles1 = 0
00273       all_timers(timer_id)%node_cycles2 = 0
00274 
00275       all_timers(timer_id)%node_accum_time = c0
00276 
00277       nullify(all_timers(timer_id)%block_started)
00278       nullify(all_timers(timer_id)%block_cycles1)
00279       nullify(all_timers(timer_id)%block_cycles2)
00280       nullify(all_timers(timer_id)%block_accum_time)
00281 
00282    else
00283       call exit_POP(sigAbort, &
00284                     'release_timer: attempt to reset undefined timer')
00285    endif
00286 
00287 !-----------------------------------------------------------------------
00288 
00289  end subroutine release_timer
00290 
00291 !***********************************************************************
00292 !>
00293 !! This routine resets the time for a timer which has already been
00294 !! defined.  NOTE: This routine must be called from outside a threaded
00295 !! region to ensure correct reset of block timers.
00296 !!
00297 !! @param timer_id  timer number
00298 !<
00299  subroutine timer_clear(timer_id)
00300 
00301 ! !INPUT PARAMETERS:
00302 
00303    integer (i4), intent(in) :: 
00304       timer_id
00305 
00306 !-----------------------------------------------------------------------
00307 !
00308 !  if the timer has been defined, reset all times to 0
00309 !  otherwise exit with an error
00310 !
00311 !-----------------------------------------------------------------------
00312 
00313    if (all_timers(timer_id)%in_use) then
00314       all_timers(timer_id)%node_started  = .false.
00315       all_timers(timer_id)%num_starts    = 0
00316       all_timers(timer_id)%num_stops     = 0
00317       all_timers(timer_id)%node_cycles1  = 0
00318       all_timers(timer_id)%node_cycles2  = 0
00319 
00320       all_timers(timer_id)%node_accum_time = c0
00321 
00322       all_timers(timer_id)%block_started(:)    = .false.
00323       all_timers(timer_id)%block_cycles1(:)    = 0
00324       all_timers(timer_id)%block_cycles2(:)    = 0
00325       all_timers(timer_id)%block_accum_time(:) = c0
00326    else
00327       call exit_POP(sigAbort, &
00328                     'timer_clear: attempt to reset undefined timer')
00329    endif
00330 
00331 !-----------------------------------------------------------------------
00332 
00333  end subroutine timer_clear
00334 
00335 !***********************************************************************
00336 !>
00337 !! This routine starts a given node timer if it has not already
00338 !! been started by another thread.  If block information is available,
00339 !! the appropriate block timer is also started.
00340 !!
00341 !! @param timer_id    timer number
00342 !! @param block_id    optional block id for this block this must be the actual
00343 !!                    local address of the block in the distribution from which 
00344 !!                    it is called (if timer called outside of block region, no 
00345 !!                    block info required)
00346 !<
00347  subroutine timer_start(timer_id, block_id)
00348 
00349 ! !INPUT PARAMETERS:
00350 
00351    integer (i4), intent(in) :: 
00352       timer_id
00353 
00354    integer (i4), intent(in), optional :: 
00355       block_id
00356 
00357 !-----------------------------------------------------------------------
00358 !
00359 !  if timer is defined, start it up
00360 !
00361 !-----------------------------------------------------------------------
00362 
00363    if (all_timers(timer_id)%in_use) then
00364 
00365       !***
00366       !*** if called from within a block loop, start block timers
00367       !***
00368 
00369       if (present(block_id)) then
00370 
00371          !*** if block timer already started, stop it first
00372 
00373          if (all_timers(timer_id)%block_started(block_id)) &
00374             call timer_stop(timer_id, block_id)
00375 
00376          !*** start block timer
00377 
00378          all_timers(timer_id)%block_started(block_id) = .true.
00379 
00380          call system_clock(count= &
00381                    all_timers(timer_id)%block_cycles1(block_id))
00382 
00383          !*** start node timer if not already started by
00384          !*** another thread.  if already started, keep track
00385          !*** of number of start requests in order to match
00386          !*** start and stop requests
00387  
00388          !$OMP CRITICAL
00389 
00390          if (.not. all_timers(timer_id)%node_started) then
00391             all_timers(timer_id)%node_started = .true.
00392             all_timers(timer_id)%num_starts   = 1
00393             all_timers(timer_id)%num_stops    = 0
00394 
00395             call system_clock(count= &
00396                    all_timers(timer_id)%node_cycles1)
00397          else
00398             all_timers(timer_id)%num_starts = &
00399             all_timers(timer_id)%num_starts + 1
00400          endif
00401 
00402          !$OMP END CRITICAL
00403 
00404       !***
00405       !*** if called from outside a block loop, start node timer
00406       !***
00407 
00408       else
00409 
00410          !*** stop timer if already started
00411          if (all_timers(timer_id)%node_started) call timer_stop(timer_id)
00412 
00413          !*** start node timer
00414 
00415          all_timers(timer_id)%node_started = .true.
00416          call system_clock(count=all_timers(timer_id)%node_cycles1)
00417 
00418       endif
00419    else
00420       call exit_POP(sigAbort, &
00421                     'timer_start: attempt to start undefined timer')
00422    endif
00423 
00424 !-----------------------------------------------------------------------
00425  end subroutine timer_start
00426  
00427 !***********************************************************************
00428 
00429 !>
00430 !! This routine stops a given node timer if appropriate.  If block 
00431 !! information is available the appropriate block timer is also stopped.
00432 !!
00433 !! @param timer_id    timer number
00434 !! @param block_id    optional block id for this block this must be the actual
00435 !!                    local address of the block in the distribution from which 
00436 !!                    it is called (if timer called outside of block region, no 
00437 !!                    block info required)
00438 !<
00439  subroutine timer_stop(timer_id, block_id)
00440 
00441 ! !INPUT PARAMETERS:
00442 
00443    integer (i4), intent(in) :: 
00444       timer_id
00445 
00446    integer (i4), intent(in), optional :: 
00447       block_id
00448 
00449 !-----------------------------------------------------------------------
00450 !
00451 !  local variables
00452 !
00453 !-----------------------------------------------------------------------
00454 
00455    integer (i4) :: 
00456       cycles1, cycles2   ! temps to hold cycle info before correction
00457 
00458 !-----------------------------------------------------------------------
00459 !
00460 !  get end cycles
00461 !
00462 !-----------------------------------------------------------------------
00463 
00464    call system_clock(count=cycles2)
00465 
00466 !-----------------------------------------------------------------------
00467 !
00468 !  if timer is defined, stop it
00469 !
00470 !-----------------------------------------------------------------------
00471 
00472    if (all_timers(timer_id)%in_use) then
00473 
00474       !***
00475       !*** if called from within a block loop, stop block timer
00476       !***
00477 
00478       if (present(block_id)) then
00479 
00480          all_timers(timer_id)%block_started(block_id) = .false.
00481 
00482          !*** correct for cycle wraparound and accumulate time
00483 
00484          cycles1 = all_timers(timer_id)%block_cycles1(block_id)
00485          if (cycles2 >= cycles1) then
00486             all_timers(timer_id)%block_accum_time(block_id) = &
00487             all_timers(timer_id)%block_accum_time(block_id) + &
00488                clock_rate*(cycles2 - cycles1)
00489          else
00490             all_timers(timer_id)%block_accum_time(block_id) = &
00491             all_timers(timer_id)%block_accum_time(block_id) + &
00492                clock_rate*(cycles_max + cycles2 - cycles1)
00493          endif
00494 
00495          !*** stop node timer if number of requested stops
00496          !*** matches the number of starts (to avoid stopping
00497          !*** a node timer started by multiple threads)
00498  
00499          cycles1 = all_timers(timer_id)%node_cycles1
00500 
00501          !$OMP CRITICAL
00502 
00503          all_timers(timer_id)%num_stops = &
00504          all_timers(timer_id)%num_stops + 1
00505 
00506          if (all_timers(timer_id)%num_starts == &
00507              all_timers(timer_id)%num_stops) then
00508 
00509             all_timers(timer_id)%node_started = .false.
00510             if (cycles2 >= cycles1) then
00511                all_timers(timer_id)%node_accum_time = &
00512                all_timers(timer_id)%node_accum_time + &
00513                   clock_rate*(cycles2 - cycles1)
00514             else
00515                all_timers(timer_id)%node_accum_time = &
00516                all_timers(timer_id)%node_accum_time + &
00517                   clock_rate*(cycles_max + cycles2 - cycles1)
00518             endif
00519 
00520             all_timers(timer_id)%num_starts   = 0
00521             all_timers(timer_id)%num_stops    = 0
00522 
00523          endif
00524 
00525          !$OMP END CRITICAL
00526 
00527       !***
00528       !*** if called from outside a block loop, stop node timer
00529       !***
00530 
00531       else
00532 
00533          !*** correct for wraparound and accumulate time
00534 
00535          all_timers(timer_id)%node_started = .false.
00536          cycles1 = all_timers(timer_id)%node_cycles1
00537 
00538          if (cycles2 >= cycles1) then
00539             all_timers(timer_id)%node_accum_time = &
00540             all_timers(timer_id)%node_accum_time + &
00541                clock_rate*(cycles2 - cycles1)
00542          else
00543             all_timers(timer_id)%node_accum_time = &
00544             all_timers(timer_id)%node_accum_time + &
00545                clock_rate*(cycles_max + cycles2 - cycles1)
00546          endif
00547 
00548       endif
00549    else
00550       call exit_POP(sigAbort, &
00551                     'timer_start: attempt to start undefined timer')
00552    endif
00553 
00554 !-----------------------------------------------------------------------
00555 
00556  end subroutine timer_stop
00557  
00558 !***********************************************************************
00559 
00560 !>
00561 !! Prints the accumulated time for a given timer and optional
00562 !! statistics for that timer. It is assumed that this routine
00563 !! is called outside of a block loop.
00564 !!
00565 !! @param timer_id    timer number
00566 !! @param stats       if true, print statistics for node and block times for
00567 !!                    this timer
00568 !<
00569  subroutine timer_print(timer_id,stats)
00570 
00571 ! !INPUT PARAMETERS:
00572 
00573    integer (i4), intent(in) :: 
00574       timer_id
00575 
00576    logical (log_kind), intent(in), optional :: 
00577       stats
00578     
00579 !-----------------------------------------------------------------------
00580 !
00581 !  local variables
00582 !
00583 !-----------------------------------------------------------------------
00584 
00585    integer (i4) :: 
00586       n,icount           ! dummy loop index and counter
00587 
00588    logical (log_kind) :: 
00589       lrestart_timer     ! flag to restart timer if timer is running
00590                          ! when this routine is called
00591 
00592    real (r8) :: 
00593       local_time,       ! temp space for holding local timer results
00594       min_time,         ! minimum accumulated time
00595       max_time,         ! maximum accumulated time
00596       mean_time          ! mean    accumulated time
00597 
00598    character (36), parameter :: 
00599       timer_format = "('Timer: ',a,' =:',f11.2,' seconds')"
00600 
00601    character (49), parameter :: 
00602       stats_fmt1 = "('  Timer stats (node): min = ',f11.2,' seconds')",
00603       stats_fmt2 = "('                      max = ',f11.2,' seconds')",
00604       stats_fmt3 = "('                      mean= ',f11.2,' seconds')",
00605       stats_fmt4 = "('  Timer stats(block): min = ',f11.2,' seconds')"
00606 
00607 !-----------------------------------------------------------------------
00608 !
00609 !  if timer has been defined, check to see whether it is currently
00610 !  running.  If it is, stop the timer and print the info.
00611 !
00612 !-----------------------------------------------------------------------
00613 
00614    if (all_timers(timer_id)%in_use) then
00615       if (all_timers(timer_id)%node_started) then
00616         call timer_stop(timer_id)
00617         lrestart_timer = .true.
00618       else
00619         lrestart_timer = .false.
00620       endif
00621 
00622       !*** Find max node time and print that time as default timer
00623       !*** result
00624 
00625       if (my_task < all_timers(timer_id)%num_nodes) then
00626          local_time = all_timers(timer_id)%node_accum_time
00627       else
00628          local_time = c0
00629       endif
00630       max_time = global_maxval(local_time)
00631       
00632       if (my_task == master_task) then
00633         write (stdout,timer_format) trim(all_timers(timer_id)%name),max_time
00634       endif
00635 
00636       if (present(stats)) then
00637       if (stats) then
00638 
00639          !*** compute and print statistics for node timer
00640 
00641          min_time = global_minval(local_time)
00642          mean_time = global_sum(local_time)/ &
00643                      real(all_timers(timer_id)%num_nodes)
00644          if (my_task == master_task) then
00645             write (stdout,stats_fmt1) min_time
00646             write (stdout,stats_fmt2) max_time
00647             write (stdout,stats_fmt3) mean_time
00648          endif
00649 
00650          !*** compute and print statistics for block timers
00651          !*** min block time
00652 
00653          local_time = bignum
00654          do n=1,all_timers(timer_id)%num_blocks
00655             local_time = min(local_time, &
00656                              all_timers(timer_id)%block_accum_time(n))
00657          end do
00658          min_time = global_minval(local_time)
00659          if (min_time == bignum) min_time = c0
00660 
00661          !*** max block time
00662 
00663          local_time = -bignum
00664          do n=1,all_timers(timer_id)%num_blocks
00665             local_time = max(local_time, &
00666                              all_timers(timer_id)%block_accum_time(n))
00667          end do
00668          max_time = global_maxval(local_time)
00669          if (max_time == -bignum) min_time = c0
00670 
00671          !*** mean block time
00672 
00673          local_time = c0
00674          do n=1,all_timers(timer_id)%num_blocks
00675             local_time = local_time + &
00676                          all_timers(timer_id)%block_accum_time(n)
00677          end do
00678          icount = global_sum(all_timers(timer_id)%num_blocks)
00679          if (icount > 0) mean_time=global_sum(local_time)&
00680                                    /real(icount)
00681 
00682          if (my_task == master_task) then
00683             write (stdout,stats_fmt4) min_time
00684             write (stdout,stats_fmt2) max_time
00685             write (stdout,stats_fmt3) mean_time
00686          endif
00687 
00688       endif
00689       endif
00690 
00691       if (lrestart_timer) call timer_start(timer_id)
00692    else
00693       call exit_POP(sigAbort, &
00694                     'timer_print: attempt to print undefined timer')
00695    endif
00696 
00697 !-----------------------------------------------------------------------
00698 
00699  end subroutine timer_print
00700 
00701 !***********************************************************************
00702 
00703 !>
00704 !! Prints the accumulated time for a all timers and optional
00705 !! statistics for that timer. It is assumed that this routine
00706 !! is called outside of a block loop.
00707 !!
00708 !! @param stats       if true, print statistics for node and block times for
00709 !!                    this timer
00710 !<
00711  subroutine timer_print_all(stats)
00712 
00713 ! !INPUT PARAMETERS:
00714 
00715    logical (log_kind), intent(in), optional :: 
00716       stats
00717 
00718 !-----------------------------------------------------------------------
00719 !
00720 !  local variables
00721 !
00722 !-----------------------------------------------------------------------
00723 
00724    integer (i4) :: n ! dummy loop index
00725 
00726 !-----------------------------------------------------------------------
00727 !
00728 !  loop through timers anc call timer_print for each defined timer
00729 !
00730 !-----------------------------------------------------------------------
00731 
00732    if (my_task == master_task) then
00733       write(stdout,blank_fmt)
00734       write(stdout,'(a19)') 'Timing information:'
00735       write(stdout,blank_fmt)
00736    endif
00737 
00738    do n=1,max_timers
00739       if (all_timers(n)%in_use) then
00740          if (present(stats)) then
00741             call timer_print(n,stats)
00742          else
00743             call timer_print(n)
00744          endif
00745       endif
00746    end do
00747 
00748 !-----------------------------------------------------------------------
00749 
00750  end subroutine timer_print_all
00751 
00752 !***********************************************************************
00753 
00754 !>
00755 !! This routine checks a given timer by stopping and restarting the
00756 !! timer.  This is primarily used to periodically accumulate time in 
00757 !! the timer to prevent timer cycles from wrapping around max_cycles.
00758 !!
00759 !! @param timer_id      timer number
00760 !! @param block_id      optional block id for this block this must be the
00761 !!                      actual local address of the block in the distribution
00762 !!                      from which it is called (if timer called outside of
00763 !!                      block region, no block info required)
00764 !<
00765  subroutine timer_check(timer_id,block_id)
00766 
00767 ! !INPUT PARAMETERS:
00768 
00769    integer (i4), intent(in) :: 
00770       timer_id
00771 
00772    integer (i4), intent(in), optional :: 
00773       block_id
00774     
00775 !-----------------------------------------------------------------------
00776 !
00777 !  stop and restart the requested timer
00778 !
00779 !-----------------------------------------------------------------------
00780 
00781    if (present(block_id)) then
00782       call timer_stop (timer_id,block_id)
00783       call timer_start(timer_id,block_id)
00784    else
00785       call timer_stop (timer_id)
00786       call timer_start(timer_id)
00787    endif
00788 
00789 !-----------------------------------------------------------------------
00790 
00791  end subroutine timer_check
00792 
00793 !***********************************************************************
00794 
00795  end module timers
00796 
00797 !|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 All Classes Namespaces Files Functions Variables