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