moab
|
00001 00013 #ifndef SPATIALLOCATORTIMES_HPP 00014 #define SPATIALLOCATORTIMES_HPP 00015 00016 #include "moab/Interface.hpp" 00017 00018 #include <iostream> 00019 00020 #ifdef USE_MPI 00021 #include "moab_mpi.h" 00022 #endif 00023 00024 namespace moab 00025 { 00026 class SpatialLocatorTimes 00027 { 00028 public: 00029 /* constructor 00030 */ 00031 SpatialLocatorTimes() {reset();} 00032 00033 /* \brief Reset all stats defined here 00034 */ 00035 void reset(); 00036 00037 /* \brief Output header for stats names 00038 */ 00039 void output_header(bool print_endl = false) const; 00040 00041 /* \brief Output stats all on one line 00042 */ 00043 void output(bool print_head = false, bool print_endl = false) const; 00044 00045 #ifdef USE_MPI 00046 /* \brief Accumulate times over all processors into provided array 00047 * Max and min is accumulated over all processors, onto root, for each stat. If avg_stats is non-NULL, 00048 * all stats are gathered to root so average can be taken too. 00049 * 00050 * This function must be called collectively on the communicator 00051 * \param comm MPI communictor over which this accumulation is done 00052 * \param max_times Array of size NUM_STATS into which max times are inserted 00053 * \param min_times Array of size NUM_STATS into which min times are inserted 00054 * \param avg_times Array of size NUM_STATS into which avg times are inserted; if NULL, no avg times are computed. 00055 00056 */ 00057 ErrorCode accumulate_times(MPI_Comm comm, double *max_times, double *min_times, 00058 double *avg_times = NULL); 00059 #endif 00060 00061 /* \brief Enumeration to identify fields in performance data 00062 */ 00063 enum {INTMED_INIT = 0, // time to compute intermediate partition, incl global bounding box 00064 INTMED_SEND, // time to send search points from target to intermediate parts 00065 INTMED_SEARCH, // time to find candidate src boxes for search points on intermidiate procs 00066 SRC_SEND, // time to send search points to src procs 00067 SRC_SEARCH, // time to search local box/elements on src procs 00068 TARG_RETURN, // time to return point location data to target procs 00069 TARG_STORE, // time to store point location into local SpatialLocator object 00070 NUM_STATS // number of stats, useful for array sizing and terminating loops over stats 00071 }; 00072 00073 double slTimes[NUM_STATS]; 00074 }; 00075 00076 inline void SpatialLocatorTimes::reset() 00077 { 00078 for (int i = 0; i < NUM_STATS; i++) slTimes[i] = 0.0; 00079 } 00080 00081 #ifdef USE_MPI 00082 inline ErrorCode SpatialLocatorTimes::accumulate_times(MPI_Comm comm, 00083 double *min_times, double *max_times, double *avg_times) 00084 { 00085 ErrorCode rval = MB_SUCCESS; 00086 int success = MPI_Reduce(slTimes, min_times, NUM_STATS, MPI_DOUBLE, MPI_MIN, 0, comm); 00087 if (!success) rval = MB_FAILURE; 00088 00089 success = MPI_Reduce(slTimes, max_times, NUM_STATS, MPI_DOUBLE, MPI_MAX, 0, comm); 00090 if (!success) rval = MB_FAILURE; 00091 00092 if (avg_times) { 00093 int sz, rank; 00094 MPI_Comm_size(comm, &sz); 00095 MPI_Comm_rank(comm, &rank); 00096 std::vector<double> all_times; 00097 if (!rank) all_times.resize(NUM_STATS*sz+NUM_STATS); 00098 success = MPI_Gather(slTimes, NUM_STATS, MPI_DOUBLE, (rank ? NULL : &all_times[0]), NUM_STATS, MPI_DOUBLE, 0, comm); 00099 if (!success) rval = MB_FAILURE; 00100 if (!rank) { 00101 std::fill(avg_times, avg_times+NUM_STATS, 0.0); 00102 for (int p = 0; p < sz; p++) { 00103 for (int s = 0; s < NUM_STATS; s++) 00104 avg_times[s] += all_times[p*NUM_STATS+s]; 00105 } 00106 00107 for (int s = 0; s <= NUM_STATS; s++) avg_times[s] /= (double)sz; 00108 } 00109 } 00110 00111 return rval; 00112 } 00113 #endif 00114 00115 /* \brief Output stats all on one line 00116 */ 00117 inline void SpatialLocatorTimes::output_header(bool print_endl) const 00118 { 00119 std::cout << "Intmed_init Intmed_send Intmed_search src_send src_search targ_return targ_store"; 00120 if (print_endl) std::cout << std::endl; 00121 } 00122 00123 /* \brief Output stats all on one line 00124 */ 00125 inline void SpatialLocatorTimes::output(bool print_head, bool print_endl) const 00126 { 00127 if (print_head) output_header(true); 00128 for (int i = 0; i < NUM_STATS; i++) std::cout << slTimes[i] << " "; 00129 00130 if (print_endl) std::cout << std::endl; 00131 } 00132 00133 00134 } // namespace moab 00135 00136 #endif 00137 00138