TECA
The Toolkit for Extreme Climate Analysis
teca_profiler.h
1 #ifndef teca_profiler_h
2 #define teca_profiler_h
3 
4 #include "teca_config.h"
5 #include "teca_mpi.h"
6 
7 #include <string>
8 #include <thread>
9 #include <ostream>
10 
11 
12 /// A class containing methods managing memory and time profiling.
13 /**
14  * Each timed event logs rank, event name, start and end time, and
15  * duration.
16  */
18 {
19 public:
20  // Initialize logging from environment variables, and/or the timer
21  // API below. This is a collective call with respect to the timer's
22  // communicator.
23  //
24  // If found in the environment the following variable override the
25  // the current settings
26  //
27  // PROFILER_ENABLE : bit mask turns on or off logging,
28  // 0x01 -- event profiling enabled
29  // 0x02 -- memory profiling enabled
30  // PROFILER_LOG_FILE : path to write timer log to
31  // MEMPROF_LOG_FILE : path to write memory profiler log to
32  // MEMPROF_INTERVAL : number of seconds between memory recordings
33  //
34  static int initialize();
35 
36  // Finalize the log. this is where logs are written and cleanup occurs.
37  // All processes in the communicator must call, and it must be called
38  // prior to MPI_Finalize.
39  static int finalize();
40 
41  // this can occur after MPI_Finalize. It should only be called by rank 0.
42  // Any remaining events will be appended to the log file. This is necessary
43  // to time MPI_Initialize/Finalize and log associated I/O.
44  static int flush();
45 
46  // Sets the communicator for MPI calls. This must be called prior to
47  // initialization.
48  // default value: MPI_COMM_NULL
49  static void set_communicator(MPI_Comm comm);
50 
51  // Sets the path to write the timer log to
52  // overridden by PROFILER_LOG_FILE environment variable
53  // default value; Timer.csv
54  static void set_timer_log_file(const std::string &file_name);
55 
56  // Sets the path to write the timer log to
57  // overridden by MEMPROF_LOG_FILE environment variable
58  // default value: MemProfLog.csv
59  static void set_mem_prof_log_file(const std::string &file_name);
60 
61  // Sets the number of seconds in between memory use recordings
62  // overridden by MEMPROF_INTERVAL environment variable.
63  static void set_mem_prof_interval(int interval);
64 
65  // Enable/Disable logging. Overridden by PROFILER_ENABLE environment
66  // variable. In the default format a CSV file is generated capturing each
67  // ranks timer events. default value: disabled
68  static void enable(int arg = 0x03);
69  static void disable();
70 
71  // return true if logging is enabled.
72  static bool enabled();
73 
74  // @brief Log start of an event.
75  //
76  // This marks the beginning of a event that must be logged. The @arg
77  // eventname must match when calling end_event() to mark the end of the
78  // event.
79  static int start_event(const char *eventname);
80 
81  // @brief Log end of a log-able event.
82  //
83  // This marks the end of a event that must be logged. The @arg eventname
84  // must match when calling end_event() to mark the end of the event.
85  static int end_event(const char *eventname);
86 
87  // write contents of the string to the file.
88  static int write_c_stdio(const char *file_name, const char *mode,
89  const std::string &str);
90 
91  // write contents of the string to the file in rank order
92  // the file is truncated first or created
93  static int write_mpi_io(MPI_Comm comm, const char *file_name,
94  const std::string &str);
95 
96  // checks to see if all active events have been ended.
97  // will report errors if not
98  static int validate();
99 
100  // setnd the current contents of the log to the stream
101  static int to_stream(std::ostream &os);
102 };
103 
104 /// A helper class that times it's life.
105 /**
106  * A timer event is created that starts at the object's construction and ends
107  * at its destruction. The pointer to the event name must be valid throughout
108  * the objects life.
109  */
110 template <int buffer_size>
112 {
113 public:
114  // logs an event named
115  // <class_name>::<method> port=<p>
116  teca_time_event(const char *class_name,
117  const char *method, int port) : eventname(buffer)
118  {
119  snprintf(buffer, buffer_size, "%s::%s port=%d",
120  class_name, method, port);
121  teca_profiler::start_event(eventname);
122  }
123 
124  // logs an event named
125  // <class_name>::<method>
126  teca_time_event(const char *class_name,
127  int n_threads, int n_reqs) : eventname(buffer)
128  {
129  snprintf(buffer, buffer_size,
130  "%s thread_pool process n_threads=%d n_reqs=%d",
131  class_name, n_threads, n_reqs);
132  teca_profiler::start_event(eventname);
133  }
134 
135 
136  // logs an event named:
137  // <class_name>::<method>
138  teca_time_event(const char *class_name,
139  const char *method) : eventname(buffer)
140  {
141  buffer[0] = '\0';
142  strcat(buffer, class_name);
143  strcat(buffer, method);
144  teca_profiler::start_event(eventname);
145  }
146 
147  // logs an event named:
148  // <name>
149  teca_time_event(const char *name) : eventname(name)
150  { teca_profiler::start_event(name); }
151 
152  ~teca_time_event()
153  { teca_profiler::end_event(this->eventname); }
154 
155 private:
156  char buffer[buffer_size];
157  const char *eventname;
158 };
159 
160 #if defined(TECA_ENABLE_PROFILER)
161 #define TECA_PROFILE_PIPELINE(_n, _alg, _meth, _port, _code) \
162 { \
163  teca_time_event<_n> event(_alg->get_class_name(), \
164  _meth, _port); \
165  _code \
166 }
167 
168 #define TECA_PROFILE_METHOD(_n, _alg, _meth, _code) \
169 { \
170  teca_time_event<_n> \
171  event(_alg->get_class_name(), "::" _meth); \
172  _code \
173 }
174 
175 #define TECA_PROFILE_THREAD_POOL(_n, _alg, _nt, _nr, _code) \
176 { \
177  teca_time_event<_n> \
178  event(_alg->get_class_name(), _nt, _nr); \
179  _code \
180 }
181 #else
182 #define TECA_PROFILE_PIPELINE(_n, _alg, _meth, _port, _code) \
183 { \
184  _code \
185 }
186 
187 #define TECA_PROFILE_METHOD(_n, _alg, _meth, _code) \
188 { \
189  _code \
190 }
191 
192 #define TECA_PROFILE_THREAD_POOL(_n, _alg, _nt, _nr, _code) \
193 { \
194  _code \
195 }
196 #endif
197 #endif
A class containing methods managing memory and time profiling.
Definition: teca_profiler.h:18
A helper class that times it's life.
Definition: teca_profiler.h:112
p_teca_error_handler error_handler TECA_EXPORT
The global error handler instance.