18 #include "libmesh/perf_log.h"
21 #include "libmesh/int_range.h"
22 #include "libmesh/timestamp.h"
31 #include <sys/types.h>
35 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
36 #include <sys/utsname.h>
39 #ifdef LIBMESH_HAVE_PWD_H
59 gettimeofday (&
tstart,
nullptr);
85 libmesh_error_msg(
"ERROR clearing performance log for class " \
89 <<
" is still being monitored!");
91 gettimeofday (&
tstart,
nullptr);
103 const std::string & header)
105 const char * label_c_str;
106 const char * header_c_str;
111 char * newcopy =
new char [label.size()+1];
112 strcpy(newcopy, label.c_str());
113 label_c_str = newcopy;
121 char * newcopy =
new char [header.size()+1];
122 strcpy(newcopy, header.c_str());
123 header_c_str = newcopy;
128 this->
fast_push(label_c_str, header_c_str);
136 this->
push(std::string(label), std::string(header));
144 const std::string & header)
158 this->
fast_pop(label_c_str, header_c_str);
166 this->
pop(std::string(label), std::string(header));
173 std::ostringstream oss;
179 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
181 struct utsname sysInfo;
195 #ifdef LIBMESH_HAVE_GETPWUID
196 struct passwd * p = getpwuid(getuid());
214 std::vector<std::ostringstream*> v;
215 v.push_back(&pid_stream);
216 v.push_back(&nprocs_stream);
217 v.push_back(&time_stream);
218 v.push_back(&os_stream);
219 v.push_back(&host_stream);
220 v.push_back(&osrel_stream);
221 v.push_back(&osver_stream);
222 v.push_back(&machine_stream);
223 v.push_back(&user_stream);
232 time_stream <<
"| Time: ";
233 os_stream <<
"| OS: ";
234 host_stream <<
"| HostName: ";
235 osrel_stream <<
"| OS Release: ";
236 osver_stream <<
"| OS Version: ";
237 machine_stream <<
"| Machine: ";
240 #ifdef LIBMESH_HAVE_SYS_UTSNAME_H
241 os_stream << sysInfo.sysname ;
242 host_stream << sysInfo.nodename ;
243 osrel_stream << sysInfo.release ;
244 osver_stream << sysInfo.version ;
245 machine_stream << sysInfo.machine ;
247 os_stream <<
"Unknown";
248 host_stream <<
"Unknown";
249 osrel_stream <<
"Unknown";
250 osver_stream <<
"Unknown";
251 machine_stream <<
"Unknown";
254 user_stream <<
"| Username: ";
255 #ifdef LIBMESH_HAVE_GETPWUID
257 user_stream << p->pw_name;
260 user_stream <<
"Unknown";
263 std::string libmesh_configure_info(LIBMESH_CONFIGURE_INFO);
264 std::vector<std::string> parsed_libmesh_configure_info;
266 parsed_libmesh_configure_info);
271 libmesh_assert_greater (parsed_libmesh_configure_info.size(), 0);
274 unsigned int max_length = 0;
276 if (v_i->str().size() > max_length)
277 max_length = cast_int<unsigned int>
281 for (
auto & plci_i : parsed_libmesh_configure_info)
282 if (plci_i.size() > max_length)
283 max_length = cast_int<unsigned int> (plci_i.size());
287 << std::string(max_length+1,
'-')
293 if (v_i->str().size())
295 << std::setw (cast_int<int>
296 (max_length + 4 - v_i->str().size()))
304 oss <<
"| Configuration: "
305 << parsed_libmesh_configure_info[0]
306 << std::setw (cast_int<int>
308 parsed_libmesh_configure_info[0].size() - 18))
317 << parsed_libmesh_configure_info[i]
318 << std::setw (cast_int<int>
320 parsed_libmesh_configure_info[i].size() - 3))
328 << std::string(max_length+1,
'-')
340 std::ostringstream oss;
345 struct timeval tstop;
347 gettimeofday (&tstop,
nullptr);
349 const double elapsed_time = (static_cast<double>(tstop.tv_sec -
tstart.tv_sec) +
350 static_cast<double>(tstop.tv_usec -
tstart.tv_usec)*1.e-6);
354 unsigned int event_col_width = 30;
355 const unsigned int ncalls_col_width = 11;
356 const unsigned int tot_time_col_width = 12;
357 const unsigned int avg_time_col_width = 12;
358 const unsigned int tot_time_incl_sub_col_width = 12;
359 const unsigned int avg_time_incl_sub_col_width = 12;
360 const unsigned int pct_active_col_width = 9;
361 const unsigned int pct_active_incl_sub_col_width = 9;
366 if (std::strlen(pos.first.second)+3 > event_col_width)
367 event_col_width = cast_int<unsigned int>
368 (std::strlen(pos.first.second)+3);
371 const unsigned int total_col_width =
376 tot_time_incl_sub_col_width +
377 avg_time_incl_sub_col_width +
378 pct_active_col_width+
379 pct_active_incl_sub_col_width+1;
383 << std::string(total_col_width,
'-')
388 std::ostringstream temp;
389 temp <<
"| " <<
label_name <<
" Performance: Alive time=" << elapsed_time
393 const unsigned int temp_size = cast_int<unsigned int>
403 if (temp_size < total_col_width+2)
404 oss << std::setw(total_col_width - temp_size + 2)
413 << std::string(total_col_width,
'-')
419 << std::setw(event_col_width)
422 << std::setw(ncalls_col_width)
425 << std::setw(tot_time_col_width)
428 << std::setw(avg_time_col_width)
431 << std::setw(tot_time_incl_sub_col_width)
434 << std::setw(avg_time_incl_sub_col_width)
437 << std::setw(pct_active_col_width+pct_active_incl_sub_col_width)
439 <<
"% of Active Time"
442 << std::setw(event_col_width)
445 << std::setw(ncalls_col_width)
448 << std::setw(tot_time_col_width)
451 << std::setw(avg_time_col_width)
454 << std::setw(tot_time_incl_sub_col_width)
457 << std::setw(avg_time_incl_sub_col_width)
460 << std::setw(pct_active_col_width)
463 << std::setw(pct_active_incl_sub_col_width)
467 << std::string(total_col_width,
'-')
469 << std::string(total_col_width,
' ')
472 unsigned int summed_function_calls = 0;
473 double summed_total_time = 0;
474 double summed_percentage = 0;
476 std::string last_header(
"");
479 std::map<std::pair<std::string, std::string>,
PerfData> string_log;
481 for (
auto char_data :
log)
482 string_log[std::make_pair(char_data.first.first,
483 char_data.first.second)] =
486 for (
auto pos : string_log)
488 const PerfData & perf_data = pos.second;
491 if (perf_data.
count != 0)
493 const unsigned int perf_count = perf_data.
count;
494 const double perf_time = perf_data.
tot_time;
495 const double perf_avg_time = perf_time / static_cast<double>(perf_count);
497 const double perf_avg_time_incl_sub = perf_time_incl_sub / static_cast<double>(perf_count);
499 const double perf_percent_incl_sub = (
total_time != 0.) ? perf_time_incl_sub /
total_time * 100. : 0.;
501 summed_function_calls += perf_count;
502 summed_total_time += perf_time;
503 summed_percentage += perf_percent;
506 if (pos.first.first ==
"")
508 << std::setw(event_col_width)
514 if (last_header != pos.first.first)
516 last_header = pos.first.first;
522 << std::string(total_col_width,
' ')
524 << std::setw(total_col_width-1)
531 << std::setw(event_col_width-2)
538 oss << std::setw(ncalls_col_width)
542 std::ios_base::fmtflags out_flags = oss.flags();
546 << std::setprecision(4)
547 << std::setw(tot_time_col_width)
554 << std::setprecision(6)
555 << std::setw(avg_time_col_width)
561 << std::setprecision(4)
562 << std::setw(tot_time_incl_sub_col_width)
564 << perf_time_incl_sub;
568 << std::setprecision(6)
569 << std::setw(avg_time_incl_sub_col_width)
571 << perf_avg_time_incl_sub;
575 << std::setprecision(2)
576 << std::setw(pct_active_col_width)
582 << std::setprecision(2)
583 << std::setw(pct_active_incl_sub_col_width)
585 << perf_percent_incl_sub;
588 oss.flags(out_flags);
595 << std::string(total_col_width,
'-')
597 << std::setw(event_col_width)
604 if (summed_function_calls < 9999999)
605 oss << std::setw(ncalls_col_width)
606 << summed_function_calls;
611 std::ios_base::fmtflags out_flags = oss.flags();
613 oss << std::scientific
614 << std::setprecision(3)
615 << std::setw(ncalls_col_width)
617 << static_cast<Real>(summed_function_calls);
620 oss.flags(out_flags);
626 << std::setprecision(4)
627 << std::setw(tot_time_col_width)
629 << summed_total_time;
632 oss << std::setw(avg_time_col_width) <<
"";
635 oss << std::setw(tot_time_incl_sub_col_width)
637 << std::setw(avg_time_incl_sub_col_width)
642 << std::setprecision(2)
643 << std::setw(pct_active_col_width)
646 << std::setw(pct_active_incl_sub_col_width)
649 << std::string(total_col_width,
'-')
660 std::ostringstream oss;
690 std::string log_string = this->
get_log();
691 if (log_string.size() > 0)
703 return log[std::make_pair(header_c_str, label_c_str)];
706 auto iter = std::find_if
708 [&label, &header] (log_type::const_reference a)
711 !std::strcmp(header.c_str(), a.first.first) &&
712 !std::strcmp(label.c_str(), a.first.second);
721 const std::string & header)
723 this->
push(label,header);
729 const std::string & header)
731 this->
pop(label,header);
760 const std::string split_on(
"' '");
762 size_t current_pos = 0;
766 size_t end_pos = input.find(split_on, current_pos);
768 if (end_pos != std::string::npos)
772 output.push_back( input.substr(current_pos, end_pos - current_pos + 1) );
776 current_pos = end_pos + split_on.size() - 1;
784 output.push_back( input.substr(current_pos) );