dune-fem  2.8-git
flops.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_FLOPS_HH
2 #define DUNE_FEM_FLOPS_HH
3 
4 #if HAVE_PAPI
5 #include <papi.h>
6 #endif
7 
8 //- system includes
9 #include <iostream>
10 #include <vector>
11 #include <cassert>
12 
13 //- dune-fem includes
18 
19 namespace Dune {
20 
21  namespace Fem {
22 
23  // FlopCounter
24  // -----------
25 
33  {
34  typedef std::vector< float > values_t ;
37  ThreadSafeValue< int > stopped_;
38 
39  // call PAPI_flops for given values
40  void evaluateCounters( float& realTime,
41  float& procTime,
42  float& mFlops,
43  long long& flop )
44  {
45 #if HAVE_PAPI
46  int retval = PAPI_flops(&realTime, &procTime, &flop, &mFlops);
47  if( retval < PAPI_OK )
48  {
49  std::cerr << "ERROR: PAPI_FP_OPS event is not available, check papi_avail!" << std::endl;
50  }
51 #endif
52  }
53 
54  // constructor
55  FlopCounter ()
56  : values_( values_t(3, float(0.0)) ),
57  stopped_( 0 )
58  {
59  }
60 
61  static unsigned long threadId ()
62  {
63  return ThreadManager :: thread();
64  }
65 
66  // initialize counters
67  void startCounter()
68  {
70  {
71 #if HAVE_PAPI
72  PAPI_thread_init( threadId );
73  PAPI_register_thread();
74 #endif
75  }
76  float realtime, proctime, mflops;
77  long long flop ;
78  evaluateCounters( realtime, proctime, mflops, flop );
79  // mark as not stopped
80  *stopped_ = 0;
81  }
82 
83  // stop counters and store values
84  void stopCounter()
85  {
86  if( *stopped_ == 0 )
87  {
88  // get reference to thread local value
89  values_t& values = *values_;
90  long long& flop = *flop_;
91  evaluateCounters( values[ 0 ], values[ 1 ], values[ 2 ], flop );
92 
93  // mark thread as stopped
94  *stopped_ = 1 ;
95  }
96  }
97 
98  // print values to given ostream, all values are gathered to
99  // the master rank
100  void printCounter( std::ostream& out ) const
101  {
102  // make sure this method is called in single thread mode only
104 
105  int allStopped = 0 ;
106  const int threads = ThreadManager :: maxThreads ();
107  for( int i=0; i<threads; ++i )
108  {
109  allStopped += stopped_[ i ];
110  }
111 
112  // make sure all other thread have been stopped, otherwise
113  // the results wont be coorect
114  if( allStopped != threads )
115  DUNE_THROW(InvalidStateException,"Not all thread have been stopped");
116 
117  typedef std::vector< double > result_t ;
118  result_t values( 5, 0.0 );
119 
120  for( int i=0; i<3; ++i )
121  values[ i ] = values_[ 0 ][ i ];
122  values[ 3 ] = flop_[ 0 ];
123 
124  // tkae maximum for times and sum flops for all threads
125  for( int i=1; i<threads; ++i )
126  {
127  values[ 0 ] = std::max( values[ 0 ], double(values_[ i ][ 0 ]) );
128  values[ 1 ] = std::max( values[ 1 ], double(values_[ i ][ 1 ]) );
129  values[ 2 ] += values_[ i ][ 2 ];
130  values[ 3 ] += flop_[ i ];
131  }
132  // convert to GFLOP
133  values[ 3 ] /= 1.0e9 ;
134  // compute mflops ourselfs
135  values[ 4 ] = values[ 3 ] / values[ 0 ];
136 
137  result_t max( values );
138  result_t min( values );
139  result_t sum( values );
140 
141  typedef MPIManager :: CollectiveCommunication CollectiveCommunication;
142  const CollectiveCommunication& comm = MPIManager :: comm();
143 
144  const int size = max.size();
145  // compute max, min, and sum of flop values
146  comm.max( &max[ 0 ], size );
147  comm.min( &min[ 0 ], size );
148  comm.sum( &sum[ 0 ], size );
149 
150  if( comm.rank() == 0 )
151  {
152  out << "FlopCounter::typ: real proc mflops flop flop/real " << std::endl;
153  printValues( out, "FlopCounter::sum: ", sum );
154  printValues( out, "FlopCounter::max: ", max );
155  printValues( out, "FlopCounter::min: ", min );
156  }
157  }
158 
159  friend class Dune::Fem::Singleton< FlopCounter >;
160 
161  static FlopCounter& instance()
162  {
164  }
165 
166  public:
172  static void start( )
173  {
174  instance().startCounter();
175  }
176 
178  static void stop( )
179  {
180  instance().stopCounter();
181  }
182 
186  static void print( std::ostream& out )
187  {
188  instance().printCounter( out );
189  }
190 
191  protected:
192  template <class vec_t>
193  void printValues( std::ostream& out, const std::string name, const vec_t& values ) const
194  {
195  out << name << " ";
196  for( unsigned int i=0; i<values.size(); ++i )
197  {
198  out << values[ i ] << " ";
199  }
200  out << std::endl;
201  }
202  };
203 
204  } // namespace Fem
205 } // namespace Dune
206 #endif
Definition: bindguard.hh:11
static double min(const Double &v, const double p)
Definition: double.hh:386
static double max(const Double &v, const double p)
Definition: double.hh:398
static constexpr T max(T a)
Definition: utility.hh:77
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
A class wrapper for the function PAPI_flops from the package PAPI. The results are CPU time,...
Definition: flops.hh:33
static void start()
Start counters.
Definition: flops.hh:172
static void print(std::ostream &out)
print values to given ostream, all values are gathered to the master rank before printing
Definition: flops.hh:186
void printValues(std::ostream &out, const std::string name, const vec_t &values) const
Definition: flops.hh:193
static void stop()
stop counters
Definition: flops.hh:178
static const CollectiveCommunication & comm()
Definition: mpimanager.hh:147
Dune::CollectiveCommunication< MPIHelper::MPICommunicator > CollectiveCommunication
Definition: mpimanager.hh:26
static int maxThreads()
return maximal number of threads possbile in the current run
Definition: threadmanager.hh:59
static bool singleThreadMode()
returns true if program is operating on one thread currently
Definition: threadmanager.hh:74
static int thread()
return thread number
Definition: threadmanager.hh:65
return singleton instance of given Object type.
Definition: singleton.hh:71
static Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:101