profiling.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2009-2016 Bernhard Gschaider
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "argList.H"
30#include "profiling.H"
32#include "profilingSysInfo.H"
33#include "cpuInfo.H"
34#include "memInfo.H"
35
36// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37
39std::unique_ptr<Foam::profiling> Foam::profiling::singleton_(nullptr);
40
41
42// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43
45{
46 // Top-level entry: reset everything
47 pool_.clear();
48 children_.clear();
49 stack_.clear();
50 times_.clear();
51
53
54 pool_.append(info);
55 children_.resize(pool_.size());
56 children_.last().clear(); // safety
57
58 return info;
59}
60
61
63(
65 const string& descr
66)
67{
68 const label parentId = parent->id();
69
70 for (Information* child : children_[parentId])
71 {
72 if (descr == child->description())
73 {
74 return child; // Found existing
75 }
76 }
77
78 Information* info = new Information(parent, descr, pool_.size());
79
80 pool_.append(info);
81 children_.resize(pool_.size());
82 children_.last().clear(); // safety
83 children_[parentId].append(info);
84
85 return info;
86}
87
88
90{
91 stack_.append(info);
92 times_.append(clockValue::now());
93 info->setActive(true); // Mark as on stack
94}
95
96
98{
99 Information *info = stack_.remove();
100 clockValue clockval = times_.remove();
101
102 info->update(clockval.elapsed()); // Update elapsed time
103 info->setActive(false); // Mark as off stack
104
105 return info;
106}
107
108
109// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
110
112{
113 return allowed && singleton_;
114}
115
116
118{
119 allowed = 0;
120}
121
122
124{
125 if (active())
126 {
127 return singleton_->writeData(os);
128 }
129
130 return false;
131}
132
133
135{
136 if (active())
137 {
138 return singleton_->regIOobject::write();
139 }
140
141 return false;
142}
143
144
146(
147 const IOobject& ioObj,
148 const Time& owner
149)
150{
151 if (allowed && !singleton_)
152 {
153 singleton_.reset(new profiling(ioObj, owner));
154 }
155}
156
157
159(
160 const dictionary& dict,
161 const IOobject& ioObj,
162 const Time& owner
163)
164{
165 if (allowed && !singleton_)
166 {
167 singleton_.reset(new profiling(dict, ioObj, owner));
168 }
169}
170
171
172void Foam::profiling::stop(const Time& owner)
173{
174 if (singleton_ && &owner == &(singleton_->owner_))
175 {
176 singleton_.reset(nullptr);
177 }
178}
179
180
182{
183 Information *info = nullptr;
184
185 if (active())
186 {
187 Information *parent = singleton_->stack_.last();
188
189 info = singleton_->create(parent, descr);
190 singleton_->beginTimer(info);
191
192 if (singleton_->memInfo_)
193 {
194 info->maxMem_ = Foam::max
195 (
196 info->maxMem_,
197 singleton_->memInfo_->update().size()
198 );
199 }
200 }
201
202 return info;
203}
204
205
207{
208 if (active() && info)
209 {
210 Information *top = singleton_->endTimer();
211
212 if (info->id() != top->id())
213 {
215 << "Profiling information to unstack has different id than"
216 << " the top of the profiling stack" << nl
217 << " info: " << info->id() << " (" << info->description()
218 << ")\n"
219 << " top: " << top->id() << " (" << top->description()
220 << ")\n" << endl
221 << abort(FatalError);
222 }
223 }
224}
225
226
227// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
228
230(
231 const IOobject& io,
232 const Time& owner,
233 const bool allEnabled
234)
235:
237 owner_(owner),
238 pool_(),
239 children_(),
240 stack_(),
241 times_(),
242 sysInfo_(nullptr),
243 cpuInfo_(nullptr),
244 memInfo_(nullptr)
245{
246 if (allEnabled)
247 {
248 sysInfo_.reset(new profilingSysInfo);
249 cpuInfo_.reset(new cpuInfo);
250 memInfo_.reset(new memInfo);
251 }
252
253 Information *info = this->create();
254 this->beginTimer(info);
255
256 DetailInfo << "profiling initialized" << nl;
257}
258
259
261(
262 const dictionary& dict,
263 const IOobject& io,
264 const Time& owner
265)
266:
267 profiling(io, owner, false)
268{
269 if (dict.getOrDefault("sysInfo", false))
270 {
271 sysInfo_.reset(new profilingSysInfo);
272 }
273 if (dict.getOrDefault("cpuInfo", false))
274 {
275 cpuInfo_.reset(new cpuInfo);
276 }
277 if (dict.getOrDefault("memInfo", false))
278 {
279 memInfo_.reset(new memInfo);
280 }
281}
282
283
284// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
285
287{
288 if (this == singleton_.get())
289 {
290 singleton_.reset(nullptr);
291 }
292}
293
294
295// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
296
298{
299 return owner_;
300}
301
302
304{
305 return stack_.size();
306}
307
308
310{
311 static DynamicList<scalar> elapsed;
312
313 const clockValue now(clockValue::now());
314
315 const label nstack = stack_.size();
316
317 elapsed.resize(nstack+1); // extend for last entry, which has no child.
318
319 for (label stacki=0; stacki < nstack; ++stacki)
320 {
321 elapsed[stacki] = (now - times_[stacki]);
322 }
323 elapsed.last() = 0;
324
325 os.beginBlock("profiling");
326
327 // Active items
328 for (label stacki=0; stacki < nstack; ++stacki)
329 {
330 if (stacki) os << nl; // Extra line between entries
331
332 stack_[stacki]->write
333 (
334 os,
335 true,
336 elapsed[stacki], // elapsedTime
337 elapsed[stacki+1] // childTimes
338 );
339 }
340
341 // Non-active items
342 for (const Information& info : pool_)
343 {
344 if (!info.active())
345 {
346 os << nl;
347 info.write(os);
348 }
349 }
350
351 os.endBlock();
352
353 if (sysInfo_)
354 {
355 os << nl;
356 os.beginBlock("sysInfo");
357 sysInfo_->write(os);
358 os.endBlock();
359 }
360
361 if (cpuInfo_)
362 {
363 os << nl;
364 os.beginBlock("cpuInfo");
365 cpuInfo_->write(os);
366 os.endBlock();
367 }
368
369 if (memInfo_)
370 {
371 memInfo_->update();
372
373 os << nl;
374 os.beginBlock("memInfo");
375 memInfo_->write(os);
376 os.writeEntry("units", "kB");
377 os.endBlock();
378 }
379
380 return os.good();
381}
382
383
385(
387 const bool valid
388) const
389{
391}
392
393
394// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void resize(const label len)
Definition: DynamicListI.H:353
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
InfoProxy< IOobject > info() const
Return info proxy, for printing information to a stream.
Definition: IOobject.H:690
The IOstreamOption is a simple container for options an IOstream can normally have.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:105
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:239
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:87
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
T & last()
Return the last element of the list.
Definition: UListI.H:216
Access to high-resolution clock value with some basic operations. Used to calculate time durations,...
Definition: clockValue.H:54
static clockValue now()
The current clock value from the system.
Definition: clockValueI.H:30
clockValue elapsed() const
The time duration elapsed until now() since the start point.
Definition: clockValueI.H:76
General CPU characteristics.
Definition: cpuInfo.H:60
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
void stop()
Stop parsing, freeing the allocated parser.
Memory usage information for the current process, and the system memory that is free.
Definition: memInfo.H:63
scalar print()
Print to screen.
Code profiling information in terms of time spent, number of calls etc.
void update(const scalar elapsedTime)
Update it with a new timing information.
const string & description() const
void setActive(bool state) const
Mark as being active or passive)
General system information useful for profiling.
Code profiling.
Definition: profiling.H:85
static bool active()
True if profiling is allowed and is active.
Definition: profiling.C:111
Information * endTimer()
Remove from stack of active information and update elapsed time.
Definition: profiling.C:97
virtual bool writeObject(IOstreamOption, const bool valid) const
Write as uncompressed ASCII.
Definition: profiling.C:385
profilingInformation Information
Definition: profiling.H:90
static bool writeNow()
Write profiling information now.
Definition: profiling.C:134
virtual bool writeData(Ostream &os) const
writeData member function required by regIOobject
Definition: profiling.C:309
const Time & owner() const
The owner of the profiling.
Definition: profiling.C:297
static void unstack(const profilingInformation *info)
Remove the information from the top of the stack.
Definition: profiling.C:206
static int allowed
Flag if profiling is allowed.
Definition: profiling.H:97
Information * create()
Clear all profiling and restart with new profiling.
Definition: profiling.C:44
static void disable()
Disallow profiling by forcing the InfoSwitch off.
Definition: profiling.C:117
label size() const noexcept
The size of the current stack.
Definition: profiling.C:303
void beginTimer(Information *info)
Add to stack of active information and begin timer datum.
Definition: profiling.C:89
~profiling()
Destructor. Top-level clears the singleton.
Definition: profiling.C:286
static void initialize(const IOobject &ioObj, const Time &owner)
Singleton to initialize profiling pool, everything enabled.
Definition: profiling.C:146
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define DetailInfo
Definition: evalEntry.C:37
OBJstream os(runTime.globalPath()/outputName)
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
errorManip< error > abort(error &err)
Definition: errorManip.H:144
const direction noexcept
Definition: Scalar.H:223
error FatalError
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict