22#include <boost/io/ios_state.hpp>
33#ifdef DEAL_II_HAVE_SYS_RESOURCE_H
34# include <sys/resource.h>
47 namespace TimerImplementation
56 struct is_duration : std::false_type
62 template <
typename Rep,
typename Period>
63 struct is_duration<
std::chrono::duration<Rep, Period>> : std::true_type
75 static_assert(is_duration<T>::value,
76 "The template type should be a duration type.");
77 return T(std::lround(T::period::den * (time / T::period::num)));
84 template <
typename Rep,
typename Period>
86 to_seconds(
const std::chrono::duration<Rep, Period> duration)
97 data.
sum = numbers::signaling_nan<double>();
98 data.
min = numbers::signaling_nan<double>();
99 data.
max = numbers::signaling_nan<double>();
100 data.
avg = numbers::signaling_nan<double>();
121 (double)(((
unsigned long long)
cpuTime.dwHighDateTime << 32) |
126#elif defined(DEAL_II_HAVE_SYS_RESOURCE_H)
139template <
typename clock_type_>
148template <
typename clock_type_>
152 current_lap_start_time = clock_type::now();
153 accumulated_time = duration_type::zero();
154 last_lap_time = duration_type::zero();
167 , mpi_communicator(mpi_communicator)
180#ifdef DEAL_II_WITH_MPI
212 internal::TimerImplementation::from_seconds<
decltype(
215 internal::TimerImplementation::from_seconds<
decltype(
218 internal::TimerImplementation::to_seconds(
230 return internal::TimerImplementation::to_seconds(
cpu_times.accumulated_time);
240 const double running_time = internal::TimerImplementation::to_seconds(
258 return internal::TimerImplementation::to_seconds(
cpu_times.last_lap_time);
304 : output_frequency(output_frequency)
305 , output_type(output_type)
306 , out_stream(stream,
true)
307 , output_is_enabled(
true)
316 : output_frequency(output_frequency)
317 , output_type(output_type)
319 , output_is_enabled(
true)
326 std::ostream & stream,
329 : output_frequency(output_frequency)
330 , output_type(output_type)
331 , out_stream(stream,
true)
332 , output_is_enabled(
true)
333 , mpi_communicator(mpi_communicator)
342 : output_frequency(output_frequency)
343 , output_type(output_type)
345 , output_is_enabled(
true)
346 , mpi_communicator(mpi_communicator)
370#ifdef DEAL_II_WITH_MPI
371# if __cpp_lib_uncaught_exceptions >= 201411
378 const unsigned int myid =
382 <<
"---------------------------------------------------------\n"
383 <<
"TimerOutput objects finalize timed values printed to the\n"
384 <<
"screen by communicating over MPI in their destructors.\n"
385 <<
"Since an exception is currently uncaught, this\n"
386 <<
"synchronization (and subsequent output) will be skipped\n"
387 <<
"to avoid a possible deadlock.\n"
388 <<
"---------------------------------------------------------"
405 std::lock_guard<std::mutex> lock(
mutex);
407 Assert(section_name.empty() ==
false,
ExcMessage(
"Section string is empty."));
412 ExcMessage(std::string(
"Cannot enter the already active section <") +
413 section_name +
">."));
430 sections[section_name].total_cpu_time = 0;
431 sections[section_name].total_wall_time = 0;
435 sections[section_name].timer.reset();
436 sections[section_name].timer.start();
448 ExcMessage(
"Cannot exit any section because none has been entered!"));
450 std::lock_guard<std::mutex> lock(
mutex);
452 if (!section_name.empty())
455 ExcMessage(
"Cannot delete a section that was never created."));
459 ExcMessage(
"Cannot delete a section that has not been entered."));
484 std::ostringstream
cpu;
485 cpu << cpu_time <<
"s";
486 std::ostringstream
wall;
494 ", CPU/wall time: " +
cpu.str() +
" / " +
wall.str() +
".";
508std::map<std::string, double>
511 std::map<std::string, double> output;
542 unsigned int max_width = 0;
544 max_width =
std::max(max_width,
static_cast<unsigned int>(i.first.size()));
547 max_width =
std::max(max_width + 1,
static_cast<unsigned int>(32));
548 const std::string
extra_dash = std::string(max_width - 32,
'-');
549 const std::string
extra_space = std::string(max_width - 32,
' ');
572 <<
"+---------------------------------------------"
574 <<
"+------------+\n"
575 <<
"| Total CPU time elapsed since start "
577 out_stream << std::setw(10) << std::setprecision(3) << std::right;
587 <<
" | % of total |\n";
589 <<
"+-----------+------------"
606 out_stream << i.second.total_cpu_time <<
"s |";
613 const double fraction =
615 if (fraction > 0.001)
629 <<
"+---------------------------------" <<
extra_dash
631 <<
"------------+------------+\n"
637 <<
"Note: The sum of counted times is " <<
time_gap
638 <<
" seconds larger than the total time.\n"
639 <<
"(Timer function may have introduced too much overhead, or different\n"
640 <<
"section timers may have run at the same time.)" << std::endl;
650 <<
"+---------------------------------------------"
652 <<
"+------------+\n"
653 <<
"| Total wallclock time elapsed since start "
655 out_stream << std::setw(10) << std::setprecision(3) << std::right;
666 <<
"+-----------+------------"
683 out_stream << i.second.total_wall_time <<
"s |";
691 const double fraction =
693 if (fraction > 0.001)
707 <<
"+---------------------------------" <<
extra_dash
709 <<
"------------+------------+\n"
732 out_stream <<
"\n\n+---------------------------------------------"
734 <<
"------------+------------+"
735 <<
"------------+------------+" <<
'\n'
736 <<
"| Total CPU/wall time elapsed since start "
737 <<
extra_space <<
"|" << std::setw(10) << std::setprecision(3)
746 <<
" CPU time | % of total |"
747 <<
" wall time | % of total |"
748 <<
"\n+---------------------------------" <<
extra_dash
750 <<
"------------+------------+"
751 <<
"------------+------------+" << std::endl;
770 out_stream << i.second.total_cpu_time <<
"s |";
777 const double fraction =
779 if (fraction > 0.001)
797 out_stream << i.second.total_wall_time <<
"s |";
805 const double fraction =
807 if (fraction > 0.001)
825 <<
"------------+------------+"
826 <<
"------------+------------+" << std::endl
832 <<
"Note: The sum of counted times is " <<
time_gap
833 <<
" seconds larger than the total time.\n"
834 <<
"(Timer function may have introduced too much overhead, or different\n"
835 <<
"section timers may have run at the same time.)" << std::endl;
852 ExcMessage(
"The quantile must be between 0 and 0.5"));
855 unsigned int max_width = 0;
857 max_width =
std::max(max_width,
static_cast<unsigned int>(i.first.size()));
860 max_width =
std::max(max_width + 1,
static_cast<unsigned int>(17));
861 const std::string
extra_dash = std::string(max_width - 17,
'-');
862 const std::string
extra_space = std::string(max_width - 17,
' ');
865 const auto print_statistics = [&](
const double given_time) {
872 out_stream << std::setw(10) << std::setprecision(4) << std::right;
876 out_stream << std::setw(10) << std::setprecision(4) << std::right;
878 out_stream << std::setw(10) << std::setprecision(4) << std::right;
886 std::vector<double>
receive_data(my_rank == 0 ? n_ranks : 0);
887 std::vector<double>
result(9);
888#ifdef DEAL_II_WITH_MPI
902 std::vector<std::pair<double, unsigned int>>
data_rank;
904 for (
unsigned int i = 0; i < n_ranks; ++i)
913 static_cast<unsigned int>(std::round(
quantile * n_ranks));
927 out_stream << std::setw(10) << std::setprecision(4) << std::right;
931 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
932 out_stream << std::setw(10) << std::setprecision(4) << std::right;
936 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
937 out_stream << std::setw(10) << std::setprecision(4) << std::right;
939 out_stream << std::setw(10) << std::setprecision(4) << std::right;
943 << (n_ranks > 99999 ?
"" :
" ") <<
"|";
944 out_stream << std::setw(10) << std::setprecision(4) << std::right;
948 << (n_ranks > 99999 ?
"" :
" ") <<
"|\n";
961 <<
"+------------------------------" <<
extra_dash <<
"+"
967 <<
"| Total wallclock time elapsed " <<
extra_space <<
"|";
978 <<
"| min time rank |";
980 out_stream <<
" " << std::setw(5) << std::setprecision(2) << std::right
984 out_stream <<
" " << std::setw(5) << std::setprecision(2) << std::right
1006 print_statistics(i.second.total_wall_time);
1036 std::lock_guard<std::mutex> lock(
mutex);
value_type * data() const noexcept
std::ostream & get_stream() const
MPI_Comm mpi_communicator
void print_summary() const
@ cpu_and_wall_times_grouped
OutputFrequency output_frequency
std::map< std::string, Section > sections
void leave_subsection(const std::string §ion_name="")
void print_wall_time_statistics(const MPI_Comm mpi_comm, const double print_quantile=0.) const
std::list< std::string > active_sections
ConditionalOStream out_stream
std::map< std::string, double > get_summary_data(const OutputData kind) const
void enter_subsection(const std::string §ion_name)
TimerOutput(std::ostream &stream, const OutputFrequency output_frequency, const OutputType output_type)
double last_cpu_time() const
Utilities::MPI::MinMaxAvg accumulated_wall_time_data
MPI_Comm mpi_communicator
ClockMeasurements< wall_clock_type > wall_times
ClockMeasurements< cpu_clock_type > cpu_times
Utilities::MPI::MinMaxAvg last_lap_wall_time_data
double last_wall_time() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_WARNING(desc)
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
MinMaxAvg min_max_avg(const double my_value, const MPI_Comm mpi_communicator)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
static time_point now() noexcept
std::chrono::time_point< CPUClock, duration > time_point
time_point_type current_lap_start_time
typename clock_type::duration duration_type
duration_type accumulated_time
duration_type last_lap_time