Sacado_ScalarFlopCounter.hpp

Go to the documentation of this file.
00001 // $Id$ 
00002 // $Source$ 
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       
00196       template <typename U> 
00197       struct apply {
00198   typedef ScalarFlopCounter<U> type;
00199       };
00200   
00203       
00205       static void resetCounters() { flopCounts_.reset(); }
00206       
00208       static void finalizeCounters() { flopCounts_.finalize(); }
00209 
00211       static FlopCounts getCounters() { return flopCounts_; }
00212 
00217       static std::ostream& printCounters( std::ostream &out ) {
00218   const int n = 1;
00219   const char* names[n] = { "Current" };
00220   const char* abbr[n]  = { "count" };
00221   const FlopCounts counts[n] = { flopCounts_ };
00222   return printCountersTable( n, &names[0], &abbr[0], &counts[0], out );
00223       } 
00224   
00226 
00229 
00231       ScalarFlopCounter() {}
00232 
00234       ScalarFlopCounter(const T &v) : val_(v) {}
00235 
00237       const T& val() const { return val_; }
00238 
00240       void val(const T& a) { val_ = a; }
00241 
00242       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(=,FlopCounts::ASSIGN);
00243       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(+=,FlopCounts::PLUS_ASSIGN);
00244       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(-=,FlopCounts::MINUS_ASSIGN);
00245       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(*=,FlopCounts::MULTIPLY_ASSIGN);
00246       SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(/=,FlopCounts::DIVIDE_ASSIGN);
00247       
00249 
00250     private:
00251 
00252       // Static members
00253       static FlopCounts flopCounts_;
00254  
00255       // Object members
00256       T val_;
00257 
00258     public:
00259 
00262       
00268       static void incrCounter( const FlopCounts::EFlopType& ft ) {
00269   flopCounts_.increment(ft);
00270       }
00271 
00273     };
00274 
00275     // Static data members
00276 
00277     template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
00278 
00279     // ////////////////////////////////////////
00280     // Nonmember operator function macros
00281 
00282 #define SCALAR_FLOP_COUNTER_BINARY_OP( OP, OP_NAME )                  \
00283     template<class T>             \
00284     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00285                const ScalarFlopCounter<T>& b )  \
00286     {                 \
00287       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00288       return ScalarFlopCounter<T>(a.val() OP b.val());      \
00289     }                 \
00290     template<class T>                   \
00291     ScalarFlopCounter<T> operator OP ( const T& a,      \
00292                const ScalarFlopCounter<T>& b )  \
00293     {                 \
00294       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00295       return ScalarFlopCounter<T>(a OP b.val());      \
00296     }                 \
00297     template<class T>                   \
00298     ScalarFlopCounter<T> operator OP ( const int& a,      \
00299                const ScalarFlopCounter<T>& b )  \
00300     {                 \
00301       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00302       return ScalarFlopCounter<T>(a OP b.val());      \
00303     }                 \
00304     template<class T>                   \
00305     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00306                const T& b )     \
00307     {                 \
00308       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00309       return ScalarFlopCounter<T>(a.val() OP b);      \
00310     }                 \
00311     template<class T>                   \
00312     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a, \
00313                const int& b )     \
00314     {                 \
00315       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00316       return ScalarFlopCounter<T>(a.val() OP b);      \
00317     }
00318 
00319 #define SCALAR_FLOP_COUNTER_UNARY_OP( OP, OP_NAME )                 \
00320     template<class T>             \
00321     ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& a )  \
00322     {                 \
00323       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00324       return ScalarFlopCounter<T>( OP a.val() );      \
00325     }
00326 
00327 #define SCALAR_FLOP_COUNTER_UNARY_FUNC( OP, OP_NAME )                 \
00328     template<class T>             \
00329     ScalarFlopCounter<T> OP( const ScalarFlopCounter<T>& a )    \
00330     {                 \
00331       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00332       return ScalarFlopCounter<T>( std::OP( a.val() ) );    \
00333     }
00334 
00335 #define SCALAR_FLOP_COUNTER_BINARY_FUNC( OP, OP_NAME )                  \
00336     template<class T>             \
00337     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00338             const ScalarFlopCounter<T>& b )   \
00339     {                 \
00340       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00341       return ScalarFlopCounter<T>( std::OP( a.val(), b.val() ) ); \
00342     }                 \
00343     template<class T>                   \
00344     ScalarFlopCounter<T> OP ( const T& a,       \
00345             const ScalarFlopCounter<T>& b )   \
00346     {                 \
00347       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00348       return ScalarFlopCounter<T>( std::OP( a, b.val() ) );   \
00349     }                 \
00350     template<class T>                   \
00351     ScalarFlopCounter<T> OP ( const int& a,       \
00352             const ScalarFlopCounter<T>& b )   \
00353     {                 \
00354       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00355       return ScalarFlopCounter<T>( std::OP( a, b.val() ) );   \
00356     }                 \
00357     template<class T>                   \
00358     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00359             const T& b )        \
00360     {                 \
00361       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00362       return ScalarFlopCounter<T>( std::OP( a.val(), b ) );   \
00363     }                 \
00364     template<class T>                   \
00365     ScalarFlopCounter<T> OP ( const ScalarFlopCounter<T>& a,    \
00366             const int& b )        \
00367     {                 \
00368       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00369       return ScalarFlopCounter<T>( std::OP(a.val(), b ) );    \
00370     }
00371     
00372 #define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP( OP, OP_NAME )         \
00373     template<class T>             \
00374     bool operator OP ( const ScalarFlopCounter<T>& a,     \
00375            const ScalarFlopCounter<T>& b )      \
00376     {                 \
00377       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00378       return (a.val() OP b.val());          \
00379     }                 \
00380     template<class T>                   \
00381     bool operator OP ( const T& a, const ScalarFlopCounter<T>& b )  \
00382     {                 \
00383       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00384       return (a OP b.val());            \
00385     }                 \
00386     template<class T>                   \
00387     bool operator OP ( const ScalarFlopCounter<T>& a, const T& b )  \
00388     {                 \
00389       ScalarFlopCounter<T>::incrCounter(OP_NAME);     \
00390       return (a.val() OP b);            \
00391     }
00392 
00393     // ////////////////////////////////////////////
00394     // Nonmember operator and other functions
00395     
00396     // Binary operations
00397     SCALAR_FLOP_COUNTER_BINARY_OP(+,FlopCounts::PLUS)
00398     SCALAR_FLOP_COUNTER_BINARY_OP(-,FlopCounts::MINUS)
00399     SCALAR_FLOP_COUNTER_BINARY_OP(*,FlopCounts::MULTIPLY)
00400     SCALAR_FLOP_COUNTER_BINARY_OP(/,FlopCounts::DIVIDE)
00401 
00402     // Unary operations
00403     SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
00404     SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
00405 
00406     // Unary functions
00407     SCALAR_FLOP_COUNTER_UNARY_FUNC(exp,FlopCounts::EXP)
00408     SCALAR_FLOP_COUNTER_UNARY_FUNC(log,FlopCounts::LOG)
00409     SCALAR_FLOP_COUNTER_UNARY_FUNC(log10,FlopCounts::LOG10)
00410     SCALAR_FLOP_COUNTER_UNARY_FUNC(sqrt,FlopCounts::SQRT) 
00411     SCALAR_FLOP_COUNTER_UNARY_FUNC(cos,FlopCounts::COS)
00412     SCALAR_FLOP_COUNTER_UNARY_FUNC(sin,FlopCounts::SIN)
00413     SCALAR_FLOP_COUNTER_UNARY_FUNC(tan,FlopCounts::TAN)
00414     SCALAR_FLOP_COUNTER_UNARY_FUNC(acos,FlopCounts::ACOS)
00415     SCALAR_FLOP_COUNTER_UNARY_FUNC(asin,FlopCounts::ASIN)
00416     SCALAR_FLOP_COUNTER_UNARY_FUNC(atan,FlopCounts::ATAN)
00417     SCALAR_FLOP_COUNTER_UNARY_FUNC(cosh,FlopCounts::COSH)
00418     SCALAR_FLOP_COUNTER_UNARY_FUNC(sinh,FlopCounts::SINH)
00419     SCALAR_FLOP_COUNTER_UNARY_FUNC(tanh,FlopCounts::TANH)
00420     SCALAR_FLOP_COUNTER_UNARY_FUNC(abs,FlopCounts::ABS)
00421     SCALAR_FLOP_COUNTER_UNARY_FUNC(fabs,FlopCounts::ABS)
00422 
00423     // Binary functions
00424     SCALAR_FLOP_COUNTER_BINARY_FUNC(atan2,FlopCounts::ATAN2)
00425     SCALAR_FLOP_COUNTER_BINARY_FUNC(pow,FlopCounts::POW)
00426     SCALAR_FLOP_COUNTER_BINARY_FUNC(max,FlopCounts::MAX)
00427     SCALAR_FLOP_COUNTER_BINARY_FUNC(min,FlopCounts::MIN)
00428 
00429     // Comparison
00430     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>,FlopCounts::GREATER_THAN)
00431     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>=,FlopCounts::GREATER_THAN_EQUAL)
00432     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<,FlopCounts::LESS_THAN)
00433     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<=,FlopCounts::LESS_THAN_EQUAL)
00434     SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(==,FlopCounts::EQUAL)
00435 
00436   } // namespace FlopCounterPack
00437 } // namespace Sacado
00438 
00439 #endif // SACADO_SCALAR_FLOP_COUNTER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:19:34 2011 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.6.3