Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
SpatialLocatorTimes.hpp
Go to the documentation of this file.
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 {
27 {
28  public:
29  /* constructor
30  */
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 
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