Chi-Tech
chi_log.cc
Go to the documentation of this file.
1#include "chi_runtime.h"
2#include "chi_log.h"
3#include "chi_mpi.h"
4#include "utils/chi_timer.h"
5
7
8#include <sstream>
9
10// ###################################################################
11/**Access to the singleton*/
13{
14 static ChiLog instance;
15 return instance;
16}
17
18// ###################################################################
19/** Default constructor*/
21{
22 verbosity_ = 0;
23 std::string memory_usage_event("Maximum Memory Usage");
24 repeating_events.emplace_back(memory_usage_event);
25
26 RepeatingEvent& ref_rep_event = repeating_events.back();
27
28 ref_rep_event.Events().emplace_back(Chi::program_timer.GetTime(),
29 EventType::EVENT_CREATED,
30 std::make_shared<EventInfo>());
31}
32
33// ###################################################################
34/** Makes a log entry.*/
36{
37 switch (level)
38 {
39 case LOG_0VERBOSE_0:
40 case LOG_0:
41 {
42 if (Chi::mpi.location_id == 0)
43 {
44 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
45 return {&std::cout, header};
46 }
47 else
48 {
49 std::string header = " ";
50 return {&dummy_stream_, header, true};
51 }
52 }
53 case LOG_0WARNING:
54 {
55 if (Chi::mpi.location_id == 0)
56 {
57 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
58 header += StringStreamColor(FG_YELLOW) + "**WARNING** ";
59 return {&std::cout, header};
60 }
61 else
62 {
63 std::string header = " ";
64 return {&dummy_stream_, header, true};
65 }
66 }
67 case LOG_0ERROR:
68 {
69 if (Chi::mpi.location_id == 0)
70 {
71 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
72 header += StringStreamColor(FG_RED) + "**!**ERROR**!** ";
73 return {&std::cerr, header};
74 }
75 else
76 {
77 std::string header = " ";
78 return {&dummy_stream_, header, true};
79 }
80 }
81
82 case LOG_0VERBOSE_1:
83 {
84 if ((Chi::mpi.location_id == 0) && (verbosity_ >= 1))
85 {
86 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
87 header += StringStreamColor(FG_CYAN);
88 return {&std::cout, header};
89 }
90 else
91 {
92 std::string header = " ";
93 return {&dummy_stream_, header, true};
94 }
95 }
96 case ChiLog::LOG_LVL::LOG_0VERBOSE_2:
97 {
98 if ((Chi::mpi.location_id == 0) && (verbosity_ >= 2))
99 {
100 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
101 header += StringStreamColor(FG_MAGENTA);
102 return {&std::cout, header};
103 }
104 else
105 {
106 std::string header = " ";
107 return {&dummy_stream_, header, true};
108 }
109 }
110 case LOG_ALLVERBOSE_0:
111 case LOG_ALL:
112 {
113 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
114 return {&std::cout, header};
115 }
116 case LOG_ALLWARNING:
117 {
118 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
119 header += StringStreamColor(FG_YELLOW) + "**WARNING** ";
120 return {&std::cout, header};
121 }
122 case LOG_ALLERROR:
123 {
124 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
125 header += StringStreamColor(FG_RED) + "**!**ERROR**!** ";
126 return {&std::cerr, header};
127 }
128
129 case LOG_ALLVERBOSE_1:
130 {
131 if (verbosity_ >= 1)
132 {
133 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
134 header += StringStreamColor(FG_CYAN);
135 return {&std::cout, header};
136 }
137 else
138 {
139 std::string header = " ";
140 return {&dummy_stream_, header, true};
141 }
142 }
143 case LOG_ALLVERBOSE_2:
144 {
145 if (verbosity_ >= 2)
146 {
147 std::string header = "[" + std::to_string(Chi::mpi.location_id) + "] ";
148 header += StringStreamColor(FG_MAGENTA);
149 return {&std::cout, header};
150 }
151 else
152 {
153 std::string header = " ";
154 return {&dummy_stream_, header, true};
155 }
156 }
157 default:
158 std::string header = " ";
159 return {&dummy_stream_, header};
160 }
161}
162
163// ###################################################################
164/** Sets the verbosity level.*/
165void chi::ChiLog::SetVerbosity(int int_level)
166{
167 verbosity_ = std::min(int_level, 2);
168}
169
170// ###################################################################
171/** Gets the current verbosity level.*/
172int chi::ChiLog::GetVerbosity() const { return verbosity_; }
173
174// ###################################################################
175/** Returns a unique tag to a newly created repeating event.*/
176size_t chi::ChiLog::GetRepeatingEventTag(std::string event_name)
177{
178 repeating_events.emplace_back(event_name);
179
180 RepeatingEvent& ref_rep_event = repeating_events.back();
181
182 ref_rep_event.Events().emplace_back(Chi::program_timer.GetTime(),
183 EventType::EVENT_CREATED,
184 std::make_shared<EventInfo>());
185
186 return repeating_events.size() - 1;
187}
188
189// ###################################################################
190/** Returns a unique tag to the latest version of an existing repeating event.*/
191size_t chi::ChiLog::GetExistingRepeatingEventTag(std::string event_name)
192{
193 const size_t num_rep_events = repeating_events.size();
194 for (size_t k=num_rep_events-1; k!=0; --k)
195 if (repeating_events[k].Name() == event_name)
196 return k;
197
198 ChiLogicalError("Tag could not be found for repeating event name \"" +
199 event_name + "\"");
200}
201
202// ###################################################################
203/**Logs an event with the supplied event information.*/
204void chi::ChiLog::LogEvent(size_t ev_tag,
205 EventType ev_type,
206 const std::shared_ptr<EventInfo>& ev_info)
207{
208 if (ev_tag >= repeating_events.size()) return;
209
210 RepeatingEvent& ref_rep_event = repeating_events[ev_tag];
211
212 ref_rep_event.Events().emplace_back(
213 Chi::program_timer.GetTime(), ev_type, ev_info);
214}
215
216// ###################################################################
217/**Logs an event without any event information.*/
218void chi::ChiLog::LogEvent(size_t ev_tag, EventType ev_type)
219{
220 if (ev_tag >= repeating_events.size()) return;
221
222 RepeatingEvent& ref_rep_event = repeating_events[ev_tag];
223
224 ref_rep_event.Events().emplace_back(
225 Chi::program_timer.GetTime(), ev_type, nullptr);
226}
227
228// ###################################################################
229/**Returns a string representation of the event history associated with
230 * the tag. Each event entry will be prepended by the location id and
231 * the program timestamp in seconds. This method uses the
232 * ChiLog::EventInfo::GetString method to append information. This allows
233 * derived classes to implement more sophisticated outputs.*/
234std::string chi::ChiLog::PrintEventHistory(size_t ev_tag)
235{
236 std::stringstream outstr;
237 if (ev_tag >= repeating_events.size()) return outstr.str();
238
239 RepeatingEvent& ref_rep_event = repeating_events[ev_tag];
240
241 for (auto& event : ref_rep_event.Events())
242 {
243 outstr << "[" << Chi::mpi.location_id << "] ";
244
245 char buf[100];
246 snprintf(buf, 100, "%16.9f", event.ev_time / 1000.0);
247 outstr << buf << " ";
248
249 switch (event.ev_type)
250 {
251 case EventType::EVENT_CREATED:
252 outstr << "EVENT_CREATED ";
253 break;
254 case EventType::SINGLE_OCCURRENCE:
255 outstr << "SINGLE_OCCURRENCE ";
256 break;
257 case EventType::EVENT_BEGIN:
258 outstr << "EVENT_BEGIN ";
259 break;
260 case EventType::EVENT_END:
261 outstr << "EVENT_END ";
262 break;
263 }
264
265 if (event.ev_info != nullptr) outstr << event.ev_info->GetString();
266 outstr << std::endl;
267 }
268
269 return outstr.str();
270}
271
272// ###################################################################
273/**Processes an event given an event operation. See ChiLog for further
274 * reference.*/
275double chi::ChiLog::ProcessEvent(size_t ev_tag,
276 chi::ChiLog::EventOperation ev_operation)
277{
278 if (ev_tag >= repeating_events.size()) return 0.0;
279
280 RepeatingEvent& ref_rep_event = repeating_events[ev_tag];
281
282 double ret_val = 0.0;
283 switch (ev_operation)
284 {
285 case EventOperation::NUMBER_OF_OCCURRENCES:
286 {
287 for (auto& event : ref_rep_event.Events())
288 {
289 if ((event.ev_type == EventType::EVENT_CREATED) or
290 (event.ev_type == EventType::SINGLE_OCCURRENCE) or
291 (event.ev_type == EventType::EVENT_BEGIN))
292 ret_val += 1.0;
293 } // for events
294 break;
295 }
296 case EventOperation::TOTAL_DURATION:
297 {
298 double start_time = 0.0;
299 for (auto& event : ref_rep_event.Events())
300 {
301 if (event.ev_type == EventType::EVENT_BEGIN) start_time = event.ev_time;
302 if (event.ev_type == EventType::EVENT_END)
303 ret_val += event.ev_time - start_time;
304 } // for events
305 ret_val *= 1000.0;
306 break;
307 }
308 case EventOperation::AVERAGE_DURATION:
309 {
310 double start_time = 0.0;
311 int counter = 0;
312 for (auto& event : ref_rep_event.Events())
313 {
314 if (event.ev_type == EventType::EVENT_BEGIN) start_time = event.ev_time;
315
316 if (event.ev_type == EventType::EVENT_END)
317 {
318 ret_val += event.ev_time - start_time;
319 counter++;
320 }
321 } // for events
322 ret_val /= (1000.0 * counter);
323 break;
324 }
325 case EventOperation::MAX_VALUE:
326 {
327 ret_val = 0.0;
328 for (auto& event : ref_rep_event.Events())
329 {
330 if ((event.ev_type == EventType::SINGLE_OCCURRENCE) or
331 (event.ev_type == EventType::EVENT_BEGIN) or
332 (event.ev_type == EventType::EVENT_END))
333 {
334 if (event.ev_info != nullptr)
335 ret_val = std::max(event.ev_info->arb_value, ret_val);
336 }
337 } // for events
338 break;
339 }
340 case EventOperation::AVERAGE_VALUE:
341 {
342 ret_val = 0.0;
343 int count = 0;
344 for (auto& event : ref_rep_event.Events())
345 {
346 if ((event.ev_type == EventType::SINGLE_OCCURRENCE) or
347 (event.ev_type == EventType::EVENT_BEGIN) or
348 (event.ev_type == EventType::EVENT_END))
349 {
350 if (event.ev_info != nullptr)
351 {
352 ret_val += event.ev_info->arb_value;
353 ++count;
354 }
355 }
356 } // for events
357 if (count == 0) count = 1;
358 ret_val /= count;
359 break;
360 }
361 } // switch
362
363 return ret_val;
364}
#define ChiLogicalError(message)
static chi::Timer program_timer
Definition: chi_runtime.h:79
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
std::vector< Event > & Events()
Definition: chi_log.h:331
double ProcessEvent(size_t ev_tag, EventOperation ev_operation)
Definition: chi_log.cc:275
int GetVerbosity() const
Definition: chi_log.cc:172
ChiLog() noexcept
Definition: chi_log.cc:20
void SetVerbosity(int int_level)
Definition: chi_log.cc:165
size_t GetExistingRepeatingEventTag(std::string event_name)
Definition: chi_log.cc:191
static ChiLog & GetInstance() noexcept
Definition: chi_log.cc:12
std::string PrintEventHistory(size_t ev_tag)
Definition: chi_log.cc:234
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
size_t GetRepeatingEventTag(std::string event_name)
Definition: chi_log.cc:176
void LogEvent(size_t ev_tag, EventType ev_type, const std::shared_ptr< EventInfo > &ev_info)
Definition: chi_log.cc:204
const int & location_id
Current process rank.
Definition: mpi_info.h:26
std::string StringStreamColor(StringSteamColorCode code)