/*
DFT++ is a density functional package developed by the research group
of Professor Tomas Arias
Copyright 1996-2003 Sohrab Ismail-Beigi
This file is part of DFT++.
DFT++ is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DFT++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DFT++; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Please see the file CREDITS for a list of authors.
For academic users, we request that publications using results obtained with
this software reference
"New algebraic formulation of density functional calculation," by Sohrab Ismail-Beigi
and T.A. Arias, Computer Physics Communications 128:1-2, 1-45 (June 2000).
and, if using the wavelet basis, further reference
"Multiresolution analysis of electronic structure: semicardinal and wavelet bases,"
T.A. Arias, Reviews of Modern Physics 71:1, 267-311 (January 1999).
and
"Robust ab initio calculation of condensed matter: transparent convergence through
semicardinal multiresolution analysis,'' I.P. Daykov, T.A. Arias, and
Torkel D. Engeness, Physical Review Letters, 90:21, 216402 (May 2003).
For your convenience, preprints of the above articles may be obtained from
http://arXiv.org/abs/cond-mat/9909130, 9805262, and 0204411, respectively.
*/
/************************************************************************/
/* */
/* Tairan Wang Nov. 6, 1997 */
/* */
/* A set of timer access routines for MPI performance profiling */
/* */
/************************************************************************/
/* $Id: timer.cpp,v 1.14.2.4 2003/05/29 18:54:35 ivan Exp $ */
#include "header.h"
#include "parallel.h"
#ifdef DFT_PROFILING
#define ON 1
#define OFF 0
#define NUM_TIMERS 64
#define NUM_COUNTERS 64
int timerState[NUM_TIMERS];
char timerTitle[NUM_TIMERS][DFT_MSG_LEN];
double lastStart[NUM_TIMERS],accTime[NUM_TIMERS];
int num_timers;
double counterState[NUM_COUNTERS];
char counterTitle[NUM_TIMERS][DFT_MSG_LEN];
int num_counters;
//////////////////////////////////////////////////////////////////
/* To turn on a timer. Returns the prior state of the timer. */
int
timerOn(int timer)
{
int priorState = timerState[timer];
if (priorState == OFF)
{
timerState[timer] = ON;
lastStart[timer] = System::get_time();
}
// SIB 27/1/00: commented out for now... this is NOT thread safe
// i.e. when running threads, many threads
// call the same timer at the same time, and as
// variables are global, we get WARNINGs galore
// else
// {
// dft_log("\nWARNING: timer %d already on at:%f",
// timer,lastStart[timer]);
// }
return(priorState);
}
/* To turn a timer off. Again, returns the prior state. */
int
timerOff(int timer)
{
int priorState = timerState[timer];
if (priorState == ON)
{
timerState[timer] = OFF;
accTime[timer] += System::get_time() - lastStart[timer];
}
return(priorState);
}
/* To set the timer to a given state. Returns prior state. */
int
timerSetState(int timer, int state)
{
if (state == ON)
return timerOn(timer);
else
return timerOff(timer);
}
/* To initialize all timers. */
void
timerInitAll(void)
{
num_timers = 0;
for (int i = 0; i < NUM_TIMERS; i++)
timerInit(i);
}
/* To initialize a timer. */
void
timerInit(int timer, char* title)
{
timerState[timer] = OFF;
accTime[timer] = 0;
strcpy(timerTitle[timer], title);
if ((timer+1) > num_timers)
num_timers = timer+1;
}
void
timerInit(int timer)
{
timerState[timer] = OFF;
accTime[timer] = 0;
}
/* To reset a timer, possibly running. */
int
timerReset(int timer)
{
int priorState = timerOff(timer);
timerInit(timer);
timerSetState(timer,priorState);
return(priorState);
}
/* To read a timer, regardless of state. */
double
timerRead(int timer)
{
double timeTemp;
timeTemp = accTime[timer];
if (timerState[timer] == ON)
timeTemp += System::get_time() - lastStart[timer];
return(timeTemp);
}
/* To get the title of a timer */
char *
timerGetTitle(int timer)
{
return (timerTitle[timer]);
}
/* To get the number of initialized timers */
int
timerGetTotal(void)
{
return num_timers;
}
/*
* Convenience routines to turn on all the timers
*/
int
timerActivateAll(void)
{
timerInitAll();
timerInit(0, "Initializations");
timerInit(1, "Total computation");
timerInit(2, "Minimization routines");
timerInit(3, "Y1^Y2");
timerInit(4, "Y*M");
timerInit(5, "Column bundle transpose");
timerInit(6, "diagouterI");
timerInit(7, "diaginner");
timerInit(8, "memory allocation");
timerInit(9, "do_linmin");
timerInit(10, "calc_elecgrad_Hsub");
timerInit(11, "calc_UVCn_d_elec_dependent_e");
timerInit(12, "Y1^Y2 MPI_Allreduce");
timerInit(13, "Other MPI_Allreduce");
timerInit(14, "\tcalc_U");
timerInit(15, "\tcalc_C");
timerInit(16, "\tcalc_n");
timerInit(17, "\tsolve_poisson");
timerInit(18, "\tcalc_KE");
timerInit(19, "\tcalc_Eloc");
timerInit(20, "\tcalc_Enl");
timerInit(21, "\tcalc_EH");
timerInit(22, "\tcalc_Exc");
timerInit(23, "\tcalc_Ecore");
timerInit(24, "\tcalc_Eewald");
timerInit(25, "\tcalc_Vscloc");
timerInit(26, "\tapply_Hsp");
timerInit(27, "\tdiagonalize_herm");
timerInit(28, "\tmatrix*matrix");
timerInit(29, "\tO");
timerInit(30, "\tPbar");
timerInit(31, "\tL");
timerInit(32, "\tinvL");
timerInit(33, "\tprecond");
timerInit(34, "\tI");
timerInit(35, "\tJ");
timerInit(36, "\tIdag");
timerInit(37, "\tJdag");
timerInit(38,"diaginner MPI_Allreduce");
timerInit(39,"diagouterI MPI_Allreduce");
timerInit(40,"FFT3D");
timerInit(41,"calc_V");
timerInit(42,"apply_Hsp_loc");
timerInit(43,"apply_Hsp_nloc");
timerInit(50,"operator \"=\"");
timerInit(51,"operator \"+\"");
timerInit(52,"operator \"-\"");
// For wavelet profiling, it's important to count the time we spend doing
// data conversion.
#ifdef WAVELETS
timerInit(60,"GetRe, PutRe, GetIm, PutIm");
#endif // WAVELETS
return 43;
}
/*
* Report the timer content
*/
void
timerReport(int iter)
{
int itimer, n_timers = timerGetTotal();
if (n_timers > 0)
{
dft_log("\nTiming reports at iteration %d:\n",iter);
for (itimer = 0; itimer < n_timers; itimer++)
dft_log("\t%4d %s :\t\t%f sec\n",
itimer,
timerGetTitle(itimer),
timerRead(itimer));
dft_log("\n");
dft_log_flush();
}
}
/*
* Report the timer content and counter content:
*/
void
timer_counter_Report(int iter)
{
timerReport(iter);
counterReport(iter);
}
/////////////////////////////////////////////////////////////////
void
counterReport(int iter)
{
int n_counters = counterGetTotal();
if (n_counters > 0)
{
dft_log("\nCounter reports at iteration %d:\n",iter);
for (int icounter = 0; icounter < n_counters; icounter++)
if (counterRead(icounter)>1.0e6)
dft_log("\t%4d %s :\t\t%e\n",
icounter,
counterGetTitle(icounter),
counterRead(icounter));
else
dft_log("\t%4d %s :\t\t%f\n",
icounter,
counterGetTitle(icounter),
counterRead(icounter));
dft_log("\n");
dft_log_flush();
}
}
int
counterActivateAll(void)
{
counterInitAll();
counterInit(0, "Y1^Y2 flop count");
counterInit(1, "Y1^Y2 total count");
counterInit(2, "Y1^Y2 distributed count");
counterInit(3, "Y1^Y2 MPI_Allreduce bytes");
counterInit(4, "Y*M flop count");
counterInit(5, "Y*M total count");
counterInit(6, "Y*M distributed count");
counterInit(7, "Tranpose count");
counterInit(8, "Transpose bytes");
counterInit(9, "matrix*matrix flop count");
counterInit(10, "matrix*matrix count");
counterInit(11, "diagonalization count");
counterInit(12, "I count");
counterInit(13, "Idag count");
counterInit(14, "J count");
counterInit(15, "Jdag count");
counterInit(16, "FFT3D count");
counterInit(17, "diaginner MPI_Allreduce count");
counterInit(18, "diaginner MPI_Allreduce bytes");
counterInit(19, "diagouterI MPI_Allreduce count");
counterInit(20, "diagouterI MPI_Allreduce bytes");
counterInit(21, "other MPI_Allreduce count");
counterInit(22, "other MPI_Allreduce bytes");
// My additions to the operator counts.
counterInit(23, "L count");
counterInit(24, "O count");
#ifdef WAVELETS
counterInit(25, "Get/Put count");
#endif // WAVELETS
return 24;
}
void
counterInitAll(void)
{
num_counters = 0;
for (int i=0; i < NUM_COUNTERS; i++)
counterState[i] = 0.0;
}
void
counterInit(int counter, char* title)
{
counterState[counter] = 0.0;
strcpy(counterTitle[counter], title);
if ((counter+1) > num_counters) {
num_counters = counter + 1;
}
}
void
counterIncr(int counter)
{
counterState[counter] += 1.0;
}
void
counterIncr(int counter, double amount)
{
counterState[counter] += amount;
}
double
counterRead(int counter)
{
return counterState[counter];
}
char *
counterGetTitle(int counter)
{
return (counterTitle[counter]);
}
int
counterGetTotal(void)
{
return num_counters;
}
#endif // DFT_PROFILING
syntax highlighted by Code2HTML, v. 0.9.1