OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
IpplTimings.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  ***************************************************************************/
7 
8 #include "Utility/IpplTimings.h"
9 #include "Utility/Inform.h"
10 #include "Message/GlobalComm.h"
11 #include "PETE/IpplExpressions.h"
12 
13 #include <boost/algorithm/string/predicate.hpp>
14 
15 #include <fstream>
16 #include <iostream>
17 #include <algorithm>
18 
20 std::stack<Timing*> IpplTimings::stashedInstance;
21 
23 // default constructor
25  TimerList(),
26  TimerMap()
27 { }
28 
29 
31 // destructor
33  for (TimerMap_t::iterator it = TimerMap.begin(); it != TimerMap.end(); ++ it) {
34  it->second = 0;
35  }
36  TimerMap.clear();
37 
38  TimerList.clear();
39 }
40 
41 
43 // create a timer, or get one that already exists
45  std::string s(nm);
46  TimerInfo *tptr = 0;
47  TimerMap_t::iterator loc = TimerMap.find(s);
48  if (loc == TimerMap.end()) {
49  tptr = new TimerInfo;
50  tptr->indx = TimerList.size();
51  tptr->name = s;
52  TimerMap.insert(TimerMap_t::value_type(s,tptr));
53  TimerList.push_back(my_auto_ptr<TimerInfo>(tptr));
54  } else {
55  tptr = (*loc).second;
56  }
57  return tptr->indx;
58 }
59 
60 
62 // start a timer
64  if (t >= TimerList.size())
65  return;
66  TimerList[t]->start();
67 }
68 
69 
71 // stop a timer, and accumulate it's values
73  if (t >= TimerList.size())
74  return;
75  TimerList[t]->stop();
76 }
77 
78 
80 // clear a timer, by turning it off and throwing away its time
82  if (t >= TimerList.size())
83  return;
84  TimerList[t]->clear();
85 }
86 
87 
89 // print out the timing results
90 void Timing::print() {
91  if (TimerList.size() < 1)
92  return;
93 
94  // report the average time for each timer
95  Inform msg("Timings");
96  msg << level1
97  << "-----------------------------------------------------------------";
98  msg << "\n";
99  msg << " Timing results for " << Ippl::getNodes() << " nodes:" << "\n";
100  msg << "-----------------------------------------------------------------";
101  msg << "\n";
102 
103  {
104  TimerInfo *tptr = TimerList[0].get();
105  double walltotal = 0.0, cputotal = 0.0;
106  reduce(tptr->wallTime, walltotal, OpMaxAssign());
107  reduce(tptr->cpuTime, cputotal, OpMaxAssign());
108  size_t lengthName = std::min(tptr->name.length(), 19lu);
109  msg << tptr->name.substr(0,lengthName)
110  << std::string().assign(20 - lengthName,'.')
111  << " Wall tot = " << std::setw(10) << walltotal << ","
112  << " CPU tot = " << std::setw(10) << cputotal << "\n"
113  << "\n";
114  }
115 
116  auto begin = ++ TimerList.begin();
117  auto end = TimerList.end();
118  std::sort(begin, end, [](const my_auto_ptr<TimerInfo>& a, const my_auto_ptr<TimerInfo>& b)
119  {
120  return boost::ilexicographical_compare(a->name, b->name);
121  });
122 
123  for (unsigned int i=1; i < TimerList.size(); ++i) {
124  TimerInfo *tptr = TimerList[i].get();
125  double wallmax = 0.0, cpumax = 0.0, wallmin = 0.0, cpumin = 0.0;
126  double wallavg = 0.0, cpuavg = 0.0;
127  reduce(tptr->wallTime, wallmax, OpMaxAssign());
128  reduce(tptr->cpuTime, cpumax, OpMaxAssign());
129  reduce(tptr->wallTime, wallmin, OpMinAssign());
130  reduce(tptr->cpuTime, cpumin, OpMinAssign());
131  reduce(tptr->wallTime, wallavg, OpAddAssign());
132  reduce(tptr->cpuTime, cpuavg, OpAddAssign());
133  size_t lengthName = std::min(tptr->name.length(), 19lu);
134 
135  msg << tptr->name.substr(0,lengthName)
136  << std::string().assign(20 - lengthName, '.')
137  << " Wall max = " << std::setw(10) << wallmax << ","
138  << " CPU max = " << std::setw(10) << cpumax << "\n"
139  << std::string().assign(20,' ')
140  << " Wall avg = " << std::setw(10) << wallavg / Ippl::getNodes() << ","
141  << " CPU avg = " << std::setw(10) << cpuavg / Ippl::getNodes() << "\n"
142  << std::string().assign(20,' ')
143  << " Wall min = " << std::setw(10) << wallmin << ","
144  << " CPU min = " << std::setw(10) << cpumin << "\n"
145  << "\n";
146  }
147  msg << "-----------------------------------------------------------------";
148  msg << endl;
149 }
150 
152 // save the timing results into a file
153 void Timing::print(const std::string &fn, const std::map<std::string, unsigned int> &problemSize) {
154 
155  std::ofstream *timer_stream;
156  Inform *msg;
157 
158  if (TimerList.size() < 1)
159  return;
160 
161  timer_stream = new std::ofstream;
162  timer_stream->open( fn.c_str(), std::ios::out );
163  msg = new Inform( 0, *timer_stream, 0 );
164  // report the average time for each timer
165  // Inform msg("Timings");
166  /*
167  *msg << "---------------------------------------------------------------------------";
168  *msg << "\n";
169  *msg << " Timing results for " << Ippl::getNodes() << " nodes:" << "\n";
170  *msg << "---------------------------------------------------------------------------";
171  *msg << " name nodes (cputot cpumax) (walltot wallmax) cpumin wallmin cpuav wallav ";
172  *msg << "\n";
173  */
174 
175  if (problemSize.size() > 0) {
176  *msg << "Problem size:\n";
177  for (auto it: problemSize) {
178  *msg << " " << std::setw(10) << it.first << ": " << it.second << "\n";
179  }
180  *msg << endl;
181  }
182 
183  *msg << std::setw(27) << "num Nodes"
184  << std::setw(10) << "CPU tot"
185  << std::setw(11) << "Wall tot\n"
186  << std::string().assign(47,'=')
187  << "\n";
188  {
189  TimerInfo *tptr = TimerList[0].get();
190  double walltotal = 0.0, cputotal = 0.0;
191  reduce(tptr->wallTime, walltotal, OpMaxAssign());
192  reduce(tptr->cpuTime, cputotal, OpMaxAssign());
193  size_t lengthName = std::min(tptr->name.length(), 19lu);
194  *msg << tptr->name.substr(0,lengthName);
195  for (int j=lengthName; j < 20; ++j) {
196  *msg << ".";
197  }
198  *msg << " " << std::setw(6) << Ippl::getNodes()
199  << " " << std::setw(9) << std::setprecision(4) << cputotal
200  << " " << std::setw(9) << std::setprecision(4) << walltotal
201  << "\n";
202  }
203 
204  auto begin = ++ TimerList.begin();
205  auto end = TimerList.end();
206  std::sort(begin, end, [](const my_auto_ptr<TimerInfo>& a, const my_auto_ptr<TimerInfo>& b)
207  {
208  return boost::ilexicographical_compare(a->name, b->name);
209  });
210 
211  *msg << "\n"
212  << std::setw(27) << "num Nodes"
213  << std::setw(10) << "CPU max"
214  << std::setw(10) << "Wall max"
215  << std::setw(10) << "CPU min"
216  << std::setw(10) << "Wall min"
217  << std::setw(10) << "CPU avg"
218  << std::setw(11) << "Wall avg\n"
219  << std::string().assign(87,'=')
220  << "\n";
221  for (unsigned int i=0; i < TimerList.size(); ++i) {
222  TimerInfo *tptr = TimerList[i].get();
223  double wallmax = 0.0, cpumax = 0.0, wallmin = 0.0, cpumin = 0.0;
224  double wallavg = 0.0, cpuavg = 0.0;
225  reduce(tptr->wallTime, wallmax, OpMaxAssign());
226  reduce(tptr->cpuTime, cpumax, OpMaxAssign());
227  reduce(tptr->wallTime, wallmin, OpMinAssign());
228  reduce(tptr->cpuTime, cpumin, OpMinAssign());
229  reduce(tptr->wallTime, wallavg, OpAddAssign());
230  reduce(tptr->cpuTime, cpuavg, OpAddAssign());
231  size_t lengthName = std::min(tptr->name.length(), 19lu);
232  *msg << tptr->name.substr(0,lengthName);
233  for (int j=lengthName; j < 20; ++j) {
234  *msg << ".";
235  }
236  *msg << " " << std::setw(6) << Ippl::getNodes()
237  << " " << std::setw(9) << std::setprecision(4) << cpumax
238  << " " << std::setw(9) << std::setprecision(4) << wallmax
239  << " " << std::setw(9) << std::setprecision(4) << cpumin
240  << " " << std::setw(9) << std::setprecision(4) << wallmin
241  << " " << std::setw(9) << std::setprecision(4) << cpuavg / Ippl::getNodes()
242  << " " << std::setw(9) << std::setprecision(4) << wallavg / Ippl::getNodes()
243  << endl;
244  }
245  timer_stream->close();
246  delete msg;
247  delete timer_stream;
248 }
249 
252 
254  PAssert_EQ(stashedInstance.size(), 0);
255 
257  instance = new Timing();
258 }
259 
261  PAssert_GT(stashedInstance.size(), 0);
262 
263  delete instance;
264  instance = stashedInstance.top();
265  stashedInstance.pop();
266 }
T * value_type(const SliceIterator< T > &)
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
std::complex< double > a
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
#define PAssert_GT(a, b)
Definition: PAssert.h:108
std::string::iterator iterator
Definition: MSLang.h:16
Definition: Inform.h:42
static int getNodes()
Definition: IpplInfo.cpp:670
std::string name
Definition: IpplTimings.h:106
TimerRef indx
Definition: IpplTimings.h:116
double cpuTime
Definition: IpplTimings.h:109
double wallTime
Definition: IpplTimings.h:110
unsigned int TimerRef
Definition: IpplTimings.h:122
void clearTimer(TimerRef)
Definition: IpplTimings.cpp:81
IpplTimerInfo TimerInfo
Definition: IpplTimings.h:125
TimerMap_t TimerMap
Definition: IpplTimings.h:167
void print()
Definition: IpplTimings.cpp:90
void stopTimer(TimerRef)
Definition: IpplTimings.cpp:72
TimerList_t TimerList
Definition: IpplTimings.h:164
void startTimer(TimerRef)
Definition: IpplTimings.cpp:63
TimerRef getTimer(const char *)
Definition: IpplTimings.cpp:44
static void stash()
static std::stack< Timing * > stashedInstance
Definition: IpplTimings.h:233
static Timing * instance
Definition: IpplTimings.h:232
static void pop()