Sacado_ScalarFlopCounter.hpp

Go to the documentation of this file.
00001 // $Id: Sacado_ScalarFlopCounter.hpp,v 1.8 2007/08/01 19:58:54 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/src/Sacado_ScalarFlopCounter.hpp,v $ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 // @HEADER
00031 
00032 #ifndef SACADO_SCALAR_FLOP_COUNTER_HPP
00033 #define SACADO_SCALAR_FLOP_COUNTER_HPP
00034 
00035 #include "Sacado_ScalarFlopCounterTraits.hpp"
00036 #include <cmath>
00037 #include <algorithm>  // for std::min and std::max
00038 #include <ostream>  // for std::ostream
00039 
00040 namespace Sacado {
00041 
00042   namespace FlopCounterPack {
00043 
00045     class  FlopCounts {
00046     public:
00047 
00049       enum { NUM_OPS = 34 };
00050 
00052       enum EFlopType {
00053   ASSIGN
00054   ,PLUS
00055   ,PLUS_ASSIGN
00056   ,UNARY_PLUS
00057   ,MINUS
00058   ,MINUS_ASSIGN
00059   ,UNARY_MINUS
00060   ,MULTIPLY
00061   ,MULTIPLY_ASSIGN
00062   ,DIVIDE
00063   ,DIVIDE_ASSIGN
00064   ,GREATER_THAN
00065   ,GREATER_THAN_EQUAL
00066   ,LESS_THAN
00067   ,LESS_THAN_EQUAL
00068   ,EQUAL
00069   ,EXP
00070   ,LOG
00071   ,LOG10
00072   ,SQRT
00073   ,COS
00074   ,SIN
00075   ,TAN
00076   ,ACOS
00077   ,ASIN
00078   ,ATAN
00079   ,ATAN2
00080   ,COSH
00081   ,SINH
00082   ,TANH
00083   ,ABS
00084   ,POW
00085   ,MAX
00086   ,MIN
00087       };
00088 
00090       enum { NUM_SUMMARY_OPS = 6 };
00091       
00093       enum ESummaryFlopType {
00094   SUMMARY_ASSIGN
00095   ,SUMMARY_PLUS_MINUS
00096   ,SUMMARY_MULTIPLY
00097   ,SUMMARY_DIVIDE
00098   ,SUMMARY_COMPARISON
00099   ,SUMMARY_NONLINEAR
00100       };
00101 
00103       static const char* flopCountsNames[NUM_OPS];
00104 
00106       static const char* summaryFlopCountsNames[NUM_SUMMARY_OPS];
00107 
00117       static unsigned int flopGranularity;
00118 
00120       double flopCounts[NUM_OPS];
00121 
00123       double summaryFlopCounts[NUM_SUMMARY_OPS];
00124 
00126       double totalFlopCount;
00127 
00129       FlopCounts();
00130 
00132       void reset();
00133       
00135       void finalize();
00136 
00138       void increment(EFlopType ft);
00139       
00140     private:
00141 
00143       ESummaryFlopType getSummaryType(EFlopType ft);
00144 
00146       unsigned int partialFlopCounts[NUM_OPS];
00147 
00149       unsigned int partialSummaryFlopCounts[NUM_SUMMARY_OPS];
00150     };
00151 
00167     std::ostream& printCountersTable(const int n, 
00168              const char* names[], 
00169              const char* abbr[],
00170              const FlopCounts counts[], 
00171              std::ostream &out);
00172 
00173     //
00174     // Member macros
00175     //
00176 
00178 #define SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN( OP, OP_NAME )         \
00179     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& s )  \
00180     {                 \
00181       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00182       val_ OP s.val();              \
00183       return *this;             \
00184     }
00185 
00191     template<class T>
00192     class ScalarFlopCounter {
00193     public:
00194   
00197       
00199       static void resetCounters() { flopCounts_.reset(); }
00200       
00202       static void finalizeCounters() { flopCounts_.finalize(); }
00203 
00205       static FlopCounts getCounters() { return flopCounts_; }
00206 
00211       static std::ostream& printCounters( std::ostream &out ) {
00212   const int n = 1;
00213   const char* names[n] = { "Current" };
00214   const char* abbr[n]  = { "count" };
00215   const FlopCounts counts[n] = { flopCounts_ };
00216   return printCountersTable( n, &names[0], &abbr[0], &counts[0], out );
00217       } 
00218   
00220 
00223 
00225       ScalarFlopCounter() {}
00226 
00228       ScalarFlopCounter(const T &val) : val_(val) {}
00229 
00231       const T& val() const { return val_; }
00232 
00234       void val(const T& a) { val_ = a; }
00235 
00236       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(=,FlopCounts::ASSIGN);
00237       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(+=,FlopCounts::PLUS_ASSIGN);
00238       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(-=,FlopCounts::MINUS_ASSIGN);
00239       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(*=,FlopCounts::MULTIPLY_ASSIGN);
00240       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(/=,FlopCounts::DIVIDE_ASSIGN);
00241       
00243 
00244     private:
00245 
00246       // Static members
00247       static FlopCounts flopCounts_;
00248  
00249       // Object members
00250       T val_;
00251 
00252     public:
00253 
00256       
00262       static void incrCounter( const FlopCounts::EFlopType& ft ) {
00263   flopCounts_.increment(ft);
00264       }
00265 
00267     };
00268 
00269     // Static data members
00270 
00271     template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
00272 
00273     // ////////////////////////////////////////
00274     // Nonmember operator function macros
00275 
00276 #define SCALAR_FLOP_COUNTER_BINARY_OP( OP, OP_NAME )                  \
00277     template<class T>             \
00278     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00279                const ScalarFlopCounter<T>& b )  \
00280     {                 \
00281       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00282       return ScalarFlopCounter<T>(a.val() OP b.val());      \
00283     }                 \
00284     template<class T>                   \
00285     ScalarFlopCounter<T> operator OP ( const T& a,      \
00286                const ScalarFlopCounter<T>& b )  \
00287     {                 \
00288       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00289       return ScalarFlopCounter<T>(a OP b.val());      \
00290     }                 \
00291     template<class T>                   \
00292     ScalarFlopCounter<T> operator OP ( const int& a,      \
00293                const ScalarFlopCounter<T>& b )  \
00294     {                 \
00295       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00296       return ScalarFlopCounter<T>(a OP b.val());      \
00297     }                 \
00298     template<class T>                   \
00299     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00300                const T& b )     \
00301     {                 \
00302       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00303       return ScalarFlopCounter<T>(a.val() OP b);      \
00304     }                 \
00305     template<class T>                   \
00306     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00307                const int& b )     \
00308     {                 \
00309       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00310       return ScalarFlopCounter<T>(a.val() OP b);      \
00311     }
00312 
00313 #define SCALAR_FLOP_COUNTER_UNARY_OP( OP, OP_NAME )                 \
00314     template<class T>             \
00315     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a )  \
00316     {                 \
00317       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00318       return ScalarFlopCounter<T>( OP a.val() );      \
00319     }
00320 
00321 #define SCALAR_FLOP_COUNTER_UNARY_FUNC( OP, OP_NAME )                 \
00322     template<class T>             \
00323     ScalarFlopCounter<T> OP( const ScalarFlopCounter<T>& a )    \
00324     {                 \
00325       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00326       return ScalarFlopCounter<T>( std::OP( a.val() ) );    \
00327     }
00328 
00329 #define SCALAR_FLOP_COUNTER_BINARY_FUNC( OP, OP_NAME )                  \
00330     template<class T>             \
00331     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00332             const ScalarFlopCounter<T>& b )   \
00333     {                 \
00334       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00335       return ScalarFlopCounter<T>( std::OP( a.val(), b.val() ) ); \
00336     }                 \
00337     template<class T>                   \
00338     ScalarFlopCounter<T> OP ( const T& a,       \
00339             const ScalarFlopCounter<T>& b )   \
00340     {                 \
00341       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00342       return ScalarFlopCounter<T>( std::OP( a, b.val() ) );   \
00343     }                 \
00344     template<class T>                   \
00345     ScalarFlopCounter<T> OP ( const int& a,       \
00346             const ScalarFlopCounter<T>& b )   \
00347     {                 \
00348       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00349       return ScalarFlopCounter<T>( std::OP( a, b.val() ) );   \
00350     }                 \
00351     template<class T>                   \
00352     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00353             const T& b )        \
00354     {                 \
00355       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00356       return ScalarFlopCounter<T>( std::OP( a.val(), b ) );   \
00357     }                 \
00358     template<class T>                   \
00359     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00360             const int& b )        \
00361     {                 \
00362       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00363       return ScalarFlopCounter<T>( std::OP(a.val(), b ) );    \
00364     }
00365     
00366 #define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP( OP, OP_NAME )         \
00367     template<class T>             \
00368     bool operator OP ( const ScalarFlopCounter<T>& a,     \
00369            const ScalarFlopCounter<T>& b )      \
00370     {                 \
00371       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00372       return (a.val() OP b.val());          \
00373     }                 \
00374     template<class T>                   \
00375     bool operator OP ( const T& a, const ScalarFlopCounter<T>& b )  \
00376     {                 \
00377       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00378       return (a OP b.val());            \
00379     }                 \
00380     template<class T>                   \
00381     bool operator OP ( const ScalarFlopCounter<T>& a, const T& b )  \
00382     {                 \
00383       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00384       return (a.val() OP b);            \
00385     }
00386 
00387     // ////////////////////////////////////////////
00388     // Nonmember operator and other functions
00389     
00390     // Binary operations
00391     SCALAR_FLOP_COUNTER_BINARY_OP(+,FlopCounts::PLUS)
00392     SCALAR_FLOP_COUNTER_BINARY_OP(-,FlopCounts::MINUS)
00393     SCALAR_FLOP_COUNTER_BINARY_OP(*,FlopCounts::MULTIPLY)
00394     SCALAR_FLOP_COUNTER_BINARY_OP(/,FlopCounts::DIVIDE)
00395 
00396     // Unary operations
00397     SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
00398     SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
00399 
00400     // Unary functions
00401     SCALAR_FLOP_COUNTER_UNARY_FUNC(exp,FlopCounts::EXP)
00402     SCALAR_FLOP_COUNTER_UNARY_FUNC(log,FlopCounts::LOG)
00403     SCALAR_FLOP_COUNTER_UNARY_FUNC(log10,FlopCounts::LOG10)
00404     SCALAR_FLOP_COUNTER_UNARY_FUNC(sqrt,FlopCounts::SQRT) 
00405     SCALAR_FLOP_COUNTER_UNARY_FUNC(cos,FlopCounts::COS)
00406     SCALAR_FLOP_COUNTER_UNARY_FUNC(sin,FlopCounts::SIN)
00407     SCALAR_FLOP_COUNTER_UNARY_FUNC(tan,FlopCounts::TAN)
00408     SCALAR_FLOP_COUNTER_UNARY_FUNC(acos,FlopCounts::ACOS)
00409     SCALAR_FLOP_COUNTER_UNARY_FUNC(asin,FlopCounts::ASIN)
00410     SCALAR_FLOP_COUNTER_UNARY_FUNC(atan,FlopCounts::ATAN)
00411     SCALAR_FLOP_COUNTER_UNARY_FUNC(cosh,FlopCounts::COSH)
00412     SCALAR_FLOP_COUNTER_UNARY_FUNC(sinh,FlopCounts::SINH)
00413     SCALAR_FLOP_COUNTER_UNARY_FUNC(tanh,FlopCounts::TANH)
00414     SCALAR_FLOP_COUNTER_UNARY_FUNC(abs,FlopCounts::ABS)
00415     SCALAR_FLOP_COUNTER_UNARY_FUNC(fabs,FlopCounts::ABS)
00416 
00417     // Binary functions
00418     SCALAR_FLOP_COUNTER_BINARY_FUNC(atan2,FlopCounts::ATAN2)
00419     SCALAR_FLOP_COUNTER_BINARY_FUNC(pow,FlopCounts::POW)
00420     SCALAR_FLOP_COUNTER_BINARY_FUNC(max,FlopCounts::MAX)
00421     SCALAR_FLOP_COUNTER_BINARY_FUNC(min,FlopCounts::MIN)
00422 
00423     // Comparison
00424     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>,FlopCounts::GREATER_THAN)
00425     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>=,FlopCounts::GREATER_THAN_EQUAL)
00426     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<,FlopCounts::LESS_THAN)
00427     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<=,FlopCounts::LESS_THAN_EQUAL)
00428     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(==,FlopCounts::EQUAL)
00429 
00430   } // namespace FlopCounterPack
00431 } // namespace Sacado
00432 
00433 #endif // SACADO_SCALAR_FLOP_COUNTER_HPP

Generated on Wed May 12 21:59:05 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7