Reference documentation for deal.II version 9.1.0-pre
timer.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/exceptions.h>
17 #include <deal.II/base/mpi.h>
18 #include <deal.II/base/signaling_nan.h>
19 #include <deal.II/base/thread_management.h>
20 #include <deal.II/base/timer.h>
21 #include <deal.II/base/utilities.h>
22 
23 #include <algorithm>
24 #include <chrono>
25 #include <iomanip>
26 #include <iostream>
27 #include <map>
28 #include <sstream>
29 #include <string>
30 #include <type_traits>
31 
32 #ifdef DEAL_II_HAVE_SYS_RESOURCE_H
33 # include <sys/resource.h>
34 #endif
35 
36 #ifdef DEAL_II_MSVC
37 # include <windows.h>
38 #endif
39 
40 
41 
42 DEAL_II_NAMESPACE_OPEN
43 
44 namespace internal
45 {
46  namespace TimerImplementation
47  {
48  namespace
49  {
54  template <typename T>
55  struct is_duration : std::false_type
56  {};
57 
61  template <typename Rep, typename Period>
62  struct is_duration<std::chrono::duration<Rep, Period>> : std::true_type
63  {};
64 
70  template <typename T>
71  T
72  from_seconds(const double time)
73  {
74  static_assert(is_duration<T>::value,
75  "The template type should be a duration type.");
76  return T(std::lround(T::period::den * (time / T::period::num)));
77  }
78 
83  template <typename Rep, typename Period>
84  double
85  to_seconds(const std::chrono::duration<Rep, Period> duration)
86  {
87  return Period::num * double(duration.count()) / Period::den;
88  }
89 
93  void
94  clear_timing_data(Utilities::MPI::MinMaxAvg &data)
95  {
96  data.sum = numbers::signaling_nan<double>();
97  data.min = numbers::signaling_nan<double>();
98  data.max = numbers::signaling_nan<double>();
99  data.avg = numbers::signaling_nan<double>();
102  }
103  } // namespace
104  } // namespace TimerImplementation
105 } // namespace internal
106 
107 
108 
110 CPUClock::now() noexcept
111 {
112  double system_cpu_duration = 0.0;
113 #ifdef DEAL_II_MSVC
114  FILETIME cpuTime, sysTime, createTime, exitTime;
115  const auto succeeded = GetProcessTimes(
116  GetCurrentProcess(), &createTime, &exitTime, &sysTime, &cpuTime);
117  if (succeeded)
118  {
119  system_cpu_duration =
120  (double)(((unsigned long long)cpuTime.dwHighDateTime << 32) |
121  cpuTime.dwLowDateTime) /
122  1e7;
123  }
124  // keep the zero value if GetProcessTimes didn't work
125 #elif defined(DEAL_II_HAVE_SYS_RESOURCE_H)
126  rusage usage;
127  getrusage(RUSAGE_SELF, &usage);
128  system_cpu_duration = usage.ru_utime.tv_sec + 1.e-6 * usage.ru_utime.tv_usec;
129 #else
130  DEAL_II_WARNING("Unsupported platform. Porting not finished.")
131 #endif
132  return time_point(
133  internal::TimerImplementation::from_seconds<duration>(system_cpu_duration));
134 }
135 
136 
137 
138 template <typename clock_type_>
140  : current_lap_start_time(clock_type::now())
141  , accumulated_time(duration_type::zero())
142  , last_lap_time(duration_type::zero())
143 {}
144 
145 
146 
147 template <typename clock_type_>
148 void
150 {
151  current_lap_start_time = clock_type::now();
152  accumulated_time = duration_type::zero();
153  last_lap_time = duration_type::zero();
154 }
155 
156 
157 
159  : Timer(MPI_COMM_SELF, /*sync_lap_times=*/false)
160 {}
161 
162 
163 
164 Timer::Timer(MPI_Comm mpi_communicator, const bool sync_lap_times_)
165  : running(false)
166  , mpi_communicator(mpi_communicator)
167  , sync_lap_times(sync_lap_times_)
168 {
169  reset();
170  start();
171 }
172 
173 
174 
175 void
177 {
178  running = true;
179 #ifdef DEAL_II_WITH_MPI
180  if (sync_lap_times)
181  {
182  const int ierr = MPI_Barrier(mpi_communicator);
183  AssertThrowMPI(ierr);
184  }
185 #endif
186  wall_times.current_lap_start_time = wall_clock_type::now();
187  cpu_times.current_lap_start_time = cpu_clock_type::now();
188 }
189 
190 
191 
192 double
194 {
195  if (running)
196  {
197  running = false;
198 
200  wall_clock_type::now() - wall_times.current_lap_start_time;
201  cpu_times.last_lap_time =
202  cpu_clock_type::now() - cpu_times.current_lap_start_time;
203 
205  Utilities::MPI::min_max_avg(internal::TimerImplementation::to_seconds(
208  if (sync_lap_times)
209  {
211  internal::TimerImplementation::from_seconds<decltype(
212  wall_times)::duration_type>(last_lap_wall_time_data.max);
213  cpu_times.last_lap_time =
214  internal::TimerImplementation::from_seconds<decltype(
215  cpu_times)::duration_type>(
217  internal::TimerImplementation::to_seconds(
218  cpu_times.last_lap_time),
220  .max);
221  }
223  cpu_times.accumulated_time += cpu_times.last_lap_time;
225  Utilities::MPI::min_max_avg(internal::TimerImplementation::to_seconds(
228  }
229  return internal::TimerImplementation::to_seconds(cpu_times.accumulated_time);
230 }
231 
232 
233 
234 double
236 {
237  if (running)
238  {
239  const double running_time = internal::TimerImplementation::to_seconds(
240  cpu_clock_type::now() - cpu_times.current_lap_start_time +
241  cpu_times.accumulated_time);
242  return Utilities::MPI::sum(running_time, mpi_communicator);
243  }
244  else
245  {
246  return Utilities::MPI::sum(internal::TimerImplementation::to_seconds(
247  cpu_times.accumulated_time),
249  }
250 }
251 
252 
253 
254 double
256 {
257  return internal::TimerImplementation::to_seconds(cpu_times.last_lap_time);
258 }
259 
260 
261 
262 double
264 {
265  return internal::TimerImplementation::to_seconds(wall_times.last_lap_time);
266 }
267 
268 
269 
270 double
272 {
273  return cpu_time();
274 }
275 
276 
277 
278 double
280 {
281  wall_clock_type::duration current_elapsed_wall_time;
282  if (running)
283  current_elapsed_wall_time = wall_clock_type::now() -
286  else
287  current_elapsed_wall_time = wall_times.accumulated_time;
288 
289  return internal::TimerImplementation::to_seconds(current_elapsed_wall_time);
290 }
291 
292 
293 
294 double
296 {
297  return internal::TimerImplementation::to_seconds(wall_times.last_lap_time);
298 }
299 
300 
301 
302 void
304 {
305  wall_times.reset();
306  cpu_times.reset();
307  running = false;
308  internal::TimerImplementation::clear_timing_data(last_lap_wall_time_data);
309  internal::TimerImplementation::clear_timing_data(accumulated_wall_time_data);
310 }
311 
312 
313 
314 /* ---------------------------- TimerOutput -------------------------- */
315 
316 TimerOutput::TimerOutput(std::ostream & stream,
317  const OutputFrequency output_frequency,
318  const OutputType output_type)
319  : output_frequency(output_frequency)
320  , output_type(output_type)
321  , out_stream(stream, true)
322  , output_is_enabled(true)
323  , mpi_communicator(MPI_COMM_SELF)
324 {}
325 
326 
327 
330  const OutputType output_type)
331  : output_frequency(output_frequency)
332  , output_type(output_type)
333  , out_stream(stream)
334  , output_is_enabled(true)
335  , mpi_communicator(MPI_COMM_SELF)
336 {}
337 
338 
339 
341  std::ostream & stream,
343  const OutputType output_type)
344  : output_frequency(output_frequency)
345  , output_type(output_type)
346  , out_stream(stream, true)
347  , output_is_enabled(true)
348  , mpi_communicator(mpi_communicator)
349 {}
350 
351 
352 
354  ConditionalOStream & stream,
356  const OutputType output_type)
357  : output_frequency(output_frequency)
358  , output_type(output_type)
359  , out_stream(stream)
360  , output_is_enabled(true)
361  , mpi_communicator(mpi_communicator)
362 {}
363 
364 
365 
367 {
368  auto do_exit = [this]() {
369  try
370  {
371  while (active_sections.size() > 0)
373  // don't print unless we leave all subsections
374  if ((output_frequency == summary ||
376  output_is_enabled == true)
377  print_summary();
378  }
379  catch (...)
380  {}
381  };
382 
383  // avoid communicating with other processes if there is an uncaught
384  // exception
385 #ifdef DEAL_II_WITH_MPI
386  if (std::uncaught_exception() && mpi_communicator != MPI_COMM_SELF)
387  {
388  std::cerr << "---------------------------------------------------------"
389  << std::endl
390  << "TimerOutput objects finalize timed values printed to the"
391  << std::endl
392  << "screen by communicating over MPI in their destructors."
393  << std::endl
394  << "Since an exception is currently uncaught, this" << std::endl
395  << "synchronization (and subsequent output) will be skipped to"
396  << std::endl
397  << "avoid a possible deadlock." << std::endl
398  << "---------------------------------------------------------"
399  << std::endl;
400  }
401  else
402  {
403  do_exit();
404  }
405 #else
406  do_exit();
407 #endif
408 }
409 
410 
411 
412 void
413 TimerOutput::enter_subsection(const std::string &section_name)
414 {
416 
417  Assert(section_name.empty() == false, ExcMessage("Section string is empty."));
418 
419  Assert(std::find(active_sections.begin(),
420  active_sections.end(),
421  section_name) == active_sections.end(),
422  ExcMessage(std::string("Cannot enter the already active section <") +
423  section_name + ">."));
424 
425  if (sections.find(section_name) == sections.end())
426  {
427  if (mpi_communicator != MPI_COMM_SELF)
428  {
429  // create a new timer for this section. the second argument
430  // will ensure that we have an MPI barrier before starting
431  // and stopping a timer, and this ensures that we get the
432  // maximum run time for this section over all processors.
433  // The mpi_communicator from TimerOutput is passed to the
434  // Timer here, so this Timer will collect timing information
435  // among all processes inside mpi_communicator.
436  sections[section_name].timer = Timer(mpi_communicator, true);
437  }
438 
439 
440  sections[section_name].total_cpu_time = 0;
441  sections[section_name].total_wall_time = 0;
442  sections[section_name].n_calls = 0;
443  }
444 
445  sections[section_name].timer.reset();
446  sections[section_name].timer.start();
447  sections[section_name].n_calls++;
448 
449  active_sections.push_back(section_name);
450 }
451 
452 
453 
454 void
455 TimerOutput::leave_subsection(const std::string &section_name)
456 {
457  Assert(!active_sections.empty(),
458  ExcMessage("Cannot exit any section because none has been entered!"));
459 
461 
462  if (section_name != "")
463  {
464  Assert(sections.find(section_name) != sections.end(),
465  ExcMessage("Cannot delete a section that was never created."));
466  Assert(std::find(active_sections.begin(),
467  active_sections.end(),
468  section_name) != active_sections.end(),
469  ExcMessage("Cannot delete a section that has not been entered."));
470  }
471 
472  // if no string is given, exit the last
473  // active section.
474  const std::string actual_section_name =
475  (section_name == "" ? active_sections.back() : section_name);
476 
477  sections[actual_section_name].timer.stop();
478  sections[actual_section_name].total_wall_time +=
479  sections[actual_section_name].timer.last_wall_time();
480 
481  // Get cpu time. On MPI systems, if constructed with an mpi_communicator
482  // like MPI_COMM_WORLD, then the Timer will sum up the CPU time between
483  // processors among the provided mpi_communicator. Therefore, no
484  // communication is needed here.
485  const double cpu_time = sections[actual_section_name].timer.last_cpu_time();
486  sections[actual_section_name].total_cpu_time += cpu_time;
487 
488  // in case we have to print out something, do that here...
489  if ((output_frequency == every_call ||
491  output_is_enabled == true)
492  {
493  std::string output_time;
494  std::ostringstream cpu;
495  cpu << cpu_time << "s";
496  std::ostringstream wall;
497  wall << sections[actual_section_name].timer.last_wall_time() << "s";
498  if (output_type == cpu_times)
499  output_time = ", CPU time: " + cpu.str();
500  else if (output_type == wall_times)
501  output_time = ", wall time: " + wall.str() + ".";
502  else
503  output_time =
504  ", CPU/wall time: " + cpu.str() + " / " + wall.str() + ".";
505 
506  out_stream << actual_section_name << output_time << std::endl;
507  }
508 
509  // delete the index from the list of
510  // active ones
511  active_sections.erase(std::find(active_sections.begin(),
512  active_sections.end(),
513  actual_section_name));
514 }
515 
516 
517 
518 std::map<std::string, double>
520 {
521  std::map<std::string, double> output;
522  for (const auto &section : sections)
523  {
524  switch (kind)
525  {
526  case TimerOutput::OutputData::total_cpu_time:
527  output[section.first] = section.second.total_cpu_time;
528  break;
529  case TimerOutput::OutputData::total_wall_time:
530  output[section.first] = section.second.total_wall_time;
531  break;
532  case TimerOutput::OutputData::n_calls:
533  output[section.first] = section.second.n_calls;
534  break;
535  default:
536  Assert(false, ExcNotImplemented());
537  }
538  }
539  return output;
540 }
541 
542 
543 
544 void
546 {
547  // we are going to change the precision and width of output below. store the
548  // old values so we can restore it later on
549  const std::istream::fmtflags old_flags = out_stream.get_stream().flags();
550  const std::streamsize old_precision = out_stream.get_stream().precision();
551  const std::streamsize old_width = out_stream.get_stream().width();
552 
553  // get the maximum width among all sections
554  unsigned int max_width = 0;
555  for (const auto &i : sections)
556  max_width = std::max(max_width, (unsigned int)i.first.length());
557 
558  // 32 is the default width until | character
559  max_width = std::max(max_width + 1, (unsigned int)32);
560  const std::string extra_dash = std::string(max_width - 32, '-');
561  const std::string extra_space = std::string(max_width - 32, ' ');
562 
564  {
565  // in case we want to write CPU times
566  if (output_type != wall_times)
567  {
568  double total_cpu_time =
570 
571  // check that the sum of all times is less or equal than the total
572  // time. otherwise, we might have generated a lot of overhead in this
573  // function.
574  double check_time = 0.;
575  for (const auto &i : sections)
576  check_time += i.second.total_cpu_time;
577 
578  const double time_gap = check_time - total_cpu_time;
579  if (time_gap > 0.0)
580  total_cpu_time = check_time;
581 
582  // generate a nice table
583  out_stream << "\n\n"
584  << "+---------------------------------------------"
585  << extra_dash << "+------------"
586  << "+------------+\n"
587  << "| Total CPU time elapsed since start "
588  << extra_space << "|";
589  out_stream << std::setw(10) << std::setprecision(3) << std::right;
590  out_stream << total_cpu_time << "s | |\n";
591  out_stream << "| "
592  << extra_space << "| "
593  << "| |\n";
594  out_stream << "| Section " << extra_space
595  << "| no. calls |";
596  out_stream << std::setw(10);
597  out_stream << std::setprecision(3);
598  out_stream << " CPU time "
599  << " | % of total |\n";
600  out_stream << "+---------------------------------" << extra_dash
601  << "+-----------+------------"
602  << "+------------+";
603  for (const auto &i : sections)
604  {
605  std::string name_out = i.first;
606 
607  // resize the array so that it is always of the same size
608  unsigned int pos_non_space = name_out.find_first_not_of(' ');
609  name_out.erase(0, pos_non_space);
610  name_out.resize(max_width, ' ');
611  out_stream << std::endl;
612  out_stream << "| " << name_out;
613  out_stream << "| ";
614  out_stream << std::setw(9);
615  out_stream << i.second.n_calls << " |";
616  out_stream << std::setw(10);
617  out_stream << std::setprecision(3);
618  out_stream << i.second.total_cpu_time << "s |";
619  out_stream << std::setw(10);
620  if (total_cpu_time != 0)
621  {
622  // if run time was less than 0.1%, just print a zero to avoid
623  // printing silly things such as "2.45e-6%". otherwise print
624  // the actual percentage
625  const double fraction =
626  i.second.total_cpu_time / total_cpu_time;
627  if (fraction > 0.001)
628  {
629  out_stream << std::setprecision(2);
630  out_stream << fraction * 100;
631  }
632  else
633  out_stream << 0.0;
634 
635  out_stream << "% |";
636  }
637  else
638  out_stream << 0.0 << "% |";
639  }
640  out_stream << std::endl
641  << "+---------------------------------" << extra_dash
642  << "+-----------+"
643  << "------------+------------+\n"
644  << std::endl;
645 
646  if (time_gap > 0.0)
647  out_stream
648  << std::endl
649  << "Note: The sum of counted times is " << time_gap
650  << " seconds larger than the total time.\n"
651  << "(Timer function may have introduced too much overhead, or different\n"
652  << "section timers may have run at the same time.)" << std::endl;
653  }
654 
655  // in case we want to write out wallclock times
656  if (output_type != cpu_times)
657  {
659 
660  // now generate a nice table
661  out_stream << "\n\n"
662  << "+---------------------------------------------"
663  << extra_dash << "+------------"
664  << "+------------+\n"
665  << "| Total wallclock time elapsed since start "
666  << extra_space << "|";
667  out_stream << std::setw(10) << std::setprecision(3) << std::right;
668  out_stream << total_wall_time << "s | |\n";
669  out_stream << "| "
670  << extra_space << "| "
671  << "| |\n";
672  out_stream << "| Section " << extra_space
673  << "| no. calls |";
674  out_stream << std::setw(10);
675  out_stream << std::setprecision(3);
676  out_stream << " wall time | % of total |\n";
677  out_stream << "+---------------------------------" << extra_dash
678  << "+-----------+------------"
679  << "+------------+";
680  for (const auto &i : sections)
681  {
682  std::string name_out = i.first;
683 
684  // resize the array so that it is always of the same size
685  unsigned int pos_non_space = name_out.find_first_not_of(' ');
686  name_out.erase(0, pos_non_space);
687  name_out.resize(max_width, ' ');
688  out_stream << std::endl;
689  out_stream << "| " << name_out;
690  out_stream << "| ";
691  out_stream << std::setw(9);
692  out_stream << i.second.n_calls << " |";
693  out_stream << std::setw(10);
694  out_stream << std::setprecision(3);
695  out_stream << i.second.total_wall_time << "s |";
696  out_stream << std::setw(10);
697 
698  if (total_wall_time != 0)
699  {
700  // if run time was less than 0.1%, just print a zero to avoid
701  // printing silly things such as "2.45e-6%". otherwise print
702  // the actual percentage
703  const double fraction =
704  i.second.total_wall_time / total_wall_time;
705  if (fraction > 0.001)
706  {
707  out_stream << std::setprecision(2);
708  out_stream << fraction * 100;
709  }
710  else
711  out_stream << 0.0;
712 
713  out_stream << "% |";
714  }
715  else
716  out_stream << 0.0 << "% |";
717  }
718  out_stream << std::endl
719  << "+---------------------------------" << extra_dash
720  << "+-----------+"
721  << "------------+------------+\n"
722  << std::endl;
723  }
724  }
725  else
726  // output_type == cpu_and_wall_times_grouped
727  {
728  const double total_wall_time = timer_all.wall_time();
729  double total_cpu_time =
731 
732  // check that the sum of all times is less or equal than the total time.
733  // otherwise, we might have generated a lot of overhead in this function.
734  double check_time = 0.;
735 
736  for (const auto &i : sections)
737  check_time += i.second.total_cpu_time;
738 
739  const double time_gap = check_time - total_cpu_time;
740  if (time_gap > 0.0)
741  total_cpu_time = check_time;
742 
743  // generate a nice table
744  out_stream << "\n\n+---------------------------------------------"
745  << extra_dash << "+"
746  << "------------+------------+"
747  << "------------+------------+"
748  << "\n"
749  << "| Total CPU/wall time elapsed since start "
750  << extra_space << "|" << std::setw(10) << std::setprecision(3)
751  << std::right << total_cpu_time << "s | |"
752  << total_wall_time << "s | |"
753  << "\n| "
754  << extra_space << "|"
755  << " | |"
756  << " | |"
757  << "\n| Section " << extra_space
758  << "| no. calls |"
759  << " CPU time | % of total |"
760  << " wall time | % of total |"
761  << "\n+---------------------------------" << extra_dash
762  << "+-----------+"
763  << "------------+------------+"
764  << "------------+------------+" << std::endl;
765 
766  for (const auto &i : sections)
767  {
768  std::string name_out = i.first;
769 
770  // resize the array so that it is always of the same size
771  unsigned int pos_non_space = name_out.find_first_not_of(' ');
772  name_out.erase(0, pos_non_space);
773  name_out.resize(max_width, ' ');
774  out_stream << "| " << name_out << "| ";
775 
776  out_stream << std::setw(9);
777  out_stream << i.second.n_calls << " |";
778 
779  if (output_type != wall_times)
780  {
781  out_stream << std::setw(10);
782  out_stream << std::setprecision(3);
783  out_stream << i.second.total_cpu_time << "s |";
784  out_stream << std::setw(10);
785  if (total_cpu_time != 0)
786  {
787  // if run time was less than 0.1%, just print a zero to avoid
788  // printing silly things such as "2.45e-6%". otherwise print
789  // the actual percentage
790  const double fraction =
791  i.second.total_cpu_time / total_cpu_time;
792  if (fraction > 0.001)
793  {
794  out_stream << std::setprecision(2);
795  out_stream << fraction * 100;
796  }
797  else
798  out_stream << 0.0;
799 
800  out_stream << "% |";
801  }
802  else
803  out_stream << 0.0 << "% |";
804  }
805 
806  if (output_type != cpu_times)
807  {
808  out_stream << std::setw(10);
809  out_stream << std::setprecision(3);
810  out_stream << i.second.total_wall_time << "s |";
811  out_stream << std::setw(10);
812 
813  if (total_wall_time != 0)
814  {
815  // if run time was less than 0.1%, just print a zero to avoid
816  // printing silly things such as "2.45e-6%". otherwise print
817  // the actual percentage
818  const double fraction =
819  i.second.total_wall_time / total_wall_time;
820  if (fraction > 0.001)
821  {
822  out_stream << std::setprecision(2);
823  out_stream << fraction * 100;
824  }
825  else
826  out_stream << 0.0;
827 
828  out_stream << "% |";
829  }
830  else
831  out_stream << 0.0 << "% |";
832  }
833  out_stream << std::endl;
834  }
835 
836  out_stream << "+---------------------------------" << extra_dash
837  << "+-----------+"
838  << "------------+------------+"
839  << "------------+------------+" << std::endl
840  << std::endl;
841 
842  if (output_type != wall_times && time_gap > 0.0)
843  out_stream
844  << std::endl
845  << "Note: The sum of counted times is " << time_gap
846  << " seconds larger than the total time.\n"
847  << "(Timer function may have introduced too much overhead, or different\n"
848  << "section timers may have run at the same time.)" << std::endl;
849  }
850 
851  // restore previous precision and width
852  out_stream.get_stream().precision(old_precision);
853  out_stream.get_stream().width(old_width);
854  out_stream.get_stream().flags(old_flags);
855 }
856 
857 
858 
859 void
861 {
862  output_is_enabled = false;
863 }
864 
865 
866 
867 void
869 {
870  output_is_enabled = true;
871 }
872 
873 void
875 {
877  sections.clear();
878  active_sections.clear();
879  timer_all.restart();
880 }
881 
883 {
884  try
885  {
886  stop();
887  }
888  catch (...)
889  {}
890 }
891 
892 
893 DEAL_II_NAMESPACE_CLOSE
void reset()
Definition: timer.cc:874
static const unsigned int invalid_unsigned_int
Definition: types.h:173
MPI_Comm mpi_communicator
Definition: timer.h:907
clock_type_ clock_type
Definition: timer.h:325
void reset()
Definition: timer.cc:303
MPI_Comm mpi_communicator
Definition: timer.h:397
double last_cpu_time() const
Definition: timer.cc:255
STL namespace.
static time_point now() noexcept
Definition: timer.cc:110
double stop()
Definition: timer.cc:193
Timer timer_all
Definition: timer.h:866
std::ostream & get_stream() const
Threads::Mutex mutex
Definition: timer.h:913
OutputType output_type
Definition: timer.h:859
bool output_is_enabled
Definition: timer.h:894
Utilities::MPI::MinMaxAvg last_lap_wall_time_data
Definition: timer.h:410
bool sync_lap_times
Definition: timer.h:403
static::ExceptionBase & ExcMessage(std::string arg1)
T sum(const T &t, const MPI_Comm &mpi_communicator)
#define Assert(cond, exc)
Definition: exceptions.h:1227
duration_type accumulated_time
Definition: timer.h:346
Timer()
Definition: timer.cc:158
typename clock_type::duration duration_type
Definition: timer.h:335
OutputFrequency
Definition: timer.h:630
ClockMeasurements< wall_clock_type > wall_times
Definition: timer.h:380
void disable_output()
Definition: timer.cc:860
bool running
Definition: timer.h:390
duration_type last_lap_time
Definition: timer.h:351
std::list< std::string > active_sections
Definition: timer.h:902
void start()
Definition: timer.cc:176
double last_wall_time() const
Definition: timer.cc:295
void restart()
Definition: timer.h:922
double get_lap_time() const
Definition: timer.cc:263
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1443
TimerOutput(std::ostream &stream, const OutputFrequency output_frequency, const OutputType output_type)
Definition: timer.cc:316
std::map< std::string, Section > sections
Definition: timer.h:883
ConditionalOStream out_stream
Definition: timer.h:888
void enable_output()
Definition: timer.cc:868
double wall_time() const
Definition: timer.cc:279
double operator()() const
Definition: timer.cc:271
std::chrono::time_point< CPUClock, duration > time_point
Definition: timer.h:60
static::ExceptionBase & ExcNotImplemented()
Definition: timer.h:119
void enter_subsection(const std::string &section_name)
Definition: timer.cc:413
double cpu_time() const
Definition: timer.cc:235
void print_summary() const
Definition: timer.cc:545
MinMaxAvg min_max_avg(const double my_value, const MPI_Comm &mpi_communicator)
Definition: mpi.cc:341
OutputFrequency output_frequency
Definition: timer.h:854
time_point_type current_lap_start_time
Definition: timer.h:341
unsigned int min_index
Definition: mpi.h:400
Utilities::MPI::MinMaxAvg accumulated_wall_time_data
Definition: timer.h:418
~TimerOutput()
Definition: timer.cc:366
unsigned int max_index
Definition: mpi.h:410
std::map< std::string, double > get_summary_data(const OutputData kind) const
Definition: timer.cc:519
ClockMeasurements< cpu_clock_type > cpu_times
Definition: timer.h:385
void leave_subsection(const std::string &section_name=std::string())
Definition: timer.cc:455