Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_ScalarFlopCounter.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 #ifndef SACADO_SCALAR_FLOP_COUNTER_HPP
31 #define SACADO_SCALAR_FLOP_COUNTER_HPP
32 
33 #include "Sacado_ConfigDefs.h"
35 #include "Sacado_Base.hpp"
36 #include "Sacado_SFINAE_Macros.hpp"
37 #include <cmath>
38 #include <algorithm> // for std::min and std::max
39 #include <ostream> // for std::ostream
40 
41 namespace Sacado {
42 
43  namespace FlopCounterPack {
44 
46  class FlopCounts {
47  public:
48 
50  enum { NUM_OPS = 35 };
51 
53  enum EFlopType {
70  ,EXP
71  ,LOG
75  ,COS
76  ,SIN
77  ,TAN
85  ,ABS
86  ,POW
87  ,MAX
88  ,MIN
89  };
90 
92  enum { NUM_SUMMARY_OPS = 6 };
93 
102  };
103 
105  static const char* flopCountsNames[NUM_OPS];
106 
109 
119  static unsigned int flopGranularity;
120 
123 
126 
129 
131  FlopCounts();
132 
134  void reset();
135 
137  void finalize();
138 
140  void increment(EFlopType ft);
141 
142  private:
143 
146 
148  unsigned int partialFlopCounts[NUM_OPS];
149 
152  };
153 
169  std::ostream& printCountersTable(const int n,
170  const char* names[],
171  const char* abbr[],
172  const FlopCounts counts[],
173  std::ostream &out);
174 
175  //
176  // Member macros
177  //
178 
180 #define SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN( OP, OP_NAME ) \
181  ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& s ) \
182  { \
183  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
184  val_ OP s.val(); \
185  return *this; \
186  }
187 
193  template<class T>
194  class ScalarFlopCounter : public Base< ScalarFlopCounter<T> > {
195  public:
196 
199 
202 
204  template <typename U>
205  struct apply {
207  };
208 
211 
213  static void resetCounters() { flopCounts_.reset(); }
214 
216  static void finalizeCounters() { flopCounts_.finalize(); }
217 
219  static FlopCounts getCounters() { return flopCounts_; }
220 
225  static std::ostream& printCounters( std::ostream &out ) {
226  const int n = 1;
227  const char* names[n] = { "Current" };
228  const char* abbr[n] = { "count" };
229  const FlopCounts counts[n] = { flopCounts_ };
230  return printCountersTable( n, &names[0], &abbr[0], &counts[0], out );
231  }
232 
234 
237 
240 
242  template <typename S>
244 
246  const T& val() const { return val_; }
247 
249  void val(const T& a) { val_ = a; }
250 
256 
258 
259  private:
260 
261  // Static members
263 
264  // Object members
266 
267  public:
268 
271 
277  static void incrCounter( const FlopCounts::EFlopType& ft ) {
279  }
280 
282  };
283 
284  // Static data members
285 
286  template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
287 
288  // ////////////////////////////////////////
289  // Nonmember operator function macros
290 
291 #define SCALAR_FLOP_COUNTER_BINARY_OP( OP, OP_NAME ) \
292  template<class T> \
293  ScalarFlopCounter<T> operator OP ( \
294  const Base< ScalarFlopCounter<T> >& aa, \
295  const Base< ScalarFlopCounter<T> >& bb ) \
296  { \
297  const ScalarFlopCounter<T>& a = aa.derived(); \
298  const ScalarFlopCounter<T>& b = bb.derived(); \
299  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
300  return ScalarFlopCounter<T>(a.val() OP b.val()); \
301  } \
302  template<class T> \
303  ScalarFlopCounter<T> operator OP ( \
304  const typename ScalarFlopCounter<T>::value_type& a, \
305  const Base< ScalarFlopCounter<T> >& bb ) \
306  { \
307  const ScalarFlopCounter<T>& b = bb.derived(); \
308  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
309  return ScalarFlopCounter<T>(a OP b.val()); \
310  } \
311  template<class T> \
312  ScalarFlopCounter<T> operator OP ( \
313  const int& a, \
314  const Base< ScalarFlopCounter<T> >& bb ) \
315  { \
316  const ScalarFlopCounter<T>& b = bb.derived(); \
317  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
318  return ScalarFlopCounter<T>(a OP b.val()); \
319  } \
320  template<class T> \
321  ScalarFlopCounter<T> operator OP ( \
322  const Base< ScalarFlopCounter<T> >& aa, \
323  const typename ScalarFlopCounter<T>::value_type& b ) \
324  { \
325  const ScalarFlopCounter<T>& a = aa.derived(); \
326  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
327  return ScalarFlopCounter<T>(a.val() OP b); \
328  } \
329  template<class T> \
330  ScalarFlopCounter<T> operator OP ( \
331  const Base< ScalarFlopCounter<T> >& aa, \
332  const int& b ) \
333  { \
334  const ScalarFlopCounter<T>& a = aa.derived(); \
335  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
336  return ScalarFlopCounter<T>(a.val() OP b); \
337  }
338 
339 #define SCALAR_FLOP_COUNTER_UNARY_OP( OP, OP_NAME ) \
340  template<class T> \
341  ScalarFlopCounter<T> operator OP ( \
342  const Base< ScalarFlopCounter<T> >& aa ) \
343  { \
344  const ScalarFlopCounter<T>& a = aa.derived(); \
345  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
346  return ScalarFlopCounter<T>( OP a.val() ); \
347  }
348 
349 #define SCALAR_FLOP_COUNTER_UNARY_FUNC( OP, OP_NAME ) \
350  template<class T> \
351  ScalarFlopCounter<T> OP( \
352  const Base< ScalarFlopCounter<T> >& aa ) \
353  { \
354  const ScalarFlopCounter<T>& a = aa.derived(); \
355  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
356  return ScalarFlopCounter<T>( std::OP( a.val() ) ); \
357  }
358 
359 #define SCALAR_FLOP_COUNTER_BINARY_FUNC( OP, OP_NAME ) \
360  template<class T> \
361  ScalarFlopCounter<T> OP ( \
362  const Base< ScalarFlopCounter<T> >& aa, \
363  const Base< ScalarFlopCounter<T> >& bb ) \
364  { \
365  const ScalarFlopCounter<T>& a = aa.derived(); \
366  const ScalarFlopCounter<T>& b = bb.derived(); \
367  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
368  return ScalarFlopCounter<T>( std::OP( a.val(), b.val() ) ); \
369  } \
370  template<class T> \
371  ScalarFlopCounter<T> OP ( \
372  const typename ScalarFlopCounter<T>::value_type& a, \
373  const Base< ScalarFlopCounter<T> >& bb ) \
374  { \
375  const ScalarFlopCounter<T>& b = bb.derived(); \
376  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
377  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
378  } \
379  template<class T> \
380  ScalarFlopCounter<T> OP ( \
381  const int& a, \
382  const Base< ScalarFlopCounter<T> >& bb ) \
383  { \
384  const ScalarFlopCounter<T>& b = bb.derived(); \
385  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
386  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
387  } \
388  template<class T> \
389  ScalarFlopCounter<T> OP ( \
390  const Base< ScalarFlopCounter<T> >& aa, \
391  const typename ScalarFlopCounter<T>::value_type& b ) \
392  { \
393  const ScalarFlopCounter<T>& a = aa.derived(); \
394  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
395  return ScalarFlopCounter<T>( std::OP( a.val(), b ) ); \
396  } \
397  template<class T> \
398  ScalarFlopCounter<T> OP ( \
399  const Base< ScalarFlopCounter<T> >& aa, \
400  const int& b ) \
401  { \
402  const ScalarFlopCounter<T>& a = aa.derived(); \
403  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
404  return ScalarFlopCounter<T>( std::OP(a.val(), b ) ); \
405  }
406 
407 #define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP( OP, OP_NAME ) \
408  template<class T> \
409  bool operator OP ( \
410  const Base< ScalarFlopCounter<T> >& aa, \
411  const Base< ScalarFlopCounter<T> >& bb ) \
412  { \
413  const ScalarFlopCounter<T>& a = aa.derived(); \
414  const ScalarFlopCounter<T>& b = bb.derived(); \
415  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
416  return (a.val() OP b.val()); \
417  } \
418  template<class T> \
419  bool operator OP ( \
420  const typename ScalarFlopCounter<T>::value_type& a, \
421  const Base< ScalarFlopCounter<T> >& bb ) \
422  { \
423  const ScalarFlopCounter<T>& b = bb.derived(); \
424  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
425  return (a OP b.val()); \
426  } \
427  template<class T> \
428  bool operator OP ( \
429  const Base< ScalarFlopCounter<T> >& aa, \
430  const typename ScalarFlopCounter<T>::value_type& b ) \
431  { \
432  const ScalarFlopCounter<T>& a = aa.derived(); \
433  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
434  return (a.val() OP b); \
435  }
436 
437  // ////////////////////////////////////////////
438  // Nonmember operator and other functions
439 
440  // Binary operations
442  SCALAR_FLOP_COUNTER_BINARY_OP(-,FlopCounts::MINUS)
443  SCALAR_FLOP_COUNTER_BINARY_OP(*,FlopCounts::MULTIPLY)
444  SCALAR_FLOP_COUNTER_BINARY_OP(/,FlopCounts::DIVIDE)
445 
446  // Unary operations
447  SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
448  SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
449 
450  // Unary functions
451  SCALAR_FLOP_COUNTER_UNARY_FUNC(exp,FlopCounts::EXP)
452  SCALAR_FLOP_COUNTER_UNARY_FUNC(log,FlopCounts::LOG)
453  SCALAR_FLOP_COUNTER_UNARY_FUNC(log10,FlopCounts::LOG10)
454  SCALAR_FLOP_COUNTER_UNARY_FUNC(sqrt,FlopCounts::SQRT)
455  SCALAR_FLOP_COUNTER_UNARY_FUNC(cbrt,FlopCounts::CBRT)
456  SCALAR_FLOP_COUNTER_UNARY_FUNC(cos,FlopCounts::COS)
457  SCALAR_FLOP_COUNTER_UNARY_FUNC(sin,FlopCounts::SIN)
458  SCALAR_FLOP_COUNTER_UNARY_FUNC(tan,FlopCounts::TAN)
459  SCALAR_FLOP_COUNTER_UNARY_FUNC(acos,FlopCounts::ACOS)
460  SCALAR_FLOP_COUNTER_UNARY_FUNC(asin,FlopCounts::ASIN)
461  SCALAR_FLOP_COUNTER_UNARY_FUNC(atan,FlopCounts::ATAN)
462  SCALAR_FLOP_COUNTER_UNARY_FUNC(cosh,FlopCounts::COSH)
463  SCALAR_FLOP_COUNTER_UNARY_FUNC(sinh,FlopCounts::SINH)
464  SCALAR_FLOP_COUNTER_UNARY_FUNC(tanh,FlopCounts::TANH)
465  SCALAR_FLOP_COUNTER_UNARY_FUNC(abs,FlopCounts::ABS)
466  SCALAR_FLOP_COUNTER_UNARY_FUNC(fabs,FlopCounts::ABS)
467 
468  // Binary functions
469  SCALAR_FLOP_COUNTER_BINARY_FUNC(atan2,FlopCounts::ATAN2)
470  SCALAR_FLOP_COUNTER_BINARY_FUNC(pow,FlopCounts::POW)
471  SCALAR_FLOP_COUNTER_BINARY_FUNC(max,FlopCounts::MAX)
472  SCALAR_FLOP_COUNTER_BINARY_FUNC(min,FlopCounts::MIN)
473 
474  // Comparison
475  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>,FlopCounts::GREATER_THAN)
476  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>=,FlopCounts::GREATER_THAN_EQUAL)
477  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<,FlopCounts::LESS_THAN)
478  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<=,FlopCounts::LESS_THAN_EQUAL)
479  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(==,FlopCounts::EQUAL)
480 
481  } // namespace FlopCounterPack
482 } // namespace Sacado
483 
484 #endif // SACADO_SCALAR_FLOP_COUNTER_HPP
cbrt(expr.val())
void reset()
Reset flop counters before starting a block of computations. */.
static FlopCounts getCounters()
Get the flop counts after a block of computations.
static void resetCounters()
Reset static flop counters before starting a block of computations.
asin(expr.val())
cosh(expr.val())
abs(expr.val())
ESummaryFlopType getSummaryType(EFlopType ft)
Get summary op enum from op enum.
#define SACADO_ENABLE_VALUE_CTOR_DECL
void increment(EFlopType ft)
Increment an individual flop counter.
static void incrCounter(const FlopCounts::EFlopType &ft)
Increment an individual flop counter.
unsigned int partialFlopCounts[NUM_OPS]
Partial sum of individual flop counts.
const T & val() const
Return the current value.
std::ostream & printCountersTable(const int n, const char *names[], const char *abbr[], const FlopCounts counts[], std::ostream &out)
Print a list of flop counts into a single table.
static unsigned int flopGranularity
The number of flops to accumulate as an integer before converting to a double.
atan(expr.val())
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from T)
Base class for Sacado types to control overload resolution.
Definition: Sacado_Base.hpp:46
unsigned int partialSummaryFlopCounts[NUM_SUMMARY_OPS]
Partial sum of summary category flop counts.
Turn ScalarFlopCounter into a meta-function class usable with mpl::apply.
ScalarFlopCounter(const S &v, SACADO_ENABLE_VALUE_CTOR_DECL)
Construct to scalar value.
#define T
Definition: Sacado_rad.hpp:573
tanh(expr.val())
ESummaryFlopType
Enum of summary operation categories.
static std::ostream & printCounters(std::ostream &out)
Print the current static flop counts to out.
SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(=, FlopCounts::ASSIGN)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
RemoveConst< T >::type value_type
Typename of values.
sqrt(expr.val())
sinh(expr.val())
tan(expr.val())
double summaryFlopCounts[NUM_SUMMARY_OPS]
Summary category flop counts.
static const char * flopCountsNames[NUM_OPS]
Names of individual flops.
Class storing flop counts and summary flop counts.
#define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(OP, OP_NAME)
atan2(expr1.val(), expr2.val())
double flopCounts[NUM_OPS]
Individual flop counts.
sin(expr.val())
static const char * summaryFlopCountsNames[NUM_SUMMARY_OPS]
Names for summary operation categories.
log(expr.val())
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define SCALAR_FLOP_COUNTER_UNARY_FUNC(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_BINARY_OP(OP, OP_NAME)
SACADO_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
static void finalizeCounters()
Finalize total flop count after block of computations.
void val(const T &a)
Set the current value.
exp(expr.val())
fabs(expr.val())
int n
log10(expr.val())
cos(expr.val())
#define SCALAR_FLOP_COUNTER_UNARY_OP(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_BINARY_FUNC(OP, OP_NAME)