OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
IpplTimings.cpp
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 ***************************************************************************/
7
9#include "Utility/Inform.h"
10#include "Message/GlobalComm.h"
12
13#include <boost/algorithm/string/predicate.hpp>
14
15#include <fstream>
16#include <iostream>
17#include <algorithm>
18
20std::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
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
153void 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.empty()) {
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;
265 stashedInstance.pop();
266}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
T * value_type(const SliceIterator< T > &)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
std::complex< double > a
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
#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()