626 "Cannot print data from TimerOutput while inside a timed section."));
633 unsigned int max_width = 0;
635 max_width =
std::max(max_width,
static_cast<unsigned int>(i.first.size()));
638 max_width =
std::max(max_width + 1,
static_cast<unsigned int>(32));
639 const std::string extra_dash = std::string(max_width - 32,
'-');
640 const std::string extra_space = std::string(max_width - 32,
' ');
652 double total_cpu_time_in_sections = 0.;
654 total_cpu_time_in_sections += i.second.cpu_time();
656 const double section_overhead =
658 if (section_overhead > 0.0)
663 <<
"+---------------------------------------------"
664 << extra_dash <<
"+------------"
665 <<
"+------------+\n"
666 <<
"| Total CPU time elapsed since start "
667 << extra_space <<
"|";
668 out_stream << std::setw(10) << std::setprecision(3) << std::right;
671 << extra_space <<
"| "
678 <<
" | % of total |\n";
679 out_stream <<
"+---------------------------------" << extra_dash
680 <<
"+-----------+------------"
684 std::string name_out = i.first;
687 unsigned int pos_non_space = name_out.find_first_not_of(
' ');
688 name_out.erase(0, pos_non_space);
689 name_out.resize(max_width,
' ');
691 const double section_cpu_time = i.second.cpu_time();
708 if (fraction > 0.001)
722 <<
"+---------------------------------" << extra_dash
724 <<
"------------+------------+\n"
727 if (section_overhead > 0.0)
730 <<
"Note: The sum of section times is " << section_overhead
731 <<
" seconds larger than the total time.\n"
732 <<
"(Timer function may have introduced too much overhead, or different\n"
733 <<
"section timers may have run at the same time.)" << std::endl;
743 <<
"+---------------------------------------------"
744 << extra_dash <<
"+------------"
745 <<
"+------------+\n"
746 <<
"| Total wallclock time elapsed since start "
747 << extra_space <<
"|";
748 out_stream << std::setw(10) << std::setprecision(3) << std::right;
751 << extra_space <<
"| "
758 out_stream <<
"+---------------------------------" << extra_dash
759 <<
"+-----------+------------"
763 std::string name_out = i.first;
766 unsigned int pos_non_space = name_out.find_first_not_of(
' ');
767 name_out.erase(0, pos_non_space);
768 name_out.resize(max_width,
' ');
784 const double fraction =
786 if (fraction > 0.001)
800 <<
"+---------------------------------" << extra_dash
802 <<
"------------+------------+\n"
814 double total_cpu_time_in_sections = 0.;
816 total_cpu_time_in_sections += i.second.cpu_time();
818 const double section_overhead =
820 if (section_overhead > 0.0)
824 out_stream <<
"\n\n+---------------------------------------------"
826 <<
"------------+------------+"
827 <<
"------------+------------+" <<
'\n'
828 <<
"| Total CPU/wall time elapsed since start "
829 << extra_space <<
"|" << std::setw(10) << std::setprecision(3)
831 << extra_space <<
"|" << std::setw(10) << std::setprecision(3)
834 << extra_space <<
"|"
837 <<
"\n| Section " << extra_space
839 <<
" CPU time | % of total |"
840 <<
" wall time | % of total |"
841 <<
"\n+---------------------------------" << extra_dash
843 <<
"------------+------------+"
844 <<
"------------+------------+" << std::endl;
848 std::string name_out = i.first;
851 unsigned int pos_non_space = name_out.find_first_not_of(
' ');
852 name_out.erase(0, pos_non_space);
853 name_out.resize(max_width,
' ');
861 const double section_cpu_time = i.second.cpu_time();
873 if (fraction > 0.001)
899 const double fraction =
901 if (fraction > 0.001)
917 out_stream <<
"+---------------------------------" << extra_dash
919 <<
"------------+------------+"
920 <<
"------------+------------+" << std::endl
926 <<
"Note: The sum of section times is " << section_overhead
927 <<
" seconds larger than the total time.\n"
928 <<
"(Timer function may have introduced too much overhead, or different\n"
929 <<
"section timers may have run at the same time.)" << std::endl;
937 const MPI_Comm mpi_communicator_statistics,
938 const double quantile)
const
942 "Cannot print data from TimerOutput while inside a timed section."));
944 Assert(quantile >= 0. && quantile <= 0.5,
945 ExcMessage(
"The quantile must be between 0 and 0.5"));
947#ifdef DEAL_II_WITH_MPI
956 const int ierr = MPI_Comm_compare(mpi_communicator_statistics,
961 Assert(result == MPI_IDENT || result == MPI_CONGRUENT ||
962 result == MPI_SIMILAR,
964 "The passed MPI communicator must contain the same processes as "
965 "the one used to construct the TimerOutput."));
975 std::vector<std::string> my_section_names;
976 my_section_names.reserve(
sections.size());
977 for (
const auto &[section, timer] :
sections)
978 my_section_names.push_back(section);
980 const std::vector<std::string> global_section_names =
982 mpi_communicator_statistics);
985 unsigned int max_width = 0;
986 for (
const auto &i : global_section_names)
987 max_width =
std::max(max_width,
static_cast<unsigned int>(i.size()));
990 max_width =
std::max(max_width + 1,
static_cast<unsigned int>(17));
991 const std::string extra_dash = std::string(max_width - 17,
'-');
992 const std::string extra_space = std::string(max_width - 17,
' ');
995 const auto print_statistics = [&](
const double given_time) {
996 const unsigned int n_ranks =
998 if (n_ranks == 1 || quantile == 0.)
1003 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1006 out_stream <<
data.min_index << (n_ranks > 99999 ?
"" :
" ") <<
"|";
1007 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1009 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1012 out_stream <<
data.max_index << (n_ranks > 99999 ?
"" :
" ") <<
"|\n";
1018 std::vector<double> receive_data(
my_rank == 0 ? n_ranks : 0);
1019 std::vector<double> result(9);
1020#ifdef DEAL_II_WITH_MPI
1021 int ierr = MPI_Gather(&given_time,
1024 receive_data.data(),
1028 mpi_communicator_statistics);
1034 std::vector<std::pair<double, unsigned int>> data_rank;
1035 data_rank.reserve(n_ranks);
1036 for (
unsigned int i = 0; i < n_ranks; ++i)
1038 data_rank.emplace_back(receive_data[i], i);
1039 result[4] += receive_data[i];
1041 result[4] /= n_ranks;
1042 std::sort(data_rank.begin(), data_rank.end());
1044 const unsigned int quantile_index =
1045 static_cast<unsigned int>(std::round(quantile * n_ranks));
1047 result[0] = data_rank[0].first;
1048 result[1] = data_rank[0].second;
1049 result[2] = data_rank[quantile_index].first;
1050 result[3] = data_rank[quantile_index].second;
1051 result[5] = data_rank[n_ranks - 1 - quantile_index].first;
1052 result[6] = data_rank[n_ranks - 1 - quantile_index].second;
1053 result[7] = data_rank[n_ranks - 1].first;
1054 result[8] = data_rank[n_ranks - 1].second;
1057 result.data(), 9, MPI_DOUBLE, 0, mpi_communicator_statistics);
1060 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1063 out_stream << static_cast<unsigned int>(result[1])
1064 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
1065 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1068 out_stream << static_cast<unsigned int>(result[3])
1069 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
1070 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1072 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1075 out_stream << static_cast<unsigned int>(result[6])
1076 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
1077 out_stream << std::setw(10) << std::setprecision(4) << std::right;
1080 out_stream << static_cast<unsigned int>(result[8])
1081 << (n_ranks > 99999 ?
"" :
" ") <<
"|\n";
1087 const unsigned int n_ranks =
1090 const std::string time_rank_column =
"------------------+";
1091 const std::string time_rank_space =
" |";
1095 <<
"+------------------------------" << extra_dash <<
"+"
1097 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1099 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1100 << time_rank_column <<
'\n'
1101 <<
"| Total wallclock time elapsed " << extra_space <<
"|";
1107 << (n_ranks > 1 && quantile > 0. ? time_rank_space :
"")
1109 << (n_ranks > 1 && quantile > 0. ? time_rank_space :
"")
1110 << time_rank_space <<
'\n';
1111 out_stream <<
"| Section " << extra_space <<
"| no. calls "
1112 <<
"| min time rank |";
1113 if (n_ranks > 1 && quantile > 0.)
1114 out_stream <<
" " << std::setw(5) << std::setprecision(2) << std::right
1115 << quantile <<
"-tile rank |";
1117 if (n_ranks > 1 && quantile > 0.)
1118 out_stream <<
" " << std::setw(5) << std::setprecision(2) << std::right
1119 << 1. - quantile <<
"-tile rank |";
1121 out_stream <<
"+------------------------------" << extra_dash <<
"+"
1123 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1125 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1126 << time_rank_column <<
'\n';
1128 for (
const auto &global_section_name : global_section_names)
1130 std::string name_out = global_section_name;
1131 const auto section_it =
sections.find(global_section_name);
1132 const bool entered_section_locally = (section_it !=
sections.end());
1135 unsigned int pos_non_space = name_out.find_first_not_of(
' ');
1136 name_out.erase(0, pos_non_space);
1137 name_out.resize(max_width,
' ');
1141 const unsigned n_laps =
1142 entered_section_locally ? section_it->second.n_laps() : 0;
1146 const double wall_time =
1147 entered_section_locally ? section_it->second.wall_time() : 0.0;
1148 print_statistics(wall_time);
1150 out_stream <<
"+------------------------------" << extra_dash <<
"+"
1152 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1154 << (n_ranks > 1 && quantile > 0. ? time_rank_column :
"")
1155 << time_rank_column <<
'\n';