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 
49 #ifdef HAVE_SACADO_CXX11
50  enum { NUM_OPS = 35 };
52 #else
53  enum { NUM_OPS = 34 };
55 #endif
56  enum EFlopType {
74  ,EXP
75  ,LOG
78 #ifdef HAVE_SACADO_CXX11
79  ,CBRT
80 #endif
81  ,COS
82  ,SIN
83  ,TAN
91  ,ABS
92  ,POW
93  ,MAX
94  ,MIN
95  };
96 
98  enum { NUM_SUMMARY_OPS = 6 };
99 
108  };
109 
111  static const char* flopCountsNames[NUM_OPS];
112 
115 
125  static unsigned int flopGranularity;
126 
129 
132 
135 
137  FlopCounts();
138 
140  void reset();
141 
143  void finalize();
144 
146  void increment(EFlopType ft);
147 
148  private:
149 
152 
154  unsigned int partialFlopCounts[NUM_OPS];
155 
158  };
159 
175  std::ostream& printCountersTable(const int n,
176  const char* names[],
177  const char* abbr[],
178  const FlopCounts counts[],
179  std::ostream &out);
180 
181  //
182  // Member macros
183  //
184 
186 #define SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN( OP, OP_NAME ) \
187  ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& s ) \
188  { \
189  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
190  val_ OP s.val(); \
191  return *this; \
192  }
193 
199  template<class T>
200  class ScalarFlopCounter : public Base< ScalarFlopCounter<T> > {
201  public:
202 
205 
208 
210  template <typename U>
211  struct apply {
213  };
214 
217 
219  static void resetCounters() { flopCounts_.reset(); }
220 
222  static void finalizeCounters() { flopCounts_.finalize(); }
223 
225  static FlopCounts getCounters() { return flopCounts_; }
226 
231  static std::ostream& printCounters( std::ostream &out ) {
232  const int n = 1;
233  const char* names[n] = { "Current" };
234  const char* abbr[n] = { "count" };
235  const FlopCounts counts[n] = { flopCounts_ };
236  return printCountersTable( n, &names[0], &abbr[0], &counts[0], out );
237  }
238 
240 
243 
246 
248  template <typename S>
250 
252  const T& val() const { return val_; }
253 
255  void val(const T& a) { val_ = a; }
256 
262 
264 
265  private:
266 
267  // Static members
269 
270  // Object members
272 
273  public:
274 
277 
283  static void incrCounter( const FlopCounts::EFlopType& ft ) {
285  }
286 
288  };
289 
290  // Static data members
291 
292  template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
293 
294  // ////////////////////////////////////////
295  // Nonmember operator function macros
296 
297 #define SCALAR_FLOP_COUNTER_BINARY_OP( OP, OP_NAME ) \
298  template<class T> \
299  ScalarFlopCounter<T> operator OP ( \
300  const Base< ScalarFlopCounter<T> >& aa, \
301  const Base< ScalarFlopCounter<T> >& bb ) \
302  { \
303  const ScalarFlopCounter<T>& a = aa.derived(); \
304  const ScalarFlopCounter<T>& b = bb.derived(); \
305  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
306  return ScalarFlopCounter<T>(a.val() OP b.val()); \
307  } \
308  template<class T> \
309  ScalarFlopCounter<T> operator OP ( \
310  const typename ScalarFlopCounter<T>::value_type& a, \
311  const Base< ScalarFlopCounter<T> >& bb ) \
312  { \
313  const ScalarFlopCounter<T>& b = bb.derived(); \
314  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
315  return ScalarFlopCounter<T>(a OP b.val()); \
316  } \
317  template<class T> \
318  ScalarFlopCounter<T> operator OP ( \
319  const int& a, \
320  const Base< ScalarFlopCounter<T> >& bb ) \
321  { \
322  const ScalarFlopCounter<T>& b = bb.derived(); \
323  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
324  return ScalarFlopCounter<T>(a OP b.val()); \
325  } \
326  template<class T> \
327  ScalarFlopCounter<T> operator OP ( \
328  const Base< ScalarFlopCounter<T> >& aa, \
329  const typename ScalarFlopCounter<T>::value_type& b ) \
330  { \
331  const ScalarFlopCounter<T>& a = aa.derived(); \
332  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
333  return ScalarFlopCounter<T>(a.val() OP b); \
334  } \
335  template<class T> \
336  ScalarFlopCounter<T> operator OP ( \
337  const Base< ScalarFlopCounter<T> >& aa, \
338  const int& b ) \
339  { \
340  const ScalarFlopCounter<T>& a = aa.derived(); \
341  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
342  return ScalarFlopCounter<T>(a.val() OP b); \
343  }
344 
345 #define SCALAR_FLOP_COUNTER_UNARY_OP( OP, OP_NAME ) \
346  template<class T> \
347  ScalarFlopCounter<T> operator OP ( \
348  const Base< ScalarFlopCounter<T> >& aa ) \
349  { \
350  const ScalarFlopCounter<T>& a = aa.derived(); \
351  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
352  return ScalarFlopCounter<T>( OP a.val() ); \
353  }
354 
355 #define SCALAR_FLOP_COUNTER_UNARY_FUNC( OP, OP_NAME ) \
356  template<class T> \
357  ScalarFlopCounter<T> OP( \
358  const Base< ScalarFlopCounter<T> >& aa ) \
359  { \
360  const ScalarFlopCounter<T>& a = aa.derived(); \
361  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
362  return ScalarFlopCounter<T>( std::OP( a.val() ) ); \
363  }
364 
365 #define SCALAR_FLOP_COUNTER_BINARY_FUNC( OP, OP_NAME ) \
366  template<class T> \
367  ScalarFlopCounter<T> OP ( \
368  const Base< ScalarFlopCounter<T> >& aa, \
369  const Base< ScalarFlopCounter<T> >& bb ) \
370  { \
371  const ScalarFlopCounter<T>& a = aa.derived(); \
372  const ScalarFlopCounter<T>& b = bb.derived(); \
373  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
374  return ScalarFlopCounter<T>( std::OP( a.val(), b.val() ) ); \
375  } \
376  template<class T> \
377  ScalarFlopCounter<T> OP ( \
378  const typename ScalarFlopCounter<T>::value_type& a, \
379  const Base< ScalarFlopCounter<T> >& bb ) \
380  { \
381  const ScalarFlopCounter<T>& b = bb.derived(); \
382  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
383  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
384  } \
385  template<class T> \
386  ScalarFlopCounter<T> OP ( \
387  const int& a, \
388  const Base< ScalarFlopCounter<T> >& bb ) \
389  { \
390  const ScalarFlopCounter<T>& b = bb.derived(); \
391  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
392  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
393  } \
394  template<class T> \
395  ScalarFlopCounter<T> OP ( \
396  const Base< ScalarFlopCounter<T> >& aa, \
397  const typename ScalarFlopCounter<T>::value_type& b ) \
398  { \
399  const ScalarFlopCounter<T>& a = aa.derived(); \
400  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
401  return ScalarFlopCounter<T>( std::OP( a.val(), b ) ); \
402  } \
403  template<class T> \
404  ScalarFlopCounter<T> OP ( \
405  const Base< ScalarFlopCounter<T> >& aa, \
406  const int& b ) \
407  { \
408  const ScalarFlopCounter<T>& a = aa.derived(); \
409  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
410  return ScalarFlopCounter<T>( std::OP(a.val(), b ) ); \
411  }
412 
413 #define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP( OP, OP_NAME ) \
414  template<class T> \
415  bool operator OP ( \
416  const Base< ScalarFlopCounter<T> >& aa, \
417  const Base< ScalarFlopCounter<T> >& bb ) \
418  { \
419  const ScalarFlopCounter<T>& a = aa.derived(); \
420  const ScalarFlopCounter<T>& b = bb.derived(); \
421  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
422  return (a.val() OP b.val()); \
423  } \
424  template<class T> \
425  bool operator OP ( \
426  const typename ScalarFlopCounter<T>::value_type& a, \
427  const Base< ScalarFlopCounter<T> >& bb ) \
428  { \
429  const ScalarFlopCounter<T>& b = bb.derived(); \
430  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
431  return (a OP b.val()); \
432  } \
433  template<class T> \
434  bool operator OP ( \
435  const Base< ScalarFlopCounter<T> >& aa, \
436  const typename ScalarFlopCounter<T>::value_type& b ) \
437  { \
438  const ScalarFlopCounter<T>& a = aa.derived(); \
439  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
440  return (a.val() OP b); \
441  }
442 
443  // ////////////////////////////////////////////
444  // Nonmember operator and other functions
445 
446  // Binary operations
448  SCALAR_FLOP_COUNTER_BINARY_OP(-,FlopCounts::MINUS)
449  SCALAR_FLOP_COUNTER_BINARY_OP(*,FlopCounts::MULTIPLY)
450  SCALAR_FLOP_COUNTER_BINARY_OP(/,FlopCounts::DIVIDE)
451 
452  // Unary operations
453  SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
454  SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
455 
456  // Unary functions
457  SCALAR_FLOP_COUNTER_UNARY_FUNC(exp,FlopCounts::EXP)
458  SCALAR_FLOP_COUNTER_UNARY_FUNC(log,FlopCounts::LOG)
459  SCALAR_FLOP_COUNTER_UNARY_FUNC(log10,FlopCounts::LOG10)
460  SCALAR_FLOP_COUNTER_UNARY_FUNC(sqrt,FlopCounts::SQRT)
461 #ifdef HAVE_SACADO_CXX11
462  SCALAR_FLOP_COUNTER_UNARY_FUNC(cbrt,FlopCounts::CBRT)
463 #endif
465  SCALAR_FLOP_COUNTER_UNARY_FUNC(sin,FlopCounts::SIN)
466  SCALAR_FLOP_COUNTER_UNARY_FUNC(tan,FlopCounts::TAN)
467  SCALAR_FLOP_COUNTER_UNARY_FUNC(acos,FlopCounts::ACOS)
468  SCALAR_FLOP_COUNTER_UNARY_FUNC(asin,FlopCounts::ASIN)
469  SCALAR_FLOP_COUNTER_UNARY_FUNC(atan,FlopCounts::ATAN)
470  SCALAR_FLOP_COUNTER_UNARY_FUNC(cosh,FlopCounts::COSH)
471  SCALAR_FLOP_COUNTER_UNARY_FUNC(sinh,FlopCounts::SINH)
472  SCALAR_FLOP_COUNTER_UNARY_FUNC(tanh,FlopCounts::TANH)
473  SCALAR_FLOP_COUNTER_UNARY_FUNC(abs,FlopCounts::ABS)
474  SCALAR_FLOP_COUNTER_UNARY_FUNC(fabs,FlopCounts::ABS)
475 
476  // Binary functions
477  SCALAR_FLOP_COUNTER_BINARY_FUNC(atan2,FlopCounts::ATAN2)
478  SCALAR_FLOP_COUNTER_BINARY_FUNC(pow,FlopCounts::POW)
479  SCALAR_FLOP_COUNTER_BINARY_FUNC(max,FlopCounts::MAX)
480  SCALAR_FLOP_COUNTER_BINARY_FUNC(min,FlopCounts::MIN)
481 
482  // Comparison
483  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>,FlopCounts::GREATER_THAN)
484  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>=,FlopCounts::GREATER_THAN_EQUAL)
485  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<,FlopCounts::LESS_THAN)
486  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<=,FlopCounts::LESS_THAN_EQUAL)
487  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(==,FlopCounts::EQUAL)
488 
489  } // namespace FlopCounterPack
490 } // namespace Sacado
491 
492 #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
KOKKOS_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)
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)
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)