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_Array.hpp"
00052 #include "Teuchos_Comm.hpp"
00053 #include "Teuchos_RCP.hpp"
00054 #include "Teuchos_StandardParameterEntryValidators.hpp"
00055 #include "Teuchos_TableFormat.hpp"
00056 
00057 namespace Teuchos
00058 {
00066   enum ECounterSetOp { Intersection, Union };
00067 
00092   void
00093   mergeCounterNames (const Comm<int>& comm,
00094                      const Array<std::string>& localNames,
00095                      Array<std::string>& globalNames,
00096                      const ECounterSetOp setOp);
00097 
00141   template <class T>
00142   class PerformanceMonitorBase
00143   {
00144   public:
00146     PerformanceMonitorBase(T& counter_in, bool reset=false)
00147       : counter_(counter_in), isRecursiveCall_(counter_.isRunning())
00148     {
00149       (void)reset;  // get rid of "unused parameter" warning
00150       counter_.incrementNumCalls();
00151     }
00152 
00157     virtual ~PerformanceMonitorBase() {}
00158 
00169     static RCP<T> getNewCounter(const std::string& name)
00170     {
00171       RCP<T> rtn = rcp(new T(name), true);
00172       counters().append(rtn);
00173       return rtn;
00174     }
00175 
00177     static TableFormat& format()
00178     {
00179       // WARNING This is not thread safe!  In particular, if multiple
00180       // threads call this method for the "first time" at the same
00181       // time, the RCP may be initialized incorrectly.
00182       static RCP<TableFormat> rtn=rcp(new TableFormat());
00183       return *rtn;
00184     }
00185 
00206     static RCP<T>
00207     lookupCounter (const std::string& name);
00208 
00213     static void clearCounters ();
00214 
00224     static TEUCHOS_DEPRECATED void clearTimers ();
00225 
00231     static void clearCounter (const std::string& name);
00232 
00243     static TEUCHOS_DEPRECATED void clearTimer (const std::string& name);
00244 
00245   protected:
00246 
00248     const T& counter() const { return counter_; }
00249 
00251     T& counter() { return counter_; }
00252 
00259     bool isRecursiveCall() const { return isRecursiveCall_; }
00260 
00262     static Array<RCP<T> >& counters()
00263     {
00264       // Use the "Meyers Trick" to create static data safely.
00265       //
00266       // WARNING This is not thread safe!  In particular, if multiple
00267       // threads call counters() for the "first time" at the same
00268       // time, the array may be initialized incorrectly.
00269       static Array<RCP<T> > rtn;
00270       return rtn;
00271     }
00272 
00273   private:
00274 
00276     T& counter_;
00277 
00279     bool isRecursiveCall_;
00280   };
00281 
00282 
00283   template<class T>
00284   RCP<T>
00285   PerformanceMonitorBase<T>::lookupCounter (const std::string& name)
00286   {
00287     Array<RCP<T> >& ctrs = counters();
00288 
00289     // This will have to change if we change how we store the
00290     // counters.
00291     for (typename Array<RCP<T> >::const_iterator it = ctrs.begin();
00292          it != ctrs.end(); ++it)
00293       if ((*it)->name() == name)
00294         return *it;
00295 
00296     return null;
00297   }
00298 
00299   template<class T>
00300   void
00301   PerformanceMonitorBase<T>::clearCounter (const std::string& name)
00302   {
00303     Array<RCP<T> > newCounters;
00304     // Only fill newCounters with counters whose name is not the given
00305     // name to clear.  Then, swap newCounters with the old list of
00306     // counters.
00307     typedef typename Array<RCP<T> >::const_iterator iter_t;
00308     for (iter_t it = counters().begin(); it != counters().end(); ++it)
00309       {
00310         // The variable 'it' is an Array iterator; '*it' is a 'const
00311         // RCP<T>&'.  We want the latter.
00312         if ((*it)->name() != name)
00313           newCounters.push_back (*it);
00314       }
00315     counters().swap (newCounters);
00316   }
00317 
00318   template<class T>
00319   void
00320   PerformanceMonitorBase<T>::clearTimer (const std::string& name)
00321   {
00322     clearCounter (name);
00323   }
00324 
00325   template<class T>
00326   void
00327   PerformanceMonitorBase<T>::clearTimers ()
00328   {
00329     clearCounters ();
00330   }
00331 
00332   template<class T>
00333   void
00334   PerformanceMonitorBase<T>::clearCounters ()
00335   {
00336     // Just resizing an Array to have length zero may not necessarily
00337     // free its storage.  The standard idiom is to swap with an empty
00338     // array.
00339     Array<RCP<T> > newCounters;
00340     counters().swap (newCounters);
00341   }
00342 
00343 } // namespace Teuchos
00344 
00345 #endif // TEUCHOS_PERFORMANCEMONITORBASE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines