00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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>
00038 #include <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
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
00247 static FlopCounts flopCounts_;
00248
00249
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
00270
00271 template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
00272
00273
00274
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
00389
00390
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
00397 SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
00398 SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
00399
00400
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
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
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 }
00431 }
00432
00433 #endif // SACADO_SCALAR_FLOP_COUNTER_HPP