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) );