MPQC  3.0.0-alpha
profile.hpp
1 #ifndef MPQC_PROFILE_HPP
2 #define MPQC_PROFILE_HPP
3 
4 // #include "boost/utility/timer.hpp"
5 
6 #include "boost/date_time/posix_time/posix_time_types.hpp"
7 
8 #include <string>
9 #include <sstream>
10 #include <map>
11 #include <typeinfo>
12 
13 #include <boost/thread/thread.hpp>
14 #include <boost/thread/mutex.hpp>
15 #include <boost/preprocessor/cat.hpp>
16 #include <boost/preprocessor/stringize.hpp>
17 #include <boost/typeof/typeof.hpp>
18 
49 #ifndef DOXYGEN
50 
51 #define MPQC_PROFILE__(tag) BOOST_PP_CAT(boost_profile__, tag)
52 
53 #ifdef MPQC_PROFILE_ENABLE
54 #define MPQC_PROFILE_FUNCTION(...) \
55  mpqc::profiler::event MPQC_PROFILE__(__LINE__) \
56  (mpqc::global_profiler() \
57  [mpqc::detail::profiler_event \
58  (__PRETTY_FUNCTION__)(__VA_ARGS__)])
59 
60 #define MPQC_PROFILE_TYPE(T, ...) \
61  mpqc::profiler::event MPQC_PROFILE__(__LINE__) \
62  (mpqc::global_profiler() \
63  [mpqc::detail::profiler_event \
64  (typeid(T).name())(__VA_ARGS__)])
65 
66 #define MPQC_PROFILE(...) \
67  mpqc::profiler::event MPQC_PROFILE__(__LINE__) \
68  (mpqc::global_profiler() \
69  [mpqc::detail::profiler_event(__VA_ARGS__)])
70 
71 #define MPQC_PROFILE_LINE \
72  mpqc::profiler::event MPQC_PROFILE__(__LINE__) \
73  (mpqc::global_profiler() \
74  [mpqc::detail::profiler_event(std::string(__FILE__) + ":" + \
75  (BOOST_PP_STRINGIZE(__LINE__)))])
76 
77 #define MPQC_PROFILE_REGISTER_THREAD \
78  mpqc::global_profiler().register_thread()
79 
80 #else
81 #define MPQC_PROFILE_FUNCTION(...)
82 #define MPQC_PROFILE_TYPE(T, ...)
83 #define MPQC_PROFILE_LINE
84 #define MPQC_PROFILE(...)
85 #define MPQC_PROFILE_REGISTER_THREAD
86 #endif
87 
88 #define MPQC_PROFILE_DUMP(stream) \
89  mpqc::global_profiler().dump((stream))
90 
91 #define MPQC_PROFILE_RESET \
92  mpqc::global_profiler().clear()
93 
94 namespace mpqc {
95 namespace detail {
96 
97  struct profiler_event {
98  profiler_event(const std::string &key) : data_(key) {}
99  operator const std::string&() const { return data_; }
100  profiler_event& operator()(const std::string &key) {
101  data_ += (":" + key);
102  return *this;
103  }
104  profiler_event& operator()() { return *this; }
105  private:
106  std::string data_;
107  };
108 
109  template<class>
110  struct profiler {
111 
112  typedef std::string event_key;
113 
114  struct event_data {
115  event_data(): size_(0), value_(0) {}
116  event_data(const event_data &e)
117  : size_(e.size_), value_(e.value_) {}
118  event_data& operator+=(double t) {
119  ++size_;
120  value_ += t;
121  return *this;
122  }
123  event_data& operator++() { return (*this += 1); }
124  template<class O>
125  O& to_stream(O &ostream) const {
126  ostream << value_ << "/" << size_;
127  return ostream;
128  }
129  private:
130  size_t size_;
131  double value_;
132  };
133 
134  struct event {
135  event(event_data *data)
136  : data_(data),
137  start_(microsec_clock::universal_time()) {}
138  ~event() {
139  boost::posix_time::time_duration t =
140  (microsec_clock::universal_time() - start_);
141  // std::cout << timer_ << std::endl;
142  if (data_) {
143  *data_ += t.total_microseconds()/1.0e6;
144  }
145  }
146  private:
147  typedef boost::posix_time::microsec_clock microsec_clock;
148  event_data *data_;
149  boost::posix_time::ptime start_;
150  // utility::timer timer_;
151  };
152 
153  void register_thread() {
154  boost::lock_guard<boost::mutex> lock(mutex_);
155  //std::cout << "register thread " << thread();
156  events_[thread()];
157  }
158 
159  event_data* operator[](const event_key &key) {
160  //std::cout << key << std::endl;
161  std::string thread = this->thread();
162  boost::lock_guard<boost::mutex> lock(mutex_);
163  if (events_.find(thread) == events_.end()) return NULL;
164  //std::cout << thread << ": " << key << std::endl;
165  return &events_[thread][key];
166  }
167 
168  void clear() {
169  boost::lock_guard<boost::mutex> lock(mutex_);
170  BOOST_AUTO(it, events_.begin());
171  while (it != events_.end()) {
172  it++->second.clear();
173  }
174  }
175 
176  template<class S>
177  S& to_stream(S &ostream) const {
178  boost::lock_guard<boost::mutex> lock(mutex_);
179  typedef std::map<event_key, event_data> events_t;
180  typename std::map<std::string, events_t>::const_iterator
181  e = events_.begin();
182  //std::cout << events_.size() << std::endl;
183  while (e != events_.end()) {
184  ostream << "Thread " << e->first << ":" << std::endl;
185  typename events_t::const_iterator it = e->second.begin();
186  while (it != e->second.end()) {
187  ostream << " " << it->first << ": ";
188  it->second.to_stream(ostream);
189  ostream << std::endl;
190  ++it;
191  }
192  ++e;
193  }
194  return ostream;
195  }
196 
197  template<class S>
198  void dump(S &stream) {
199  this->to_stream(stream);
200  clear();
201  }
202 
203  private:
204  mutable boost::mutex mutex_;
205  std::map<
206  std::string, std::map<event_key, event_data>
207  > events_;
208 
209  static std::string thread() {
210  std::stringstream ss;
211  ss << boost::this_thread::get_id();
212  return ss.str();
213  }
214  };
215 
216  // template<typename T>
217  // profiler<T> profiler<T>::global;
218 
219  template<typename T>
220  inline std::ostream& operator<<(std::ostream &ostream, const profiler<T> &p) {
221  return p.to_stream(ostream);
222  }
223 
224 } // namespace detail
225 } // namespace mpqc
226 
227 
228 namespace mpqc {
229 
230  typedef detail::profiler<void> profiler;
231  inline profiler& global_profiler() {
232  static profiler p;
233  return p;
234  }
235 
236 }
237 
238 #endif // DOXYGEN
239 
240 #endif // MPQC_PROFILE_HPP
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
sc::map
std::vector< int > map(const GaussianBasisSet &B, const GaussianBasisSet &A)
same as operator<<, except A does not have to be contained in B, map[a] = -1 if function a is not in ...
mpqc::operator<<
void operator<<(Array< T > A, const V &v)
Write to Array from a generic vector V.
Definition: array.hpp:191

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.