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 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef SACADO_SCALAR_FLOP_COUNTER_HPP
11 #define SACADO_SCALAR_FLOP_COUNTER_HPP
12 
13 #include "Sacado_ConfigDefs.h"
15 #include "Sacado_Base.hpp"
16 #include "Sacado_SFINAE_Macros.hpp"
17 #include <cmath>
18 #include <algorithm> // for std::min and std::max
19 #include <ostream> // for std::ostream
20 
21 namespace Sacado {
22 
23  namespace FlopCounterPack {
24 
26  class FlopCounts {
27  public:
28 
30  enum { NUM_OPS = 35 };
31 
33  enum EFlopType {
50  ,EXP
51  ,LOG
55  ,COS
56  ,SIN
57  ,TAN
65  ,ABS
66  ,POW
67  ,MAX
68  ,MIN
69  };
70 
72  enum { NUM_SUMMARY_OPS = 6 };
73 
82  };
83 
85  static const char* flopCountsNames[NUM_OPS];
86 
89 
99  static unsigned int flopGranularity;
100 
103 
106 
109 
111  FlopCounts();
112 
114  void reset();
115 
117  void finalize();
118 
120  void increment(EFlopType ft);
121 
122  private:
123 
126 
128  unsigned int partialFlopCounts[NUM_OPS];
129 
132  };
133 
149  std::ostream& printCountersTable(const int n,
150  const char* names[],
151  const char* abbr[],
152  const FlopCounts counts[],
153  std::ostream &out);
154 
155  //
156  // Member macros
157  //
158 
160 #define SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN( OP, OP_NAME ) \
161  ScalarFlopCounter<T> operator OP ( const ScalarFlopCounter<T>& s ) \
162  { \
163  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
164  val_ OP s.val(); \
165  return *this; \
166  }
167 
173  template<class T>
174  class ScalarFlopCounter : public Base< ScalarFlopCounter<T> > {
175  public:
176 
179 
182 
184  template <typename U>
185  struct apply {
187  };
188 
191 
193  static void resetCounters() { flopCounts_.reset(); }
194 
196  static void finalizeCounters() { flopCounts_.finalize(); }
197 
199  static FlopCounts getCounters() { return flopCounts_; }
200 
205  static std::ostream& printCounters( std::ostream &out ) {
206  const int n = 1;
207  const char* names[n] = { "Current" };
208  const char* abbr[n] = { "count" };
209  const FlopCounts counts[n] = { flopCounts_ };
210  return printCountersTable( n, &names[0], &abbr[0], &counts[0], out );
211  }
212 
214 
217 
220 
222  template <typename S>
224 
226  const T& val() const { return val_; }
227 
229  void val(const T& a) { val_ = a; }
230 
236 
238 
239  private:
240 
241  // Static members
243 
244  // Object members
246 
247  public:
248 
251 
257  static void incrCounter( const FlopCounts::EFlopType& ft ) {
259  }
260 
262  };
263 
264  // Static data members
265 
266  template<class T> FlopCounts ScalarFlopCounter<T>::flopCounts_;
267 
268  // ////////////////////////////////////////
269  // Nonmember operator function macros
270 
271 #define SCALAR_FLOP_COUNTER_BINARY_OP( OP, OP_NAME ) \
272  template<class T> \
273  ScalarFlopCounter<T> operator OP ( \
274  const Base< ScalarFlopCounter<T> >& aa, \
275  const Base< ScalarFlopCounter<T> >& bb ) \
276  { \
277  const ScalarFlopCounter<T>& a = aa.derived(); \
278  const ScalarFlopCounter<T>& b = bb.derived(); \
279  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
280  return ScalarFlopCounter<T>(a.val() OP b.val()); \
281  } \
282  template<class T> \
283  ScalarFlopCounter<T> operator OP ( \
284  const typename ScalarFlopCounter<T>::value_type& a, \
285  const Base< ScalarFlopCounter<T> >& bb ) \
286  { \
287  const ScalarFlopCounter<T>& b = bb.derived(); \
288  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
289  return ScalarFlopCounter<T>(a OP b.val()); \
290  } \
291  template<class T> \
292  ScalarFlopCounter<T> operator OP ( \
293  const int& a, \
294  const Base< ScalarFlopCounter<T> >& bb ) \
295  { \
296  const ScalarFlopCounter<T>& b = bb.derived(); \
297  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
298  return ScalarFlopCounter<T>(a OP b.val()); \
299  } \
300  template<class T> \
301  ScalarFlopCounter<T> operator OP ( \
302  const Base< ScalarFlopCounter<T> >& aa, \
303  const typename ScalarFlopCounter<T>::value_type& b ) \
304  { \
305  const ScalarFlopCounter<T>& a = aa.derived(); \
306  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
307  return ScalarFlopCounter<T>(a.val() OP b); \
308  } \
309  template<class T> \
310  ScalarFlopCounter<T> operator OP ( \
311  const Base< ScalarFlopCounter<T> >& aa, \
312  const int& b ) \
313  { \
314  const ScalarFlopCounter<T>& a = aa.derived(); \
315  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
316  return ScalarFlopCounter<T>(a.val() OP b); \
317  }
318 
319 #define SCALAR_FLOP_COUNTER_UNARY_OP( OP, OP_NAME ) \
320  template<class T> \
321  ScalarFlopCounter<T> operator OP ( \
322  const Base< ScalarFlopCounter<T> >& aa ) \
323  { \
324  const ScalarFlopCounter<T>& a = aa.derived(); \
325  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
326  return ScalarFlopCounter<T>( OP a.val() ); \
327  }
328 
329 #define SCALAR_FLOP_COUNTER_UNARY_FUNC( OP, OP_NAME ) \
330  template<class T> \
331  ScalarFlopCounter<T> OP( \
332  const Base< ScalarFlopCounter<T> >& aa ) \
333  { \
334  const ScalarFlopCounter<T>& a = aa.derived(); \
335  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
336  return ScalarFlopCounter<T>( std::OP( a.val() ) ); \
337  }
338 
339 #define SCALAR_FLOP_COUNTER_BINARY_FUNC( OP, OP_NAME ) \
340  template<class T> \
341  ScalarFlopCounter<T> OP ( \
342  const Base< ScalarFlopCounter<T> >& aa, \
343  const Base< ScalarFlopCounter<T> >& bb ) \
344  { \
345  const ScalarFlopCounter<T>& a = aa.derived(); \
346  const ScalarFlopCounter<T>& b = bb.derived(); \
347  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
348  return ScalarFlopCounter<T>( std::OP( a.val(), b.val() ) ); \
349  } \
350  template<class T> \
351  ScalarFlopCounter<T> OP ( \
352  const typename ScalarFlopCounter<T>::value_type& a, \
353  const Base< ScalarFlopCounter<T> >& bb ) \
354  { \
355  const ScalarFlopCounter<T>& b = bb.derived(); \
356  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
357  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
358  } \
359  template<class T> \
360  ScalarFlopCounter<T> OP ( \
361  const int& a, \
362  const Base< ScalarFlopCounter<T> >& bb ) \
363  { \
364  const ScalarFlopCounter<T>& b = bb.derived(); \
365  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
366  return ScalarFlopCounter<T>( std::OP( a, b.val() ) ); \
367  } \
368  template<class T> \
369  ScalarFlopCounter<T> OP ( \
370  const Base< ScalarFlopCounter<T> >& aa, \
371  const typename ScalarFlopCounter<T>::value_type& b ) \
372  { \
373  const ScalarFlopCounter<T>& a = aa.derived(); \
374  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
375  return ScalarFlopCounter<T>( std::OP( a.val(), b ) ); \
376  } \
377  template<class T> \
378  ScalarFlopCounter<T> OP ( \
379  const Base< ScalarFlopCounter<T> >& aa, \
380  const int& b ) \
381  { \
382  const ScalarFlopCounter<T>& a = aa.derived(); \
383  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
384  return ScalarFlopCounter<T>( std::OP(a.val(), b ) ); \
385  }
386 
387 #define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP( OP, OP_NAME ) \
388  template<class T> \
389  bool operator OP ( \
390  const Base< ScalarFlopCounter<T> >& aa, \
391  const Base< ScalarFlopCounter<T> >& bb ) \
392  { \
393  const ScalarFlopCounter<T>& a = aa.derived(); \
394  const ScalarFlopCounter<T>& b = bb.derived(); \
395  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
396  return (a.val() OP b.val()); \
397  } \
398  template<class T> \
399  bool operator OP ( \
400  const typename ScalarFlopCounter<T>::value_type& a, \
401  const Base< ScalarFlopCounter<T> >& bb ) \
402  { \
403  const ScalarFlopCounter<T>& b = bb.derived(); \
404  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
405  return (a OP b.val()); \
406  } \
407  template<class T> \
408  bool operator OP ( \
409  const Base< ScalarFlopCounter<T> >& aa, \
410  const typename ScalarFlopCounter<T>::value_type& b ) \
411  { \
412  const ScalarFlopCounter<T>& a = aa.derived(); \
413  ScalarFlopCounter<T>::incrCounter(OP_NAME); \
414  return (a.val() OP b); \
415  }
416 
417  // ////////////////////////////////////////////
418  // Nonmember operator and other functions
419 
420  // Binary operations
422  SCALAR_FLOP_COUNTER_BINARY_OP(-,FlopCounts::MINUS)
423  SCALAR_FLOP_COUNTER_BINARY_OP(*,FlopCounts::MULTIPLY)
424  SCALAR_FLOP_COUNTER_BINARY_OP(/,FlopCounts::DIVIDE)
425 
426  // Unary operations
427  SCALAR_FLOP_COUNTER_UNARY_OP(+,FlopCounts::UNARY_PLUS)
428  SCALAR_FLOP_COUNTER_UNARY_OP(-,FlopCounts::UNARY_MINUS)
429 
430  // Unary functions
431  SCALAR_FLOP_COUNTER_UNARY_FUNC(exp,FlopCounts::EXP)
432  SCALAR_FLOP_COUNTER_UNARY_FUNC(log,FlopCounts::LOG)
433  SCALAR_FLOP_COUNTER_UNARY_FUNC(log10,FlopCounts::LOG10)
434  SCALAR_FLOP_COUNTER_UNARY_FUNC(sqrt,FlopCounts::SQRT)
435  SCALAR_FLOP_COUNTER_UNARY_FUNC(cbrt,FlopCounts::CBRT)
436  SCALAR_FLOP_COUNTER_UNARY_FUNC(cos,FlopCounts::COS)
437  SCALAR_FLOP_COUNTER_UNARY_FUNC(sin,FlopCounts::SIN)
438  SCALAR_FLOP_COUNTER_UNARY_FUNC(tan,FlopCounts::TAN)
439  SCALAR_FLOP_COUNTER_UNARY_FUNC(acos,FlopCounts::ACOS)
440  SCALAR_FLOP_COUNTER_UNARY_FUNC(asin,FlopCounts::ASIN)
441  SCALAR_FLOP_COUNTER_UNARY_FUNC(atan,FlopCounts::ATAN)
442  SCALAR_FLOP_COUNTER_UNARY_FUNC(cosh,FlopCounts::COSH)
443  SCALAR_FLOP_COUNTER_UNARY_FUNC(sinh,FlopCounts::SINH)
444  SCALAR_FLOP_COUNTER_UNARY_FUNC(tanh,FlopCounts::TANH)
445  SCALAR_FLOP_COUNTER_UNARY_FUNC(abs,FlopCounts::ABS)
446  SCALAR_FLOP_COUNTER_UNARY_FUNC(fabs,FlopCounts::ABS)
447 
448  // Binary functions
449  SCALAR_FLOP_COUNTER_BINARY_FUNC(atan2,FlopCounts::ATAN2)
450  SCALAR_FLOP_COUNTER_BINARY_FUNC(pow,FlopCounts::POW)
451  SCALAR_FLOP_COUNTER_BINARY_FUNC(max,FlopCounts::MAX)
452  SCALAR_FLOP_COUNTER_BINARY_FUNC(min,FlopCounts::MIN)
453 
454  // Comparison
455  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>,FlopCounts::GREATER_THAN)
456  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(>=,FlopCounts::GREATER_THAN_EQUAL)
457  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<,FlopCounts::LESS_THAN)
458  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(<=,FlopCounts::LESS_THAN_EQUAL)
459  SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(==,FlopCounts::EQUAL)
460 
461  } // namespace FlopCounterPack
462 } // namespace Sacado
463 
464 #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:26
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:553
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)