PHASTA/Creating Timers

From PHASTA Wiki
Jump to: navigation, search

This is a page to document how to create timers in PHASTA. Timers are ways of precisely timing how long a specific part of code takes to execute while having a very low overhead when doing so.

Also see PHASTA#Timings for information on reading the timers section of the PHASTA output log.

Note: This is based on the incompressible code.

Code Changes

There are several places where code needs to change (all paths relative to [phasta git repository]/phSolver/:

  • common/common.h
    • Place definitions of variables to be used for Fortran
  • common/common_c.h
    • Ditto, but for C/C++
  • common/new_interface.c
    • Where the timer information gets printed out to the log
  • incommpressible/itrdrv.f
    • Where the variables tracking the timers get reset
  • Whatever code you want to time will need to be modified

common/common.h

Simply need to add a r* and/or i* variable to the mpistats, where the r stands for a real number and the i is for an integer (taking advantage of Fortran's implicit variable typing).

The real numbers are used to track the actual time it takes to run a specific piece of code, while the integer values are used to track how many times a piece of code can be run.

common/common_c.h

Add the same variables you added to common/common.h to the mpistats struct. Note that capitalization doesn't matter in Fortran, but does in C/C++.

common/new_interface.c

Add a print statement to the print_mpi_stats function. You can simply copy/paste a similar set of lines from the file, but it should generally look like this:

igetMinMaxAvg(&mpistats.iISend,iStats,statRanks);                                                                                                           
if(workfc.myrank==workfc.master)                                                                                                                            
  printf("iISend : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",
          statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]);

where igetMinMaxAvg calculates the statistics for a given variable in the mpistats struct (&mpistats.iISend in this case) and puts the resulting information in iStats and statRanks. The proceeding printf statement then prints the contents of iStats and statRanks out to the log.

incompressible/itrdrv.f

Here, you need to add your timer variables to the initmpistat subroutine so that they can be reset at their appropriate times.

How to actually time the code?

Record number of times code reached (integer variable timer)

For the recording how many times something in the code happens, you simply increment your integer (i*) variable by one in the code where that happens.

Example:

if (boolean .eq. 1) then
    call randomSubRoutine(argument)
    irandomSubRoutine = irandomSubRoutine + 1
endif

Here, the irandomSubRoutine variable is assumed to have been placed at the appropriate files mentioned above

Time in seconds (real variable timer)

To record the actual wall time taken to do a task, you simply need to have a example variable record the time before a task and subtract that from the time after a task. You can then add this to the timer tracking variable. Recording the time is done through the TMRC function:

real :: rdelta

[...]

if (boolean .eq. 1) then
    rdelta = TMRC()
    call randomSubRoutine(argument)
    rrandomSubRoutine = rrandomSubRoutine + TMRC() - rdelta
endif