From 5f259f183b6e875c864b533336582d66712879da Mon Sep 17 00:00:00 2001 From: Lei Qiao Date: Tue, 14 Apr 2015 17:16:14 -0500 Subject: [PATCH] fix cpu time collection on MPI system for class TimerOutput. --- doc/news/changes.h | 7 +++++++ source/base/timer.cc | 25 +++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/doc/news/changes.h b/doc/news/changes.h index ce4f8efc1a..bbe1d8dff5 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -460,6 +460,12 @@ inconvenience this causes.

Specific improvements

    +
  1. Fixed: The TimerOutput class reported abnormally large cpu time when run + with more than one process with MPI. Now this is fixed. +
    + (Lei Qiao, 2015/04/19) +
  2. +
  3. New: TrilinosWrappers::BlockSparseMatrix now has member functions TrilinosWrappers::BlockSparseMatrix::domain_paritioner() and TrilinosWrappers::BlockSparseMatrix::range_partitioner() that return a @@ -468,6 +474,7 @@ inconvenience this causes. (Matthias Maier, 2015/04/08)
  4. +
  5. Fixed: The class SymmetricTensor<2,dim> is now usable also for dim>3.
    (Martin Kronbichler, 2015/04/14) diff --git a/source/base/timer.cc b/source/base/timer.cc index 821e130b4a..f5680f43ff 100644 --- a/source/base/timer.cc +++ b/source/base/timer.cc @@ -356,7 +356,10 @@ TimerOutput::enter_subsection (const std::string §ion_name) // create a new timer for this section. the second argument // will ensure that we have an MPI barrier before starting // and stopping a timer, and this ensures that we get the - // maximum run time for this section over all processors + // maximum run time for this section over all processors. + // The mpi_communicator from TimerOutput is passed to the + // Timer here, so this Timer will collect timing information + // among all processes inside mpi_communicator. sections[section_name].timer = Timer(mpi_communicator, true); } #endif @@ -403,12 +406,12 @@ TimerOutput::leave_subsection (const std::string §ion_name) sections[actual_section_name].total_wall_time += sections[actual_section_name].timer.wall_time(); - // get cpu time. on MPI systems, add the local contributions. we - // could do that also in the Timer class itself, but we didn't - // initialize the Timers here according to that - double cpu_time = sections[actual_section_name].timer(); - sections[actual_section_name].total_cpu_time - += Utilities::MPI::sum (cpu_time, mpi_communicator); + // Get cpu time. On MPI systems, if constructed with an mpi_communicator + // like MPI_COMM_WORLD, then the Timer will sum up the CPU time between + // processors among the provided mpi_communicator. Therefore, no + // communication is needed here. + const double cpu_time = sections[actual_section_name].timer(); + sections[actual_section_name].total_cpu_time += cpu_time; // in case we have to print out something, do that here... if ((output_frequency == every_call || output_frequency == every_call_and_summary) @@ -464,7 +467,8 @@ TimerOutput::print_summary () const i = sections.begin(); i!=sections.end(); ++i) check_time += i->second.total_cpu_time; - if (check_time > total_cpu_time) + const double time_gap = check_time-total_cpu_time; + if (time_gap > 0.0) total_cpu_time = check_time; // generate a nice table @@ -512,9 +516,10 @@ TimerOutput::print_summary () const << "------------+------------+\n" << std::endl; - if (check_time > total_cpu_time) + if (time_gap > 0.0) out_stream << std::endl - << "Note: The sum of counted times is larger than the total time.\n" + << "Note: The sum of counted times is " << time_gap + << " seconds larger than the total time.\n" << "(Timer function may have introduced too much overhead, or different\n" << "section timers may have run at the same time.)" << std::endl; } -- 2.39.5