00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __deal2__timer_h
00013 #define __deal2__timer_h
00014
00015 #include <deal.II/base/config.h>
00016 #include <deal.II/base/conditional_ostream.h>
00017 #include <deal.II/base/thread_management.h>
00018 #include <deal.II/base/utilities.h>
00019
00020 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00021 # include <mpi.h>
00022 #endif
00023
00024 #include <string>
00025 #include <list>
00026 #include <map>
00027
00028 DEAL_II_NAMESPACE_OPEN
00029
00071 class Timer
00072 {
00073 public:
00077 Timer ();
00078
00079 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00080
00104 Timer (MPI_Comm mpi_communicator,
00105 bool sync_wall_time = false);
00106
00113 const Utilities::MPI::MinMaxAvg & get_data() const;
00114
00118 template <class STREAM>
00119 void print_data(STREAM & stream) const;
00120
00121
00122 #endif
00123
00129 void start ();
00130
00136 double stop ();
00137
00142 void reset ();
00143
00150 void restart();
00151
00158 double operator() () const;
00159
00166 double wall_time () const;
00167
00168 private:
00169
00176 double start_time;
00177
00178
00199 double start_time_children;
00200
00207 double start_wall_time;
00208
00214 double cumulative_time;
00215
00222 double cumulative_wall_time;
00223
00228 bool running;
00229
00234 MPI_Comm mpi_communicator;
00235
00236 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00237
00241 bool sync_wall_time;
00242
00252 Utilities::System::MinMaxAvg mpi_data;
00253 #endif
00254 };
00255
00256
00257
00258
00320 class TimerOutput
00321 {
00322 public:
00328 enum OutputFrequency {every_call, summary, every_call_and_summary}
00329 output_frequency;
00330
00335 enum OutputType {cpu_times, wall_times, cpu_and_wall_times}
00336 output_type;
00337
00342 TimerOutput (std::ostream &stream,
00343 const enum OutputFrequency output_frequency,
00344 const enum OutputType output_type);
00345
00350 TimerOutput (ConditionalOStream &stream,
00351 const enum OutputFrequency output_frequency,
00352 const enum OutputType output_type);
00353
00354 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00355
00366 TimerOutput (MPI_Comm mpi_comm,
00367 std::ostream &stream,
00368 const enum OutputFrequency output_frequency,
00369 const enum OutputType output_type);
00370
00382 TimerOutput (MPI_Comm mpi_comm,
00383 ConditionalOStream &stream,
00384 const enum OutputFrequency output_frequency,
00385 const enum OutputType output_type);
00386
00387
00388
00389
00390 #endif
00391
00397 ~TimerOutput();
00398
00405 void enter_subsection (const std::string §ion_name);
00406
00410 void enter_section (const std::string §ion_name);
00411
00417 void leave_subsection (const std::string §ion_name = std::string());
00418
00422 void exit_section (const std::string §ion_name = std::string());
00423
00429 void print_summary () const;
00430
00440 void disable_output ();
00441
00453 void enable_output ();
00454
00455 private:
00462 Timer timer_all;
00463
00469 struct Section
00470 {
00471 Timer timer;
00472 double total_cpu_time;
00473 double total_wall_time;
00474 unsigned int n_calls;
00475 };
00476
00481 std::map<std::string, Section> sections;
00482
00487 ConditionalOStream out_stream;
00488
00494 bool output_is_enabled;
00495
00507 std::list<std::string> active_sections;
00508
00512 MPI_Comm mpi_communicator;
00513
00519 Threads::ThreadMutex mutex;
00520 };
00521
00522
00523
00524
00525
00526
00527 inline
00528 void Timer::restart ()
00529 {
00530 reset();
00531 start();
00532 }
00533
00534
00535
00536 #ifdef DEAL_II_COMPILER_SUPPORTS_MPI
00537
00538 inline
00539 const Utilities::System::MinMaxAvg &
00540 Timer::get_data() const
00541 {
00542 return mpi_data;
00543 }
00544
00545
00546
00547 template <class STREAM>
00548 inline
00549 void
00550 Timer::print_data(STREAM & stream) const
00551 {
00552 unsigned int my_id = ::Utilities::MPI::this_mpi_process(mpi_communicator);
00553 if (my_id==0)
00554 stream << mpi_data.max << " wall,"
00555 << " max @" << mpi_data.max_index
00556 << ", min=" << mpi_data.min << " @" << mpi_data.min_index
00557 << ", avg=" << mpi_data.avg
00558 << std::endl;
00559 }
00560
00561 #endif
00562
00563
00564
00565 inline
00566 void
00567 TimerOutput::enter_section (const std::string §ion_name)
00568 {
00569 enter_subsection(section_name);
00570 }
00571
00572
00573
00574 inline
00575 void
00576 TimerOutput::exit_section (const std::string §ion_name)
00577 {
00578 leave_subsection(section_name);
00579 }
00580
00581
00582 DEAL_II_NAMESPACE_CLOSE
00583
00584 #endif
00585