Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_PerformanceMonitorBase.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_PERFORMANCEMONITORBASE_H
00043 #define TEUCHOS_PERFORMANCEMONITORBASE_H
00044 
00050 #include "Teuchos_ConfigDefs.hpp"
00051 #include "Teuchos_Array.hpp"
00052 #include "Teuchos_Comm.hpp"
00053 #include "Teuchos_RCP.hpp"
00054 #include "Teuchos_TableFormat.hpp"
00055 
00056 namespace Teuchos
00057 {
00065   enum ECounterSetOp { Intersection, Union };
00066 
00091   void
00092   mergeCounterNames (const Comm<int>& comm,
00093                      const Array<std::string>& localNames,
00094                      Array<std::string>& globalNames,
00095                      const ECounterSetOp setOp);
00096 
00140   template <class T>
00141   class PerformanceMonitorBase
00142   {
00143   public:
00145     PerformanceMonitorBase(T& counter_in, bool reset=false)
00146       : counter_(counter_in), isRecursiveCall_(counter_.isRunning())
00147     {
00148       (void) reset;  // get rid of "unused parameter" warning
00149       counter_.incrementNumCalls ();
00150     }
00151 
00156     virtual ~PerformanceMonitorBase() {}
00157 
00172     static RCP<T> getNewCounter (const std::string& name);
00173 
00175     static TableFormat& format()
00176     {
00177       // WARNING This is not thread safe!  In particular, if multiple
00178       // threads call this method for the "first time" at the same
00179       // time, the RCP may be initialized incorrectly.
00180       static RCP<TableFormat> rtn=rcp(new TableFormat());
00181       return *rtn;
00182     }
00183 
00191     static RCP<T>
00192     lookupCounter (const std::string& name);
00193 
00198     static void clearCounters ();
00199 
00209     static TEUCHOS_DEPRECATED void clearTimers ();
00210 
00216     static void clearCounter (const std::string& name);
00217 
00228     static TEUCHOS_DEPRECATED void clearTimer (const std::string& name);
00229 
00230   protected:
00231 
00233     const T& counter() const { return counter_; }
00234 
00236     T& counter() { return counter_; }
00237 
00244     bool isRecursiveCall() const { return isRecursiveCall_; }
00245 
00247     static std::map<std::string, RCP<T> >& counters()
00248     {
00249       // Use the "Meyers Trick" to create static data safely.
00250       //
00251       // WARNING This is not thread safe!  In particular, if multiple
00252       // threads call counters() for the "first time" at the same
00253       // time, the array may be initialized incorrectly.
00254       static std::map<std::string, RCP<T> > theCounters;
00255       static int initialized;
00256       if (! initialized) {
00257         theCounters.clear ();
00258         initialized = 1;
00259       }
00260       return theCounters;
00261     }
00262 
00263   private:
00264 
00266     T& counter_;
00267 
00269     bool isRecursiveCall_;
00270   };
00271 
00272   template<class T>
00273   RCP<T>
00274   PerformanceMonitorBase<T>::getNewCounter (const std::string& name)
00275   {
00276     typedef std::map<std::string, RCP<T> > map_type;
00277     typedef typename map_type::iterator iter_type;
00278 
00279     map_type& ctrs = counters ();
00280     iter_type it = ctrs.find (name);
00281     RCP<T> newCounter = null;
00282     if (it == ctrs.end ()) {
00283       newCounter = rcp (new T (name));
00284 #ifdef HAVE_TEUCHOS_DEBUG
00285       const bool wasNotThere = ctrs.insert (std::make_pair (name, newCounter)).second;
00286       TEUCHOS_TEST_FOR_EXCEPTION(
00287         ! wasNotThere, std::logic_error,
00288         "getNewCounter: insert() claims that timer \"" << name << "\" was "
00289         "already there in the map, even though find() claims that it was not.  "
00290         "Please report this bug to the Teuchos developers.");
00291 #else
00292       // Use the returned iterator to optimize insertion.
00293       ctrs.insert (it, std::make_pair (name, newCounter));
00294 #endif // HAVE_TEUCHOS_DEBUG
00295     } else {
00296       newCounter = it->second;
00297 #ifdef HAVE_TEUCHOS_DEBUG
00298       TEUCHOS_TEST_FOR_EXCEPTION(
00299         it->second.is_null (), std::logic_error,
00300         "getNewCounter: Timer \"" << name << "\" was already there in the map, "
00301         "but looking it up by name resulted in a null timer.  "
00302         "Please report this bug to the Teuchos developers.");
00303       TEUCHOS_TEST_FOR_EXCEPTION(
00304         name != it->second->name (), std::logic_error,
00305         "getNewCounter: Timer \"" << name << "\" was already there in the map, "
00306         "but looking it up by name resulted in a timer with a different name \""
00307         << it->second->name () << "\".  Please report this bug to the Teuchos "
00308         "developers.");
00309 #endif // HAVE_TEUCHOS_DEBUG
00310     }
00311 
00312 #ifdef HAVE_TEUCHOS_DEBUG
00313     TEUCHOS_TEST_FOR_EXCEPTION(
00314       newCounter.is_null (), std::logic_error,
00315       "getNewCounter: At end of method, when creating timer \"" << name
00316       << "\", newCounter is null.  Please report this bug to the Teuchos "
00317       "developers.");
00318 #endif // HAVE_TEUCHOS_DEBUG
00319     return newCounter;
00320   }
00321 
00322   template<class T>
00323   RCP<T>
00324   PerformanceMonitorBase<T>::lookupCounter (const std::string& name)
00325   {
00326     typedef std::map<std::string, RCP<T> > map_type;
00327     typedef typename map_type::iterator iter_type;
00328 
00329     map_type& ctrs = counters ();
00330     iter_type it = ctrs.find (name);
00331     if (it == ctrs.end ()) {
00332       return null;
00333     } else {
00334       return it->second;
00335     }
00336   }
00337 
00338   template<class T>
00339   void
00340   PerformanceMonitorBase<T>::clearCounter (const std::string& name)
00341   {
00342     counters ().erase (name);
00343   }
00344 
00345   template<class T>
00346   void
00347   PerformanceMonitorBase<T>::clearTimer (const std::string& name)
00348   {
00349     clearCounter (name);
00350   }
00351 
00352   template<class T>
00353   void
00354   PerformanceMonitorBase<T>::clearTimers ()
00355   {
00356     clearCounters ();
00357   }
00358 
00359   template<class T>
00360   void
00361   PerformanceMonitorBase<T>::clearCounters ()
00362   {
00363     counters ().clear ();
00364   }
00365 
00366 } // namespace Teuchos
00367 
00368 #endif // TEUCHOS_PERFORMANCEMONITORBASE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines