Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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"
37#include <cmath>
38#include <algorithm> // for std::min and std::max
39#include <ostream> // for std::ostream
40
41namespace Sacado {
42
43 namespace FlopCounterPack {
44
46 class FlopCounts {
47 public:
48
49#ifdef HAVE_SACADO_CXX11
51 enum { NUM_OPS = 35 };
52#else
54 enum { NUM_OPS = 34 };
55#endif
57 enum EFlopType {
58 ASSIGN
78#ifdef HAVE_SACADO_CXX11
79 ,CBRT
80#endif
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
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
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
451
452 // Unary operations
455
456 // Unary functions
461#ifdef HAVE_SACADO_CXX11
462 SCALAR_FLOP_COUNTER_UNARY_FUNC(cbrt,FlopCounts::CBRT)
463#endif
475
476 // Binary functions
481
482 // Comparison
488
489 } // namespace FlopCounterPack
490} // namespace Sacado
491
492#endif // SACADO_SCALAR_FLOP_COUNTER_HPP
#define SACADO_ENABLE_VALUE_CTOR_DECL
#define SCALAR_FLOP_COUNTER_BINARY_OP(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_UNARY_FUNC(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_UNARY_OP(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_BINARY_FUNC(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(OP, OP_NAME)
#define SCALAR_FLOP_COUNTER_BINARY_COMPARISON_OP(OP, OP_NAME)
#define T
Definition: Sacado_rad.hpp:573
Class storing flop counts and summary flop counts.
static unsigned int flopGranularity
The number of flops to accumulate as an integer before converting to a double.
double flopCounts[NUM_OPS]
Individual flop counts.
void reset()
Reset flop counters before starting a block of computations. *‍/.
void increment(EFlopType ft)
Increment an individual flop counter.
double summaryFlopCounts[NUM_SUMMARY_OPS]
Summary category flop counts.
static const char * summaryFlopCountsNames[NUM_SUMMARY_OPS]
Names for summary operation categories.
unsigned int partialFlopCounts[NUM_OPS]
Partial sum of individual flop counts.
ESummaryFlopType getSummaryType(EFlopType ft)
Get summary op enum from op enum.
unsigned int partialSummaryFlopCounts[NUM_SUMMARY_OPS]
Partial sum of summary category flop counts.
static const char * flopCountsNames[NUM_OPS]
Names of individual flops.
ESummaryFlopType
Enum of summary operation categories.
ScalarType< value_type >::type scalar_type
Typename of scalar's (which may be different from T)
SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(-=, FlopCounts::MINUS_ASSIGN)
RemoveConst< T >::type value_type
Typename of values.
static std::ostream & printCounters(std::ostream &out)
Print the current static flop counts to out.
SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(/=, FlopCounts::DIVIDE_ASSIGN)
static void incrCounter(const FlopCounts::EFlopType &ft)
Increment an individual flop counter.
static FlopCounts getCounters()
Get the flop counts after a block of computations.
void val(const T &a)
Set the current value.
SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(=, FlopCounts::ASSIGN)
SCALAR_FLOP_COUNTER_BINARY_OP_ASSIGN(+=, FlopCounts::PLUS_ASSIGN)
static void resetCounters()
Reset static flop counters before starting a block of computations.
const T & val() const
Return the current value.
static void finalizeCounters()
Finalize total flop count after block of computations.
ScalarFlopCounter(const S &v, SACADO_ENABLE_VALUE_CTOR_DECL)
Construct to scalar 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.
Base class for Sacado types to control overload resolution.
Definition: Sacado_Base.hpp:46
Turn ScalarFlopCounter into a meta-function class usable with mpl::apply.