timing module
=============

James Spencer, CUC3, University of Cambridge.

Routines for timing code blocks in fortran programs.

Usage
-----

An example program is provided (see example.f90).  Note that if the NAG fortran compilers are used
then the DNAGF95 macro must be given to the C pre-processor.  timing produces a summary of the most
expensive procedures at the end of a calculation.  For instance::

    ================================================================
    Timing report.

    Timing of most expensive procedures.

    Procedure                    Calls       CPU    system     total
    ----------------------------------------------------------------
    t1                               1      2.28      0.00      2.28
    t3                               6      0.11      0.00      0.11
    t2                               2      0.04      0.00      0.04
    ----------------------------------------------------------------
    Total                                   2.43      0.00      2.43

    Global CPU time          2.43
    Global system time       0.00
    Global total time        2.43
    ================================================================

timing must be initialised and terminated at the beginning and end of a calculation.
To use it:


#. Start the global timer at the start of the calculation::

      call init_timing()

#. For each procedure to be timed, declare a timer object and pass the
   procedure name::

      type(timer), save :: proc_timer
      proc_timer%timer_name='procedure name'

   And then time the procedure::

      call set_timer(proc_timer)
      [...]
      call halt_timer(proc_timer)

   This will time all the statements between the two timing calls.
   If a procedure is called between the timing calls which is itself 
   timed, then that is only included in one set of timings (in its own
   timer).
   The save is necessary for timing all calls to the same routine in one
   group.  The timer object is, however, very lightweight.
#. At the end of the calculation, stop the global timer and print out
   the timing report consisting of the routines which took the most time::

      call end_timing()
      call print_timing_report()

print_timing_report can take two optional arguments:

ntimer_objects
    The maximum number of timers to include in the output.  The default value is taken
    to be nPrintTimer (currently set to 10).
iunit 
     The file unit to which the timing  report is printed.  Default is 6 (stdout).

set_timer also has an optional argument and can be called as::

    call set_timer(proc_timer,obj_level)

obj_level
    If obj_level is greater than iGlobalTimerLevel (set to be 30 currently) then
    the procedure is not timed.  This allows control over which procedures are timed
    to be set via input options.  Timing a procedure involves two calls to find the
    time for each call to the procedure and so timing very low-level routines (i.e. 
    those called millions of times) should be avoided except during profiling
    and debugging work.

The time spent in a given timer can be obtained during a calculation using
the get_total_time function.  See this function for more details.

Licence
-------

Essentially you can do whatever you want with the code.
Formally it's subject to the MIT licence::

    Copyright (c) 2009 James Spencer.

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.
