! This routine and three other routines, mpp_clock_id, mpp_clock_begin(id),
! and mpp_clock_end(id) may be used to time parallel code sections, and
! extract parallel statistics. Clocks are identified by names, which
! should be unique in the first 32 characters. The mpp_clock_id
! call initializes a clock of a given name and returns an integer
! id. This id can be used by subsequent
! mpp_clock_begin and mpp_clock_end calls set around a
! code section to be timed. Example:
!
! integer :: id
! id = mpp_clock_id( 'Atmosphere' )
! call mpp_clock_begin(id)
! call atmos_model()
! call mpp_clock_end()
!
! Two flags may be used to alter the behaviour of
! mpp_clock. If the flag MPP_CLOCK_SYNC is turned on
! by mpp_clock_id, the clock calls mpp_sync across all
! the PEs in the current pelist at the top of the timed code section,
! but allows each PE to complete the code section (and reach
! mpp_clock_end) at different times. This allows us to measure
! load imbalance for a given code section. Statistics are written to
! stdout by mpp_exit.
!
! The flag MPP_CLOCK_DETAILED may be turned on by
! mpp_clock_id to get detailed communication
! profiles. Communication events of the types SEND, RECV, BROADCAST,
! REDUCE and WAIT are separately measured for data volume
! and time. Statistics are written to stdout by
! mpp_exit, and individual PE info is also written to the file
! mpp_clock.out.#### where #### is the PE id given by
! mpp_pe.
!
! The flags MPP_CLOCK_SYNC and MPP_CLOCK_DETAILED are
! integer parameters available by use association, and may be summed to
! turn them both on.
!
! While the nesting of clocks is allowed, please note that turning on
! the non-optional flags on inner clocks has certain subtle issues.
! Turning on MPP_CLOCK_SYNC on an inner
! clock may distort outer clock measurements of load imbalance. Turning
! on MPP_CLOCK_DETAILED will stop detailed measurements on its
! outer clock, since only one detailed clock may be active at one time.
! Also, detailed clocks only time a certain number of events per clock
! (currently 40000) to conserve memory. If this array overflows, a
! warning message is printed, and subsequent events for this clock are
! not timed.
!
! Timings are done using the f90 standard
! SYSTEM_CLOCK intrinsic.
!
! The resolution of SYSTEM_CLOCK is often too coarse for use except
! across large swaths of code. On SGI systems this is transparently
! overloaded with a higher resolution clock made available in a
! non-portable fortran interface made available by
! nsclock.c. This approach will eventually be extended to other
! platforms.
!
! New behaviour added at the Havana release allows the user to embed
! profiling calls at varying levels of granularity all over the code,
! and for any particular run, set a threshold of granularity so that
! finer-grained clocks become dormant.
!
! The threshold granularity is held in the private module variable
! clock_grain. This value may be modified by the call
! mpp_clock_set_grain, and affect clocks initiated by
! subsequent calls to mpp_clock_id. The value of
! clock_grain is set to an arbitrarily large number initially.
!
! Clocks initialized by mpp_clock_id can set a new optional
! argument grain setting their granularity level. Clocks check
! this level against the current value of clock_grain, and are
! only triggered if they are at or below ("coarser than") the
! threshold. Finer-grained clocks are dormant for that run.
!
!The following grain levels are pre-defined:
!
!
!!predefined clock granularities, but you can use any integer
!!using CLOCK_LOOP and above may distort coarser-grain measurements
! integer, parameter, public :: CLOCK_COMPONENT=1 !component level, e.g model, exchange
! integer, parameter, public :: CLOCK_SUBCOMPONENT=11 !top level within a model component, e.g dynamics, physics
! integer, parameter, public :: CLOCK_MODULE=21 !module level, e.g main subroutine of a physics module
! integer, parameter, public :: CLOCK_ROUTINE=31 !level of individual subroutine or function
! integer, parameter, public :: CLOCK_LOOP=41 !loops or blocks within a routine
! integer, parameter, public :: CLOCK_INFRA=51 !infrastructure level, e.g halo update
!
!
! Note that subsequent changes to clock_grain do not
! change the status of already initiated clocks, and that if the
! optional grain argument is absent, the clock is always
! triggered. This guarantees backward compatibility.
!
!