MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
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
94namespace mpqc {
95namespace 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
228namespace 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
void operator<<(Array< T > A, const V &v)
Write to Array from a generic vector V.
Definition array.hpp:191
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37

Generated at Wed Sep 25 2024 02:45:30 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.