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 
270  static void clearCounter (const std::string& name);
271 
272  protected:
273 
275  const T& counter() const { return counter_; }
276 
278  T& counter() { return counter_; }
279 
286  bool isRecursiveCall() const { return isRecursiveCall_; }
287 
292  static std::map<std::string, RCP<T> >& counters ()
293  {
294  if (counters_ == nullptr) {
295  counters_ = new std::map<std::string, RCP<T> > ();
296  // It _is_ possible for atexit() to fail (e.g., because it ran
297  // out of memory for storing callbacks). We could throw an
298  // exception here in that case, but I think it's better just
299  // to let the minor memory leak happen.
300  static_cast<void>( atexit(freeCounters) );
301  }
303  counters_ == nullptr, std::logic_error, "Teuchos::PerformanceMonitorBase::"
304  "counters: Should never get here! counters_ is nullptr.");
305 
306  return *counters_;
307  }
308 
309  private:
311  static TableFormat* format_;
312 
314  static std::map<std::string, RCP<T> >* counters_;
315 
317  T& counter_;
318 
320  bool isRecursiveCall_;
321  };
322 
323  template<class T>
324  TableFormat*
325  PerformanceMonitorBase<T>::format_ = nullptr;
326 
327  template<class T>
328  std::map<std::string, RCP<T> >*
329  PerformanceMonitorBase<T>::counters_ = nullptr;
330 
331  template<class T>
332  RCP<T>
334  {
335  typedef std::map<std::string, RCP<T> > map_type;
336  typedef typename map_type::iterator iter_type;
337 
338  map_type& ctrs = counters ();
339  iter_type it = ctrs.find (name);
340  RCP<T> newCounter = null;
341  if (it == ctrs.end ()) {
342  newCounter = rcp (new T (name));
343 #ifdef HAVE_TEUCHOS_DEBUG
344  const bool wasNotThere = ctrs.insert (std::make_pair (name, newCounter)).second;
346  ! wasNotThere, std::logic_error,
347  "getNewCounter: insert() claims that timer \"" << name << "\" was "
348  "already there in the map, even though find() claims that it was not. "
349  "Please report this bug to the Teuchos developers.");
350 #else
351  // Use the returned iterator to optimize insertion.
352  ctrs.insert (it, std::make_pair (name, newCounter));
353 #endif // HAVE_TEUCHOS_DEBUG
354  } else {
355  newCounter = it->second;
356 #ifdef HAVE_TEUCHOS_DEBUG
358  it->second.is_null (), std::logic_error,
359  "getNewCounter: Timer \"" << name << "\" was already there in the map, "
360  "but looking it up by name resulted in a null timer. "
361  "Please report this bug to the Teuchos developers.");
363  name != it->second->name (), std::logic_error,
364  "getNewCounter: Timer \"" << name << "\" was already there in the map, "
365  "but looking it up by name resulted in a timer with a different name \""
366  << it->second->name () << "\". Please report this bug to the Teuchos "
367  "developers.");
368 #endif // HAVE_TEUCHOS_DEBUG
369  }
370 
371 #ifdef HAVE_TEUCHOS_DEBUG
373  newCounter.is_null (), std::logic_error,
374  "getNewCounter: At end of method, when creating timer \"" << name
375  << "\", newCounter is null. Please report this bug to the Teuchos "
376  "developers.");
377 #endif // HAVE_TEUCHOS_DEBUG
378  return newCounter;
379  }
380 
381  template<class T>
382  RCP<T>
384  {
385  typedef std::map<std::string, RCP<T> > map_type;
386  typedef typename map_type::iterator iter_type;
387 
388  map_type& ctrs = counters ();
389  iter_type it = ctrs.find (name);
390  if (it == ctrs.end ()) {
391  return null;
392  } else {
393  return it->second;
394  }
395  }
396 
397  template<class T>
398  void
399  PerformanceMonitorBase<T>::clearCounter (const std::string& name)
400  {
401  counters ().erase (name);
402  }
403 
404  template<class T>
405  void
407  {
408  counters ().clear ();
409  }
410 
411 } // namespace Teuchos
412 
413 #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 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.
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.