Teuchos - Trilinos Tools Package 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_Comm.hpp"
00052 #include "Teuchos_RCP.hpp"
00053 #include "Teuchos_Array.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     
00168     static RCP<T> getNewCounter(const std::string& name)
00169     {
00170       RCP<T> rtn = rcp(new T(name), true);
00171       counters().append(rtn);
00172       return rtn;
00173     }
00174 
00176     static TableFormat& format()
00177     {
00178       // WARNING This is not thread safe!  In particular, if multiple
00179       // threads call this method for the "first time" at the same
00180       // time, the RCP may be initialized incorrectly.
00181       static RCP<TableFormat> rtn=rcp(new TableFormat()); 
00182       return *rtn; 
00183     }
00184 
00203     static RCP<T> 
00204     lookupCounter (const std::string& name);
00205 
00210     static void clearTimers ();
00211 
00213     static void clearTimer (const std::string& name);
00214 
00215   protected:
00216     
00218     const T& counter() const { return counter_; }
00219     
00221     T& counter() { return counter_; }
00222 
00227     bool isRecursiveCall() const { return isRecursiveCall_; }
00228       
00230     static Array<RCP<T> >& counters() 
00231     {
00232       // Use the "Meyers Trick" to create static data safely.
00233       //
00234       // WARNING This is not thread safe!  In particular, if multiple
00235       // threads call counters() for the "first time" at the same
00236       // time, the array may be initialized incorrectly.
00237       static Array<RCP<T> > rtn;
00238       return rtn;
00239     }
00240 
00241   private:
00242 
00244     T& counter_;
00245     
00247     bool isRecursiveCall_;
00248   };
00249 
00250 
00251   template<class T>
00252   RCP<T> 
00253   PerformanceMonitorBase<T>::lookupCounter (const std::string& name)
00254   {
00255     Array<RCP<T> >& ctrs = counters();
00256 
00257     // This will have to change if we change how we store the
00258     // counters.
00259     for (typename Array<RCP<T> >::const_iterator it = ctrs.begin(); 
00260    it != ctrs.end(); ++it)
00261       if ((*it)->name() == name)
00262   return *it;
00263       
00264     return null;
00265   }
00266 
00267   template<class T>
00268   void
00269   PerformanceMonitorBase<T>::clearTimer (const std::string& name)
00270   {
00271     Array<RCP<T> > newCounters;
00272     // Only fill newCounters with counters whose name is not the given
00273     // name to clear.  Then, swap newCounters with the old list of
00274     // counters.
00275     typedef typename Array<RCP<T> >::const_iterator iter_t;
00276     for (iter_t it = counters().begin(); it != counters().end(); ++it)
00277       {
00278   // The variable 'it' is an Array iterator; '*it' is a 'const
00279   // RCP<T>&'.  We want the latter.
00280   if ((*it)->name() != name)
00281     newCounters.push_back (*it);
00282       }
00283     counters().swap (newCounters);
00284   }
00285 
00286   template<class T>
00287   void
00288   PerformanceMonitorBase<T>::clearTimers ()
00289   {
00290     // Just resizing an Array to have length zero may not necessarily
00291     // free its storage.  The standard idiom is to swap with an empty
00292     // array.
00293     Array<RCP<T> > newCounters;
00294     counters().swap (newCounters);
00295   }
00296 
00297 
00298 
00299 
00300   
00301 } // namespace Teuchos
00302 
00303 
00304 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines