|
Sacado Package Browser (Single Doxygen Collection) Version of the Day
|
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
1.7.4