1 /**\file SpatialLocatorTimes.hpp
2 * \class moab::SpatialLocatorTimes
3 * \brief Statistics for spatial location
4 *
5 * Class to accumulate statistics on performance of spatial location. This structure stores
6 * only local (single proc) statistics, but provides functions for accumulating max/min/avg
7 * time properties for performance reporting.
8 *
9 * Similar to TreeStats, this class is very lightweight, with most variables publicly accessible.
10 *
11 */
12
13 #ifndef SPATIALLOCATORTIMES_HPP
14 #define SPATIALLOCATORTIMES_HPP
15
16 #include "moab/Interface.hpp"
17
18 #include <iostream>
19
20 #ifdef MOAB_HAVE_MPI
21 #include "moab_mpi.h"
22 #endif
23
24 namespace moab
25 {
26 class SpatialLocatorTimes
27 {
28 public:
29 /* constructor
30 */
31 SpatialLocatorTimes()
32 {
33 reset();
34 }
35
36 /* \brief Reset all stats defined here
37 */
38 void reset();
39
40 /* \brief Output header for stats names
41 */
42 void output_header( bool print_endl = false ) const;
43
44 /* \brief Output stats all on one line
45 */
46 void output( bool print_head = false, bool print_endl = false ) const;
47
48 #ifdef MOAB_HAVE_MPI
49 /* \brief Accumulate times over all processors into provided array
50 * Max and min is accumulated over all processors, onto root, for each stat. If avg_stats is
51 non-NULL,
52 * all stats are gathered to root so average can be taken too.
53 *
54 * This function must be called collectively on the communicator
55 * \param comm MPI communictor over which this accumulation is done
56 * \param max_times Array of size NUM_STATS into which max times are inserted
57 * \param min_times Array of size NUM_STATS into which min times are inserted
58 * \param avg_times Array of size NUM_STATS into which avg times are inserted; if NULL, no avg
59 times are computed.
60
61 */
62 ErrorCode accumulate_times( MPI_Comm comm, double* max_times, double* min_times, double* avg_times = NULL );
63 #endif
64
65 /* \brief Enumeration to identify fields in performance data
66 */
67 enum
68 {
69 INTMED_INIT = 0, // time to compute intermediate partition, incl global bounding box
70 INTMED_SEND, // time to send search points from target to intermediate parts
71 INTMED_SEARCH, // time to find candidate src boxes for search points on intermidiate procs
72 SRC_SEND, // time to send search points to src procs
73 SRC_SEARCH, // time to search local box/elements on src procs
74 TARG_RETURN, // time to return point location data to target procs
75 TARG_STORE, // time to store point location into local SpatialLocator object
76 NUM_STATS // number of stats, useful for array sizing and terminating loops over stats
77 };
78
79 double slTimes[NUM_STATS];
80 };
81
82 inline void SpatialLocatorTimes::reset()
83 {
84 for( int i = 0; i < NUM_STATS; i++ )
85 slTimes[i] = 0.0;
86 }
87
88 #ifdef MOAB_HAVE_MPI
89 inline ErrorCode SpatialLocatorTimes::accumulate_times( MPI_Comm comm,
90 double* min_times,
91 double* max_times,
92 double* avg_times )
93 {
94 ErrorCode rval = MB_SUCCESS;
95 int success = MPI_Reduce( slTimes, min_times, NUM_STATS, MPI_DOUBLE, MPI_MIN, 0, comm );
96 if( !success ) rval = MB_FAILURE;
97
98 success = MPI_Reduce( slTimes, max_times, NUM_STATS, MPI_DOUBLE, MPI_MAX, 0, comm );
99 if( !success ) rval = MB_FAILURE;
100
101 if( avg_times )
102 {
103 int sz, rank;
104 MPI_Comm_size( comm, &sz );
105 MPI_Comm_rank( comm, &rank );
106 std::vector< double > all_times;
107 if( !rank ) all_times.resize( NUM_STATS * sz + NUM_STATS );
108 success = MPI_Gather( slTimes, NUM_STATS, MPI_DOUBLE, ( rank ? NULL : &all_times[0] ), NUM_STATS, MPI_DOUBLE, 0,
109 comm );
110 if( !success ) rval = MB_FAILURE;
111 if( !rank )
112 {
113 std::fill( avg_times, avg_times + NUM_STATS, 0.0 );
114 for( int p = 0; p < sz; p++ )
115 {
116 for( int s = 0; s < NUM_STATS; s++ )
117 avg_times[s] += all_times[p * NUM_STATS + s];
118 }
119
120 for( int s = 0; s <= NUM_STATS; s++ )
121 avg_times[s] /= (double)sz;
122 }
123 }
124
125 return rval;
126 }
127 #endif
128
129 /* \brief Output stats all on one line
130 */
131 inline void SpatialLocatorTimes::output_header( bool print_endl ) const
132 {
133 std::cout << "Intmed_init Intmed_send Intmed_search src_send src_search targ_return targ_store";
134 if( print_endl ) std::cout << std::endl;
135 }
136
137 /* \brief Output stats all on one line
138 */
139 inline void SpatialLocatorTimes::output( bool print_head, bool print_endl ) const
140 {
141 if( print_head ) output_header( true );
142 for( int i = 0; i < NUM_STATS; i++ )
143 std::cout << slTimes[i] << " ";
144
145 if( print_endl ) std::cout << std::endl;
146 }
147
148 } // namespace moab
149
150 #endif