OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
IpplTimings.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Utility/IpplTimings.h"
28 #include "Utility/Inform.h"
29 #include "Utility/IpplInfo.h"
30 #include "Message/GlobalComm.h"
31 #include "PETE/IpplExpressions.h"
32 
33 #include <boost/algorithm/string/predicate.hpp>
34 
35 #include <fstream>
36 #include <iostream>
37 #include <algorithm>
38 // static data members of IpplTimings class
39 
41 std::stack<Timing*> IpplTimings::stashedInstance;
42 
44 // default constructor
46  TimerList(),
47  TimerMap()
48 { }
49 
50 
52 // destructor
54  for (TimerMap_t::iterator it = TimerMap.begin(); it != TimerMap.end(); ++ it) {
55  it->second = 0;
56  }
57  TimerMap.clear();
58 
59  TimerList.clear();
60 }
61 
62 
64 // create a timer, or get one that already exists
66  std::string s(nm);
67  TimerInfo *tptr = 0;
68  TimerMap_t::iterator loc = TimerMap.find(s);
69  if (loc == TimerMap.end()) {
70  tptr = new TimerInfo;
71  tptr->indx = TimerList.size();
72  tptr->name = s;
73  TimerMap.insert(TimerMap_t::value_type(s,tptr));
74  TimerList.push_back(my_auto_ptr<TimerInfo>(tptr));
75  } else {
76  tptr = (*loc).second;
77  }
78  return tptr->indx;
79 }
80 
81 
83 // start a timer
85  if (t >= TimerList.size())
86  return;
87  TimerList[t]->start();
88 }
89 
90 
92 // stop a timer, and accumulate it's values
94  if (t >= TimerList.size())
95  return;
96  TimerList[t]->stop();
97 }
98 
99 
101 // clear a timer, by turning it off and throwing away its time
103  if (t >= TimerList.size())
104  return;
105  TimerList[t]->clear();
106 }
107 
108 #ifdef IPPL_XT3
109 // print out the timing results
111 void Timing::print() {
112  int i,j;
113  if (TimerList.size() < 1)
114  return;
115 
116  // report the average time for each timer
117  Inform msg("Timings");
118  msg << level1 << "-----------------------------------------------------------------\n";
119  msg << " Timing (dclock) results for " << Ippl::getNodes() << " nodes:" << "\n";
120  msg << "-----------------------------------------------------------------";
121  msg << "\n";
122  for (i=0; i<1; ++i){
123  TimerInfo *tptr = TimerList[i].get();
124  double walltotal = 0.0;
125  reduce(tptr->wallTime, walltotal, OpMaxAssign());
126  msg << tptr->name.c_str() << " ";
127  for (j=strlen(tptr->name.c_str()); j < 10; ++j)
128  msg << ".";
129  msg << " Wall tot = ";
130  msg.width(10);
131  msg << walltotal;
132  msg << "\n\n";
133  }
134 
135  for (i=1; i < TimerList.size(); ++i) {
136  TimerInfo *tptr = TimerList[i].get();
137  double wallmax = 0.0, wallmin = 0.0;
138  double wallavg = 0.0 ;
139  reduce(tptr->wallTime, wallmax, OpMaxAssign());
140  reduce(tptr->wallTime, wallmin, OpMinAssign());
141  reduce(tptr->wallTime, wallavg, OpAddAssign());
142  msg << tptr->name.c_str() << " ";
143  for (j=strlen(tptr->name.c_str()); j < 10; ++j)
144  msg << ".";
145  msg << " Wall max = ";
146  msg.width(10);
147  msg << wallmax << "\n";
148  for (j = 0; j < 21; ++j)
149  msg << " ";
150  msg << " Wall avg = ";
151  msg.width(10);
152  msg << wallavg / Ippl::getNodes() << "\n";
153  for (j = 0; j < 21; ++j)
154  msg << " ";
155  msg << " Wall min = ";
156  msg.width(10);
157  msg << wallmin << "\n\n";
158  }
159  msg << "-----------------------------------------------------------------";
160  msg << endl;
161 }
162 
163 #else
164 
166 // print out the timing results
168  if (TimerList.size() < 1)
169  return;
170 
171  // report the average time for each timer
172  Inform msg("Timings");
173  msg << level1
174  << "-----------------------------------------------------------------";
175  msg << "\n";
176  msg << " Timing results for " << Ippl::getNodes() << " nodes:" << "\n";
177  msg << "-----------------------------------------------------------------";
178  msg << "\n";
179 
180  {
181  TimerInfo *tptr = TimerList[0].get();
182  double walltotal = 0.0, cputotal = 0.0;
183  reduce(tptr->wallTime, walltotal, OpMaxAssign());
184  reduce(tptr->cpuTime, cputotal, OpMaxAssign());
185  size_t lengthName = std::min(tptr->name.length(), 19lu);
186  msg << tptr->name.substr(0,lengthName)
187  << std::string().assign(20 - lengthName,'.')
188  << " Wall tot = " << std::setw(10) << walltotal << ","
189  << " CPU tot = " << std::setw(10) << cputotal << "\n"
190  << "\n";
191  }
192 
193  auto begin = ++ TimerList.begin();
194  auto end = TimerList.end();
195  std::sort(begin, end, [](const my_auto_ptr<TimerInfo>& a, const my_auto_ptr<TimerInfo>& b)
196  {
197  return boost::ilexicographical_compare(a->name, b->name);
198  });
199 
200  for (unsigned int i=1; i < TimerList.size(); ++i) {
201  TimerInfo *tptr = TimerList[i].get();
202  double wallmax = 0.0, cpumax = 0.0, wallmin = 0.0, cpumin = 0.0;
203  double wallavg = 0.0, cpuavg = 0.0;
204  reduce(tptr->wallTime, wallmax, OpMaxAssign());
205  reduce(tptr->cpuTime, cpumax, OpMaxAssign());
206  reduce(tptr->wallTime, wallmin, OpMinAssign());
207  reduce(tptr->cpuTime, cpumin, OpMinAssign());
208  reduce(tptr->wallTime, wallavg, OpAddAssign());
209  reduce(tptr->cpuTime, cpuavg, OpAddAssign());
210  size_t lengthName = std::min(tptr->name.length(), 19lu);
211 
212  msg << tptr->name.substr(0,lengthName)
213  << std::string().assign(20 - lengthName, '.')
214  << " Wall max = " << std::setw(10) << wallmax << ","
215  << " CPU max = " << std::setw(10) << cpumax << "\n"
216  << std::string().assign(20,' ')
217  << " Wall avg = " << std::setw(10) << wallavg / Ippl::getNodes() << ","
218  << " CPU avg = " << std::setw(10) << cpuavg / Ippl::getNodes() << "\n"
219  << std::string().assign(20,' ')
220  << " Wall min = " << std::setw(10) << wallmin << ","
221  << " CPU min = " << std::setw(10) << cpumin << "\n"
222  << "\n";
223  }
224  msg << "-----------------------------------------------------------------";
225  msg << endl;
226 }
227 #endif
228 
230 // save the timing results into a file
231 void Timing::print(const std::string &fn, const std::map<std::string, unsigned int> &problemSize) {
232 
233  std::ofstream *timer_stream;
234  Inform *msg;
235 
236  if (TimerList.size() < 1)
237  return;
238 
239  timer_stream = new std::ofstream;
240  timer_stream->open( fn.c_str(), std::ios::out );
241  msg = new Inform( 0, *timer_stream, 0 );
242  // report the average time for each timer
243  // Inform msg("Timings");
244  /*
245  *msg << "---------------------------------------------------------------------------";
246  *msg << "\n";
247  *msg << " Timing results for " << Ippl::getNodes() << " nodes:" << "\n";
248  *msg << "---------------------------------------------------------------------------";
249  *msg << " name nodes (cputot cpumax) (walltot wallmax) cpumin wallmin cpuav wallav ";
250  *msg << "\n";
251  */
252 
253  if (problemSize.size() > 0) {
254  *msg << "Problem size:\n";
255  for (auto it: problemSize) {
256  *msg << " " << std::setw(10) << it.first << ": " << it.second << "\n";
257  }
258  *msg << endl;
259  }
260 
261  *msg << std::setw(27) << "num Nodes"
262  << std::setw(10) << "CPU tot"
263  << std::setw(11) << "Wall tot\n"
264  << std::string().assign(47,'=')
265  << "\n";
266  {
267  TimerInfo *tptr = TimerList[0].get();
268  double walltotal = 0.0, cputotal = 0.0;
269  reduce(tptr->wallTime, walltotal, OpMaxAssign());
270  reduce(tptr->cpuTime, cputotal, OpMaxAssign());
271  size_t lengthName = std::min(tptr->name.length(), 19lu);
272  *msg << tptr->name.substr(0,lengthName);
273  for (int j=lengthName; j < 20; ++j) {
274  *msg << ".";
275  }
276  *msg << " " << std::setw(6) << Ippl::getNodes()
277  << " " << std::setw(9) << std::setprecision(4) << cputotal
278  << " " << std::setw(9) << std::setprecision(4) << walltotal
279  << "\n";
280  }
281 
282  auto begin = ++ TimerList.begin();
283  auto end = TimerList.end();
284  std::sort(begin, end, [](const my_auto_ptr<TimerInfo>& a, const my_auto_ptr<TimerInfo>& b)
285  {
286  return boost::ilexicographical_compare(a->name, b->name);
287  });
288 
289  *msg << "\n"
290  << std::setw(27) << "num Nodes"
291  << std::setw(10) << "CPU max"
292  << std::setw(10) << "Wall max"
293  << std::setw(10) << "CPU min"
294  << std::setw(10) << "Wall min"
295  << std::setw(10) << "CPU avg"
296  << std::setw(11) << "Wall avg\n"
297  << std::string().assign(87,'=')
298  << "\n";
299  for (unsigned int i=0; i < TimerList.size(); ++i) {
300  TimerInfo *tptr = TimerList[i].get();
301  double wallmax = 0.0, cpumax = 0.0, wallmin = 0.0, cpumin = 0.0;
302  double wallavg = 0.0, cpuavg = 0.0;
303  reduce(tptr->wallTime, wallmax, OpMaxAssign());
304  reduce(tptr->cpuTime, cpumax, OpMaxAssign());
305  reduce(tptr->wallTime, wallmin, OpMinAssign());
306  reduce(tptr->cpuTime, cpumin, OpMinAssign());
307  reduce(tptr->wallTime, wallavg, OpAddAssign());
308  reduce(tptr->cpuTime, cpuavg, OpAddAssign());
309  size_t lengthName = std::min(tptr->name.length(), 19lu);
310  *msg << tptr->name.substr(0,lengthName);
311  for (int j=lengthName; j < 20; ++j) {
312  *msg << ".";
313  }
314  *msg << " " << std::setw(6) << Ippl::getNodes()
315  << " " << std::setw(9) << std::setprecision(4) << cpumax
316  << " " << std::setw(9) << std::setprecision(4) << wallmax
317  << " " << std::setw(9) << std::setprecision(4) << cpumin
318  << " " << std::setw(9) << std::setprecision(4) << wallmin
319  << " " << std::setw(9) << std::setprecision(4) << cpuavg / Ippl::getNodes()
320  << " " << std::setw(9) << std::setprecision(4) << wallavg / Ippl::getNodes()
321  << endl;
322  }
323  timer_stream->close();
324  delete msg;
325  delete timer_stream;
326 }
327 
330 
332  PAssert_EQ(stashedInstance.size(), 0);
333 
335  instance = new Timing();
336 }
337 
339  PAssert_GT(stashedInstance.size(), 0);
340 
341  delete instance;
342  instance = stashedInstance.top();
343  stashedInstance.pop();
344 }
345 
346 /***************************************************************************
347  * $RCSfile: IpplTimings.cpp,v $ $Author: adelmann $
348  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
349  ***************************************************************************/
350 
351 
352 /***************************************************************************
353  * $RCSfile: addheaderfooter,v $ $Author: adelmann $
354  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:17 $
355  * IPPL_VERSION_ID: $Id: addheaderfooter,v 1.1.1.1 2003/01/23 07:40:17 adelmann Exp $
356  ***************************************************************************/
static void stash()
void startTimer(TimerRef)
Definition: IpplTimings.cpp:84
static int getNodes()
Definition: IpplInfo.cpp:773
double wallTime
Definition: IpplTimings.h:110
IpplTimerInfo TimerInfo
Definition: IpplTimings.h:125
double cpuTime
Definition: IpplTimings.h:109
void print()
TimerMap_t TimerMap
Definition: IpplTimings.h:167
static std::stack< Timing * > stashedInstance
Definition: IpplTimings.h:233
void clearTimer(TimerRef)
TimerRef indx
Definition: IpplTimings.h:116
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
#define PAssert_EQ(a, b)
Definition: PAssert.h:119
std::string name
Definition: IpplTimings.h:106
TimerList_t TimerList
Definition: IpplTimings.h:164
unsigned int TimerRef
Definition: IpplTimings.h:122
static void pop()
T * value_type(const SliceIterator< T > &)
#define PAssert_GT(a, b)
Definition: PAssert.h:123
void stopTimer(TimerRef)
Definition: IpplTimings.cpp:93
TimerRef getTimer(const char *)
Definition: IpplTimings.cpp:65
static Timing * instance
Definition: IpplTimings.h:232
std::string::iterator iterator
Definition: MSLang.h:16
Definition: Inform.h:41
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
Inform & endl(Inform &inf)
Definition: Inform.cpp:42