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 -------------------------------------------------------------------------------
11 License
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"
31 #include "profilingInformation.H"
32 #include "profilingSysInfo.H"
33 #include "cpuInfo.H"
34 #include "memInfo.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 int Foam::profiling::allowed(Foam::debug::infoSwitch("allowProfiling", 1));
39 std::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 (
64  profilingInformation *parent,
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 
172 void 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 
229 Foam::profiling::profiling
230 (
231  const IOobject& io,
232  const Time& owner,
233  const bool allEnabled
234 )
235 :
236  IOdictionary(io),
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 
260 Foam::profiling::profiling
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 
303 Foam::label Foam::profiling::size() const noexcept
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 // ************************************************************************* //
profiling.H
Foam::DynamicList::resize
void resize(const label len)
Definition: DynamicListI.H:353
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::BitSetOps::create
bitSet create(const label n, const labelHashSet &locations, const bool on=true)
Create a bitSet with length n with the specified on locations.
Definition: BitOps.C:123
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::profilingInformation::update
void update(const scalar elapsedTime)
Update it with a new timing information.
Definition: profilingInformation.C:68
Foam::profilingInformation::description
const string & description() const
Definition: profilingInformation.H:137
Foam::DynamicList< scalar >
Foam::profilingInformation::id
label id() const
Definition: profilingInformation.H:132
Foam::profilingInformation::setActive
void setActive(bool state) const
Mark as being active or passive)
Definition: profilingInformation.C:82
Foam::profiling::create
Information * create()
Clear all profiling and restart with new profiling.
Definition: profiling.C:44
Foam::profiling::allowed
static int allowed
Flag if profiling is allowed.
Definition: profiling.H:97
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Ostream::beginBlock
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:91
Foam::IOobject::info
InfoProxy< IOobject > info() const
Return info proxy.
Definition: IOobject.H:689
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::clockValue::elapsed
clockValue elapsed() const
The time duration elapsed until now() since the start point.
Definition: clockValueI.H:76
Foam::debug::infoSwitch
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
profilingInformation.H
Foam::profiling::stop
static void stop(const Time &owner)
Stop profiling, cleanup pool if possible.
Definition: profiling.C:172
Foam::profilingInformation
Code profiling information in terms of time spent, number of calls etc.
Definition: profilingInformation.H:56
Foam::profiling::active
static bool active()
True if profiling is allowed and is active.
Definition: profiling.C:111
argList.H
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::profiling::owner
const Time & owner() const
The owner of the profiling.
Definition: profiling.C:297
Foam::profiling::endTimer
Information * endTimer()
Remove from stack of active information and update elapsed time.
Definition: profiling.C:97
DetailInfo
#define DetailInfo
Definition: evalEntry.C:37
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::profiling::~profiling
~profiling()
Destructor. Top-level clears the singleton.
Definition: profiling.C:286
Foam::cpuInfo
General CPU characteristics.
Definition: cpuInfo.H:59
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::profilingSysInfo
General system information useful for profiling.
Definition: profilingSysInfo.H:51
Foam::Ostream::endBlock
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:109
Foam::clockValue
Access to high-resolution clock value with some basic operations. Used to calculate time durations,...
Definition: clockValue.H:53
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
Foam::memInfo
Memory usage information for the current process, and the system memory that is free.
Definition: memInfo.H:62
Foam::regIOobject::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: regIOobjectWrite.C:36
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam::profiling::disable
static void disable()
Disallow profiling by forcing the InfoSwitch off.
Definition: profiling.C:117
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::profiling::unstack
static void unstack(const profilingInformation *info)
Remove the information from the top of the stack.
Definition: profiling.C:206
Foam::profiling::beginTimer
void beginTimer(Information *info)
Add to stack of active information and begin timer datum.
Definition: profiling.C:89
Foam::profiling::initialize
static void initialize(const IOobject &ioObj, const Time &owner)
Singleton to initialize profiling pool, everything enabled.
Definition: profiling.C:146
Foam::profiling::writeData
virtual bool writeData(Ostream &os) const
writeData member function required by regIOobject
Definition: profiling.C:309
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::profiling::New
static profilingInformation * New(const string &descr)
Existing or new element on pool, add to stack.
Definition: profiling.C:181
Foam::profiling::size
label size() const noexcept
The size of the current stack.
Definition: profiling.C:303
Foam::profiling::print
static bool print(Ostream &os)
Print profiling information to specified output.
Definition: profiling.C:123
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:236
profilingSysInfo.H
Foam::profiling
Code profiling.
Definition: profiling.H:82
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::profiling::Information
profilingInformation Information
Definition: profiling.H:90
Foam::clockValue::now
static clockValue now()
The current clock value from the system.
Definition: clockValueI.H:30
Foam::profiling::writeObject
virtual bool writeObject(IOstreamOption, const bool valid) const
Write as uncompressed ASCII.
Definition: profiling.C:385
Foam::profiling::writeNow
static bool writeNow()
Write profiling information now.
Definition: profiling.C:134