omega_h
Reliable mesh adaptation
Omega_h_profile.hpp
1 #ifndef OMEGA_H_STACK_HPP
2 #define OMEGA_H_STACK_HPP
3 
4 #include <Omega_h_timer.hpp>
5 #include <Omega_h_filesystem.hpp>
6 #include <cstring>
7 #include <vector>
8 #include <memory>
9 #ifdef OMEGA_H_USE_KOKKOS
10 #include <Omega_h_kokkos.hpp>
11 #endif
12 
13 namespace Omega_h {
14 
15 class Comm;
16 typedef std::shared_ptr<Comm> CommPtr;
17 
18 namespace profile {
19 
20 struct Strings {
21  std::vector<char> chars;
22  std::size_t save(char const* str) {
23  auto ret = chars.size();
24  while (true) {
25  chars.push_back(*str);
26  if (*str == '\0') break;
27  ++str;
28  }
29  return ret;
30  }
31  char const* get(std::size_t i) const { return &chars[i]; }
32 };
33 
34 static constexpr std::size_t invalid = std::numeric_limits<std::size_t>::max();
35 
36 struct Frame {
37  std::size_t parent;
38  std::size_t first_child;
39  std::size_t last_child;
40  std::size_t next_sibling;
41  std::size_t name_ptr;
42  Now start_time;
43  double total_runtime;
44  std::size_t number_of_calls;
45 };
46 
47 struct History {
48  std::vector<Frame> frames;
49  std::size_t current_frame;
50  std::size_t last_root;
51  Strings names;
52  Now start_time;
53  bool do_percent;
54  double chop;
55  bool add_filename;
56  CommPtr comm;
57  History(CommPtr comm = nullptr, bool dopercent=false, double chop=0.0, bool add_filename=false);
58  History(const History& h);
59  inline const char* get_name(std::size_t frame) const {
60  return names.get(frames[frame].name_ptr);
61  }
62  inline std::size_t find_child_of(
63  std::size_t parent_index, char const* name) const {
64  if (parent_index == invalid) return find_root(name);
65  for (std::size_t child = frames[parent_index].first_child; child != invalid;
66  child = frames[child].next_sibling) {
67  if (0 == std::strcmp(get_name(child), name)) {
68  return child;
69  }
70  }
71  return invalid;
72  }
73  inline std::size_t create_child_of(
74  std::size_t parent_index, char const* name) {
75  if (parent_index == invalid) return create_root(name);
76  auto index = frames.size();
77  frames.push_back(Frame());
78  auto& frame = frames.back();
79  auto& parent_frame = frames[parent_index];
80  frame.parent = parent_index;
81  frame.first_child = invalid;
82  frame.last_child = invalid;
83  auto old_last = parent_frame.last_child;
84  if (old_last != invalid) {
85  frames[old_last].next_sibling = index;
86  } else {
87  parent_frame.first_child = index;
88  }
89  frame.next_sibling = invalid;
90  parent_frame.last_child = index;
91  frame.name_ptr = names.save(name);
92  frame.total_runtime = 0.0;
93  frame.number_of_calls = 0;
94  return index;
95  }
96  inline std::size_t create_child_of_current(char const* name) {
97  return create_child_of(current_frame, name);
98  }
99  inline std::size_t find_root(char const* name) const {
100  if (frames.empty()) return invalid;
101  for (std::size_t i = 0; i != invalid; i = frames[i].next_sibling) {
102  if (frames[i].parent == invalid &&
103  (0 == std::strcmp(get_name(i), name))) {
104  return i;
105  }
106  }
107  return invalid;
108  }
109  inline std::size_t create_root(char const* name) {
110  auto index = frames.size();
111  frames.push_back(Frame());
112  auto& frame = frames.back();
113  frame.parent = invalid;
114  frame.first_child = invalid;
115  frame.last_child = invalid;
116  if (index != 0) {
117  frames[last_root].next_sibling = index;
118  }
119  last_root = index;
120  frame.next_sibling = invalid;
121  frame.name_ptr = names.save(name);
122  frame.total_runtime = 0.0;
123  frame.number_of_calls = 0;
124  return index;
125  }
126  inline std::size_t find(char const* name) {
127  return find_child_of(current_frame, name);
128  }
129  inline std::size_t create(char const* name) {
130  return create_child_of(current_frame, name);
131  }
132  inline std::size_t find_or_create(char const* name) {
133  return find_or_create_child_of(current_frame, name);
134  }
135  inline std::size_t find_or_create_child_of(
136  std::size_t parent_index, char const* name) {
137  auto found = find_child_of(parent_index, name);
138  if (found != invalid) return found;
139  return create_child_of(parent_index, name);
140  }
141  inline std::size_t push(char const* name) {
142  std::size_t id = find_or_create(name);
143  current_frame = id;
144  return id;
145  }
146  inline void pop() { current_frame = frames[current_frame].parent; }
147  inline void start(char const* const name) {
148  auto id = push(name);
149  frames[id].number_of_calls += 1;
150  frames[id].start_time = now();
151  }
152  inline double measure_runtime() {
153  auto current_time = now();
154  auto current_runtime = current_time - frames[current_frame].start_time;
155  return current_runtime;
156  }
157  inline double measure_total_runtime() {
158  return frames[current_frame].total_runtime + measure_runtime();
159  }
160  inline void stop() {
161  frames[current_frame].total_runtime = measure_total_runtime();
162  pop();
163  }
164  std::size_t first(std::size_t parent) const;
165  std::size_t next(std::size_t sibling) const;
166  std::size_t parent(std::size_t child) const;
167  std::size_t pre_order_next(std::size_t frame) const;
168  double time(std::size_t frame) const;
169  std::size_t calls(std::size_t frame) const;
170 };
171 
172 OMEGA_H_DLL extern History* global_singleton_history;
173 
174 void simple_print(profile::History const& history);
175 History invert(History const& h);
176 void print_time_sorted(History const& h);
177 void print_top_down_and_bottom_up(History const& h, double total_runtime);
178 void print_top_sorted(History const& h, double total_runtime);
179 
180 } // namespace profile
181 } // namespace Omega_h
182 
183 namespace Omega_h {
184 
185 inline void begin_code(char const* name, char const* file=0) {
186 #ifdef OMEGA_H_USE_KOKKOS
187  Kokkos::Profiling::pushRegion(name);
188 #endif
189  if (profile::global_singleton_history) {
190  if (file == 0) {
191  file = "Omega_h";
192  }
193  if (profile::global_singleton_history->add_filename) {
194  std::string str = ::Omega_h::filesystem::path(file).filename().string()+"::"+std::string(name);
195  profile::global_singleton_history->start(str.c_str());
196  } else {
197  profile::global_singleton_history->start(name);
198  }
199  }
200 }
201 
202 inline double get_runtime () {
203  double runtime = 0.0;
204  if (profile::global_singleton_history) {
205  runtime = profile::global_singleton_history->measure_total_runtime();
206  }
207  return runtime;
208 }
209 
210 inline void end_code() {
211 #ifdef OMEGA_H_USE_KOKKOS
212  Kokkos::Profiling::popRegion();
213 #endif
214  if (profile::global_singleton_history) {
215  profile::global_singleton_history->stop();
216  }
217 }
218 
219 struct ScopedTimer {
220  ScopedTimer(char const* name, char const *file=0) { begin_code(name, file); }
221  ~ScopedTimer() { end_code(); }
222  ScopedTimer(ScopedTimer const&) = delete;
223  ScopedTimer(ScopedTimer&&) = delete;
224  ScopedTimer& operator=(ScopedTimer const&) = delete;
225  ScopedTimer& operator=(ScopedTimer&&) = delete;
226  inline double total_runtime() { return get_runtime(); }
227 };
228 
229 } // namespace Omega_h
230 
231 #define OMEGA_H_TIME_FUNCTION \
232  ::Omega_h::ScopedTimer omega_h_scoped_function_timer(__FUNCTION__, (std::string(__FILE__)+":"+std::to_string(__LINE__)).c_str())
233 
234 #endif
Definition: Omega_h_filesystem.hpp:22
Definition: amr_mpi_test.cpp:6
Definition: Omega_h_timer.hpp:10
Definition: Omega_h_profile.hpp:219
Definition: Omega_h_profile.hpp:36
Definition: Omega_h_profile.hpp:47
Definition: Omega_h_profile.hpp:20