Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_PerformanceMonitorBase.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // ***********************************************************************
38 // @HEADER
39 
40 #ifndef TEUCHOS_PERFORMANCEMONITORBASE_H
41 #define TEUCHOS_PERFORMANCEMONITORBASE_H
42 
46 
47 #include "Teuchos_ConfigDefs.hpp"
48 #include "Teuchos_Array.hpp"
49 #include "Teuchos_Comm.hpp"
50 #include "Teuchos_RCP.hpp"
51 #include "Teuchos_TableFormat.hpp"
52 #include <cstdlib> // atexit
53 
54 namespace Teuchos
55 {
63  enum ECounterSetOp { Intersection, Union };
64 
89  void
90  mergeCounterNames (const Comm<int>& comm,
91  const Array<std::string>& localNames,
92  Array<std::string>& globalNames,
93  const ECounterSetOp setOp);
94 
105  void
106  unsortedMergePair(const Array<std::string>& localNames,
107  Array<std::string>& globalNames,
108  const ECounterSetOp setOp);
109 
153  template <class T>
155  {
156  public:
158  PerformanceMonitorBase(T& counter_in, bool reset=false)
159  : counter_(counter_in), isRecursiveCall_(counter_.isRunning())
160  {
161  (void) reset; // get rid of "unused parameter" warning
162  counter_.incrementNumCalls ();
163  }
164 
166  PerformanceMonitorBase () = delete;
167 
172  virtual ~PerformanceMonitorBase() = default;
173 
188  static RCP<T> getNewCounter (const std::string& name);
189 
190  private:
200  static void freeTableFormat () {
201  if (format_ != nullptr) {
202  delete format_;
203  format_ = nullptr;
204  }
205  }
206 
216  static void freeCounters () {
217  if (counters_ != nullptr) {
218  delete counters_;
219  counters_ = nullptr;
220  }
221  }
222 
223  public:
232  static TableFormat& format ()
233  {
234  if (format_ == nullptr) {
235  format_ = new TableFormat ();
236  // It _is_ possible for atexit() to fail (e.g., because it ran
237  // out of memory for storing callbacks). We could throw an
238  // exception here in that case, but I think it's better just
239  // to let the minor memory leak happen.
240  static_cast<void>( atexit(freeTableFormat) );
241  }
243  format_ == nullptr, std::logic_error, "Teuchos::PerformanceMonitorBase::"
244  "format: Should never get here! format_ is nullptr.");
245 
246  return *format_;
247  }
248 
256  static RCP<T>
257  lookupCounter (const std::string& name);
258 
263  static void clearCounters ();
264 
274  static TEUCHOS_DEPRECATED void clearTimers ();
275 
281  static void clearCounter (const std::string& name);
282 
293  static TEUCHOS_DEPRECATED void clearTimer (const std::string& name);
294 
295  protected:
296 
298  const T& counter() const { return counter_; }
299 
301  T& counter() { return counter_; }
302 
309  bool isRecursiveCall() const { return isRecursiveCall_; }
310 
315  static std::map<std::string, RCP<T> >& counters ()
316  {
317  if (counters_ == nullptr) {
318  counters_ = new std::map<std::string, RCP<T> > ();
319  // It _is_ possible for atexit() to fail (e.g., because it ran
320  // out of memory for storing callbacks). We could throw an
321  // exception here in that case, but I think it's better just
322  // to let the minor memory leak happen.
323  static_cast<void>( atexit(freeCounters) );
324  }
326  counters_ == nullptr, std::logic_error, "Teuchos::PerformanceMonitorBase::"
327  "counters: Should never get here! counters_ is nullptr.");
328 
329  return *counters_;
330  }
331 
332  private:
334  static TableFormat* format_;
335 
337  static std::map<std::string, RCP<T> >* counters_;
338 
340  T& counter_;
341 
343  bool isRecursiveCall_;
344  };
345 
346  template<class T>
347  TableFormat*
348  PerformanceMonitorBase<T>::format_ = nullptr;
349 
350  template<class T>
351  std::map<std::string, RCP<T> >*
352  PerformanceMonitorBase<T>::counters_ = nullptr;
353 
354  template<class T>
355  RCP<T>
357  {
358  typedef std::map<std::string, RCP<T> > map_type;
359  typedef typename map_type::iterator iter_type;
360 
361  map_type& ctrs = counters ();
362  iter_type it = ctrs.find (name);
363  RCP<T> newCounter = null;
364  if (it == ctrs.end ()) {
365  newCounter = rcp (new T (name));
366 #ifdef HAVE_TEUCHOS_DEBUG
367  const bool wasNotThere = ctrs.insert (std::make_pair (name, newCounter)).second;
369  ! wasNotThere, std::logic_error,
370  "getNewCounter: insert() claims that timer \"" << name << "\" was "
371  "already there in the map, even though find() claims that it was not. "
372  "Please report this bug to the Teuchos developers.");
373 #else
374  // Use the returned iterator to optimize insertion.
375  ctrs.insert (it, std::make_pair (name, newCounter));
376 #endif // HAVE_TEUCHOS_DEBUG
377  } else {
378  newCounter = it->second;
379 #ifdef HAVE_TEUCHOS_DEBUG
381  it->second.is_null (), std::logic_error,
382  "getNewCounter: Timer \"" << name << "\" was already there in the map, "
383  "but looking it up by name resulted in a null timer. "
384  "Please report this bug to the Teuchos developers.");
386  name != it->second->name (), std::logic_error,
387  "getNewCounter: Timer \"" << name << "\" was already there in the map, "
388  "but looking it up by name resulted in a timer with a different name \""
389  << it->second->name () << "\". Please report this bug to the Teuchos "
390  "developers.");
391 #endif // HAVE_TEUCHOS_DEBUG
392  }
393 
394 #ifdef HAVE_TEUCHOS_DEBUG
396  newCounter.is_null (), std::logic_error,
397  "getNewCounter: At end of method, when creating timer \"" << name
398  << "\", newCounter is null. Please report this bug to the Teuchos "
399  "developers.");
400 #endif // HAVE_TEUCHOS_DEBUG
401  return newCounter;
402  }
403 
404  template<class T>
405  RCP<T>
407  {
408  typedef std::map<std::string, RCP<T> > map_type;
409  typedef typename map_type::iterator iter_type;
410 
411  map_type& ctrs = counters ();
412  iter_type it = ctrs.find (name);
413  if (it == ctrs.end ()) {
414  return null;
415  } else {
416  return it->second;
417  }
418  }
419 
420  template<class T>
421  void
422  PerformanceMonitorBase<T>::clearCounter (const std::string& name)
423  {
424  counters ().erase (name);
425  }
426 
427  template<class T>
428  void
429  PerformanceMonitorBase<T>::clearTimer (const std::string& name)
430  {
431  clearCounter (name);
432  }
433 
434  template<class T>
435  void
437  {
438  clearCounters ();
439  }
440 
441  template<class T>
442  void
444  {
445  counters ().clear ();
446  }
447 
448 } // namespace Teuchos
449 
450 #endif // TEUCHOS_PERFORMANCEMONITORBASE_H
static void clearCounters()
&quot;Forget&quot; about all counters created with getNewCounter().
static void clearCounter(const std::string &name)
&quot;Forget&quot; about any counters with the given name.
const T & counter() const
Constant access to the instance&#39;s counter reference.
static TEUCHOS_DEPRECATED void clearTimers()
&quot;Forget&quot; about all counters created with getNewCounter().
static RCP< T > getNewCounter(const std::string &name)
Create a new counter with the specified name and add it to a global set of counters of this type...
static RCP< T > lookupCounter(const std::string &name)
Return the first counter with the given name, or null if none.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
T & counter()
Nonconstant access to the instance&#39;s counter reference.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
PerformanceMonitorBase(T &counter_in, bool reset=false)
Construct with a counter.
virtual ~PerformanceMonitorBase()=default
Destructor.
Provides utilities for formatting tabular output.
void mergeCounterNames(const Comm< int > &comm, const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
Merge counter names over all processors.
void unsortedMergePair(const Array< std::string > &localNames, Array< std::string > &globalNames, const ECounterSetOp setOp)
static std::map< std::string, RCP< T > > & counters()
Array of all counters that were created with getNewCounter() on the calling (MPI) process...
Templated array class derived from the STL std::vector.
static TEUCHOS_DEPRECATED void clearTimer(const std::string &name)
&quot;Forget&quot; about any counters with the given name.
bool isRecursiveCall() const
Whether we are currently in a recursive call of the counter.
Smart reference counting pointer class for automatic garbage collection.
ECounterSetOp
Set operation type for mergeCounterNames() to perform.
Common capabilities for collecting and reporting performance data across processors.
Reference-counted pointer class and non-member templated function implementations.
PerformanceMonitorBase()=delete
Default constructor is deleted, since it would be unsafe.
static TableFormat & format()
Table format that will be used to print a summary of timer results.
Encapsulation of formatting specifications for writing data in a clean tabular form.
bool is_null() const
Returns true if the underlying pointer is null.