Loading...
Searching...
No Matches
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-2023 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
39
40std::unique_ptr<Foam::profiling> Foam::profiling::singleton_(nullptr);
41
42
43// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
44
46{
47 // Top-level entry: reset everything
48 pool_.clear();
49 children_.clear();
50 stack_.clear();
51 times_.clear();
52
54
55 pool_.push_back(info);
56 children_.resize(pool_.size());
57 children_.back().clear(); // safety
58
59 return info;
60}
61
62
64(
66 const std::string& descr
67)
68{
69 const label parentId = parent->id();
70
71 for (Information* child : children_[parentId])
72 {
73 if (descr == child->description())
74 {
75 return child; // Found existing
76 }
77 }
78
79 Information* info = new Information(parent, descr, pool_.size());
80
81 pool_.push_back(info);
82 children_.resize(pool_.size());
83 children_.back().clear(); // safety
84 children_[parentId].push_back(info);
85
86 return info;
87}
88
89
92 stack_.push_back(info);
93 times_.push_back(clockValue::now());
94 info->setActive(true); // Mark as on stack
95}
96
97
99{
100 Information *info = stack_.back();
101 clockValue clockval = times_.back();
102 stack_.pop_back();
103 times_.pop_back();
104
105 info->update(clockval.elapsed()); // Update elapsed time
106 info->setActive(false); // Mark as off stack
108 return info;
109}
110
111
112// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
115{
116 return allowed && singleton_;
117}
118
121{
122 allowed = 0;
123}
124
125
127{
128 if (allowed && singleton_)
129 {
130 return singleton_->writeData(os);
131 }
132
133 return false;
134}
135
136
138{
139 if (allowed && singleton_)
140 {
141 return singleton_->regIOobject::write();
142 }
143
144 return false;
145}
146
147
149(
150 const IOobject& ioObj,
151 const Time& owner
152)
153{
154 if (allowed && !singleton_)
155 {
156 singleton_.reset(new profiling(ioObj, owner));
157 }
158}
159
160
162(
163 const dictionary& dict,
164 const IOobject& ioObj,
165 const Time& owner
166)
167{
168 if (allowed && !singleton_)
169 {
170 singleton_.reset(new profiling(dict, ioObj, owner));
171 }
172}
173
174
175void Foam::profiling::stop(const Time& owner)
176{
177 if (singleton_ && &owner == &(singleton_->owner_))
178 {
179 singleton_.reset(nullptr);
180 }
181}
182
183
184Foam::profilingInformation* Foam::profiling::New(const std::string& descr)
185{
186 Information *info = nullptr;
187
188 if (active())
189 {
190 Information *parent = singleton_->stack_.back();
191
192 info = singleton_->create(parent, descr);
193 singleton_->beginTimer(info);
194
195 if (singleton_->memInfo_)
196 {
197 singleton_->memInfo_->update();
198
199 info->maxMem_ = Foam::max
200 (
201 info->maxMem_,
202 singleton_->memInfo_->size()
203 );
205 }
206
207 return info;
208}
209
210
212{
213 if (active() && info)
214 {
215 Information *top = singleton_->endTimer();
216
217 if (info->id() != top->id())
218 {
220 << "Profiling information to unstack has different id than"
221 << " the top of the profiling stack" << nl
222 << " info: " << info->id() << " (" << info->description()
223 << ")\n"
224 << " top: " << top->id() << " (" << top->description()
225 << ")\n" << endl
226 << abort(FatalError);
228 }
229}
230
231
232// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
233
235(
236 const IOobject& io,
237 const Time& owner,
238 const bool allEnabled
239)
240:
242 owner_(owner)
243{
244 if (allEnabled)
245 {
246 sysInfo_.reset(new profilingSysInfo);
247 cpuInfo_.reset(new cpuInfo);
248 memInfo_.reset(new memInfo);
249 }
250
252 this->beginTimer(info);
253
254 DetailInfo << "profiling initialized" << nl;
255}
256
257
259(
260 const dictionary& dict,
261 const IOobject& io,
262 const Time& owner
263)
264:
265 profiling(io, owner, false)
266{
267 {
268 bool on = false;
269
270 if (dict.readIfPresent("sysInfo", on) && on)
271 {
272 sysInfo_.reset(new profilingSysInfo);
273 }
274 if (dict.readIfPresent("cpuInfo", on) && on)
275 {
276 cpuInfo_.reset(new cpuInfo);
277 }
278 if (dict.readIfPresent("memInfo", on) && on)
279 {
280 memInfo_.reset(new memInfo);
282 }
283}
284
285
286// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
287
289{
290 if (this == singleton_.get())
291 {
292 singleton_.reset(nullptr);
293 }
294}
295
296
297// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
300{
301 return owner_;
302}
303
305Foam::label Foam::profiling::size() const noexcept
306{
307 return stack_.size();
308}
309
310
312{
313 static DynamicList<scalar> elapsed;
314
315 const clockValue now(clockValue::now());
316
317 const label nstack = stack_.size();
318
319 elapsed.resize(nstack+1); // extend for last entry, which has no child.
320
321 for (label stacki=0; stacki < nstack; ++stacki)
322 {
323 elapsed[stacki] = (now - times_[stacki]);
324 }
325 elapsed.back() = 0;
326
327 os.beginBlock("profiling");
328
329 // Active items
330 for (label stacki=0; stacki < nstack; ++stacki)
331 {
332 if (stacki) os << nl; // Extra line between entries
333
334 stack_[stacki]->write
335 (
336 os,
337 true,
338 elapsed[stacki], // elapsedTime
339 elapsed[stacki+1] // childTimes
340 );
341 }
342
343 // Non-active items
344 for (const Information& info : pool_)
345 {
346 if (!info.active())
347 {
348 os << nl;
349 info.write(os);
350 }
351 }
352
353 os.endBlock();
354
355 if (sysInfo_)
356 {
357 os << nl;
358 sysInfo_->writeEntry("sysInfo", os);
359 }
360
361 if (cpuInfo_)
362 {
363 os << nl;
364 cpuInfo_->writeEntry("cpuInfo", os);
365 }
366
367 if (memInfo_)
368 {
369 memInfo_->update();
370 os << nl;
371 memInfo_->writeEntry("memInfo", os);
372 }
373
374 return os.good();
375}
376
377
379(
380 IOstreamOption,
381 const bool writeOnProc
382) const
383{
384 return
386 (
387 IOstreamOption(IOstreamOption::ASCII),
388 true // always writeOnProc
389 );
390}
391
392
393// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
IOdictionary(const IOobject &io, const dictionary *fallback=nullptr)
Construct given an IOobject and optional fallback dictionary content.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
InfoProxy< IOobject > info() const noexcept
Return info proxy, for printing information to a stream.
Definition IOobject.H:1041
A simple container for options an IOstream can normally have.
@ ASCII
"ascii" (normal default)
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
virtual Ostream & endBlock()
Write end block group.
Definition Ostream.C:108
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
T & back()
Access last element of the list, position [size()-1].
Definition UListI.H:253
Access to high-resolution clock value with some basic operations. Used to calculate time durations,...
Definition clockValue.H:50
static clockValue now()
The current clock value from the system.
Definition clockValueI.H:23
void update()
Update to the current now() time from the system.
Definition clockValueI.H:57
clockValue elapsed() const
The time duration elapsed until now() since the start point.
Definition clockValueI.H:69
General CPU characteristics.
Definition cpuInfo.H:57
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const dictionary & parent() const noexcept
Return the parent dictionary.
Definition dictionaryI.H:77
Memory usage information for the current process, and the system memory that is free.
Definition memInfo.H:59
Code profiling information in terms of time spent, number of calls etc.
const std::string & description() const noexcept
General system information useful for profiling.
Code profiling.
Definition profiling.H:80
Information * endTimer()
Remove from stack of active information and update elapsed time.
Definition profiling.C:91
static void disable() noexcept
Disallow profiling - turns the InfoSwitch off.
Definition profiling.C:113
profilingInformation Information
Definition profiling.H:85
static bool writeNow()
Write profiling information now.
Definition profiling.C:130
static bool print(Ostream &os)
Print profiling information to specified output.
Definition profiling.C:119
friend class Time
Definition profiling.H:159
virtual bool writeData(Ostream &os) const
writeData member function required by regIOobject
Definition profiling.C:304
profiling(const profiling &)=delete
No copy construct.
static void unstack(const profilingInformation *info)
Remove the information from the top of the stack.
Definition profiling.C:204
static int allowed
Flag if profiling is allowed.
Definition profiling.H:94
static bool active() noexcept
True if profiling is allowed and is active.
Definition profiling.C:107
Information * create()
Clear all profiling and restart with new profiling.
Definition profiling.C:38
const Time & owner() const noexcept
The owner of the profiling.
Definition profiling.C:292
label size() const noexcept
The size of the current stack.
Definition profiling.C:298
static profilingInformation * New(const std::string &descr)
Existing or new element on pool, add to stack.
Definition profiling.C:177
void beginTimer(Information *info)
Add to stack of active information and begin timer datum.
Definition profiling.C:83
static void stop(const Time &owner)
Stop profiling, cleanup pool if possible.
Definition profiling.C:168
virtual bool writeObject(IOstreamOption, const bool writeOnProc) const
Write as uncompressed ASCII.
Definition profiling.C:372
~profiling()
Destructor. Top-level clears the singleton.
Definition profiling.C:281
static void initialize(const IOobject &ioObj, const Time &owner)
Singleton to initialize profiling pool, everything enabled.
Definition profiling.C:142
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
#define DetailInfo
Definition evalEntry.C:30
OBJstream os(runTime.globalPath()/outputName)
const auto & io
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition debug.C:228
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
errorManip< error > abort(error &err)
Definition errorManip.H:139
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict