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
19namespace Dune {
20
21 namespace Fem {
22
23 // FlopCounter
24 // -----------
25
33 {
34 typedef std::vector< float > values_t ;
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
56 : values_( values_t(3, float(0.0)) ),
57 stopped_( 0 )
58 {
59 }
60
61 static unsigned long threadId ()
62 {
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
double max(const Dune::Fem::Double &v, const double p)
Definition: double.hh:965
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 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