Difference between revisions of "PHASTA/Creating Timers"
(Start documentation of timers) |
|||
Line 3: | Line 3: | ||
Also see [[PHASTA#Timings]] for information on reading the timers section of the PHASTA output log. | 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 == | == Code Changes == | ||
Line 13: | Line 14: | ||
* <code>common/new_interface.c</code> | * <code>common/new_interface.c</code> | ||
** Where the timer information gets printed out to the log | ** Where the timer information gets printed out to the log | ||
− | * <code> | + | * <code>incommpressible/itrdrv.f</code> |
** Where the variables tracking the timers get reset | ** Where the variables tracking the timers get reset | ||
* Whatever code you want to time will need to be modified | * Whatever code you want to time will need to be modified | ||
Line 29: | Line 30: | ||
=== <code>common/new_interface.c</code> === | === <code>common/new_interface.c</code> === | ||
− | Add a print statement to the <code>print_mpi_stats</code> function. You can simply copy/paste | + | Add a print statement to the <code>print_mpi_stats</code> 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 <code>igetMinMaxAvg</code> calculates the statistics for a given variable in the <code>mpistats</code> struct (<code>&mpistats.iISend</code> in this case) and puts the resulting information in <code>iStats</code> and <code>statRanks</code>. | ||
+ | The proceeding <code>printf</code> statement then prints the contents of <code>iStats</code> and <code>statRanks</code> out to the log. | ||
+ | |||
+ | === <code>incompressible/itrdrv.f</code> === | ||
+ | |||
+ | Here, you need to add your timer variables to the <code>initmpistat</code> 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 (<code>i*</code>) variable by one in the code where that happens. | ||
+ | |||
+ | Example: | ||
+ | |||
+ | if (boolean .eq. 1) then | ||
+ | call randomSubRoutine(argument) | ||
+ | irandomSubRoutine = irandomSubRoutine + 1 | ||
+ | endif | ||
+ | |||
+ | Here, the <code>irandomSubRoutine</code> 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 <code>TMRC</code> function: | ||
+ | |||
+ | real :: rdelta | ||
+ | |||
+ | [...] | ||
+ | |||
+ | if (boolean .eq. 1) then | ||
+ | rdelta = TMRC() | ||
+ | call randomSubRoutine(argument) | ||
+ | rrandomSubRoutine = rrandomSubRoutine + TMRC() - rdelta | ||
+ | endif |
Revision as of 10:44, 3 September 2021
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.
Contents
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.
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