vtf-logo

AdlibTiming.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ralf Deiterding, ralf@amroc.net
00005 // Randolf Rotta
00006 
00007 #ifndef ADLIB_TIMING_H
00008 #define ADLIB_TIMING_H
00009 
00017 #include <iostream>
00018 #include <vector>
00019 
00020 #ifndef WITH_MPI
00021 
00022 #include <sys/time.h>
00023 #include <time.h>
00024 inline static double MPI_Wtime() { 
00025   struct timeval t; 
00026   gettimeofday(&t,0); 
00027   return (double)t.tv_sec + ((double)t.tv_usec)*0.000001; 
00028 }
00029 
00030 #endif
00031 
00032 class AdlibTiming;
00033 extern AdlibTiming adlib_timing;
00034 
00035 #ifdef TIMING_ADLIB
00036 
00037 #define ADLIB_START_WATCH                         adlib_timing.start();
00038 #define ADLIB_END_WATCH(what)                     adlib_timing.stop(AdlibTiming::what);
00039 
00040 #define ADLIB_START_WATCH_WHOLE                   adlib_timing.start_timing();
00041 #define ADLIB_END_WATCH_WHOLE                     adlib_timing.stop(AdlibTiming::MISC);
00042 
00043 #else
00044 
00045 #define ADLIB_START_WATCH_WHOLE            
00046 #define ADLIB_START_WATCH                 
00047 #define ADLIB_END_WATCH(what)
00048 #define ADLIB_END_WATCH_WHOLE              
00049 
00050 #endif
00051 
00059 class AdlibTiming {
00060 public:
00064   enum TimingAccounts { 
00065     WHOLE, 
00066     
00067     MISC,
00068 
00069     /* user accounts */
00070     INITIALIZATION, INTEGRATION, ASSEMBLE, OUTPUT, 
00071     EXAMINE1, EXAMINE2, EXAMINE3, EXAMINE4,
00072 
00073     ELC_SNDBND_RCVPRS, 
00074 
00075     CPL_SEND_OVERHEAD, CPL_RECEIVE_OVERHEAD, 
00076 
00077     /* maker for internal use */
00078     _ACMAX };
00079 
00080 public:
00081   /***************************************************************************/
00082   /* timing functions */
00083 
00086   inline void start_timing() 
00087     { tos = &timestack[0]; *tos = 0.0; start_time = MPI_Wtime(); }
00088 
00091   inline void start() { add_time(); tos++; *tos = 0.0; }
00092 
00096   inline void stop(enum TimingAccounts account) 
00097     { add_time(); times[account] += *tos; calls[account]++; tos--; }
00098 
00099 protected:
00100   inline void add_time() {
00101     double end_time = MPI_Wtime();
00102     *tos += end_time - start_time; start_time = end_time;
00103   }
00104 
00105 public:
00106   /***************************************************************************/
00107   /* global report generation interface */
00108 
00111   static void collect(MPI_Comm Comm) { 
00112 #ifdef TIMING_ADLIB
00113     adlib_timing.collect_timing(Comm);
00114 #endif
00115   }
00116 
00117   static void print(std::ostream& os) { 
00118 #ifdef TIMING_ADLIB
00119     adlib_timing.print_local_times = false;
00120     adlib_timing.print_timing(os);
00121 #endif
00122   }
00123 
00124   static void print_local(std::ostream& os) { 
00125 #ifdef TIMING_ADLIB
00126     adlib_timing.print_local_times = true;
00127     adlib_timing.print_timing(os);
00128 #endif
00129   }
00130 
00133   void collect_timing(MPI_Comm Comm, enum TimingAccounts ac, 
00134                       double* stat_times) {
00135 #ifdef WITH_MPI
00136     MPI_Reduce(&times[ac], &stat_times[0], 1, MPI_DOUBLE, 
00137                MPI_MAX, 0, Comm);
00138     MPI_Reduce(&times[ac], &stat_times[1], 1, MPI_DOUBLE, 
00139                MPI_MIN, 0, Comm);
00140     MPI_Reduce(&times[ac], &stat_times[2], 1, MPI_DOUBLE, 
00141                MPI_SUM, 0, Comm);
00142  
00143     int procs;
00144     MPI_Comm_size(Comm, &procs);
00145     stat_times[2] /= procs;
00146 #else
00147     stat_times[0] = times[ac];
00148     stat_times[1] = times[ac];
00149     stat_times[2] = times[ac];
00150 #endif
00151   }
00152 
00155   void collect_timing(MPI_Comm Comm) {
00156     /* calculate summs */
00157     times[WHOLE] = calcsum(times, MISC, _ACMAX-1, 0.0);
00158     calls[WHOLE] = calcsum(calls, MISC, _ACMAX-1, (unsigned)0);
00159 
00160     /* collect values from all nodes */
00161     stat_times_max.resize(_ACMAX);
00162     stat_times_min.resize(_ACMAX);
00163     stat_times_avg.resize(_ACMAX);
00164 #ifdef WITH_MPI
00165     MPI_Reduce(&times[0], &stat_times_max[0], _ACMAX, MPI_DOUBLE, 
00166                MPI_MAX, 0, Comm);
00167     MPI_Reduce(&times[0], &stat_times_min[0], _ACMAX, MPI_DOUBLE, 
00168                MPI_MIN, 0, Comm);
00169     MPI_Reduce(&times[0], &stat_times_avg[0], _ACMAX, MPI_DOUBLE, 
00170                MPI_SUM, 0, Comm);
00171  
00172     int procs;
00173     MPI_Comm_size(Comm, &procs);
00174     for (int i=0; i<_ACMAX; i++)
00175       stat_times_avg[i] /= procs;
00176 #else
00177     stat_times_max = times;
00178     stat_times_min = times;
00179     stat_times_avg = times;
00180 #endif
00181   }
00182 
00186   void print_timing(std::ostream& os) {
00187     pl(os,"Initialization               ", INITIALIZATION);
00188     pl(os,"Integration                  ", INTEGRATION); 
00189     pl(os,"Assemble                     ", ASSEMBLE);
00190     pl(os,"ELC - sendrcv_()             ", ELC_SNDBND_RCVPRS,true);
00191     pl(os,"Coupling Send - Overhead     ", CPL_SEND_OVERHEAD,true);
00192     pl(os,"Coupling Receive - Overhead  ", CPL_RECEIVE_OVERHEAD,true);
00193     pl(os,"Output                       ", OUTPUT); 
00194     pl(os,"Examined in detail 1         ", EXAMINE1,true);
00195     pl(os,"Examined in detail 2         ", EXAMINE2,true);
00196     pl(os,"Examined in detail 3         ", EXAMINE3,true);
00197     pl(os,"Examined in detail 4         ", EXAMINE4,true);
00198     pl(os,"Misc                         ", MISC);
00199     pl(os,"Whole time                   ", WHOLE);
00200   }
00201 
00202 protected:
00206   template<typename T>
00207   inline T calcsum(typename std::vector<T> &data, 
00208                    int start, int end, T sum) {
00209     for (int i=start; i<=end; i++) sum += data[i];
00210     return sum;
00211   }
00212 
00215   inline void pl(std::ostream& OS, char *name,
00216                  enum TimingAccounts ac, bool opt=false) {
00217     char str[500];
00218     if (print_local_times) {
00219       if (opt && times[ac]==0.) return;
00220       std::sprintf(str, "   %s : %4.3fs (%3.2f%%)   calls: %4ix", 
00221                    name,
00222                    times[ac], (times[WHOLE]>0. ? 100.0*times[ac]/times[WHOLE] : 0.),
00223                    calls[ac]     
00224                    );
00225     } else {
00226       if (opt && stat_times_avg[ac]==0.) return;
00227       std::sprintf(str, "   %s : %4.3fs (%3.2f%%)   balance: %2.3f   diff: %4.2fs (%9.2fs - %4.2fs)", 
00228                    name,
00229                    stat_times_avg[ac], (stat_times_avg[WHOLE]>0. ? 
00230                                         100.0*stat_times_avg[ac]/stat_times_avg[WHOLE] : 0.),
00231                    (stat_times_avg[ac]>0. ? stat_times_max[ac] / stat_times_avg[ac] : 1.),
00232                    stat_times_max[ac] - stat_times_min[ac],
00233                    stat_times_max[ac], stat_times_min[ac]
00234                    );
00235     }
00236     OS << str << std::endl;
00237   }
00238 
00239 public:
00240   AdlibTiming() { 
00241     times.resize(_ACMAX, 0.0);
00242     calls.resize(_ACMAX, 0);
00243     timestack.resize(MAXRECURSIONS);
00244   }
00245 
00246 protected:
00247   std::vector<double> times; // [_ACMAX]
00248   std::vector<unsigned int> calls; // [_ACMAX]
00249   
00250   enum {MAXRECURSIONS=300};
00251   std::vector<double> timestack; // [MAXRECURSIONS]
00252   double *tos;
00253 
00255   bool print_local_times;
00256   std::vector<double> stat_times_max; // [_ACMAX]
00257   std::vector<double> stat_times_min; // [_ACMAX]
00258   std::vector<double> stat_times_avg; // [_ACMAX]
00259 
00260   double start_time;
00261 };
00262 
00263 #endif
00264 

Generated on Fri Aug 24 12:55:26 2007 for Adlib Finite Element Solver by  doxygen 1.4.7