LLVM OpenMP* Runtime Library
ompt-general.c
1 /*****************************************************************************
2  * system include files
3  ****************************************************************************/
4 
5 #include <assert.h>
6 
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 
13 
14 /*****************************************************************************
15  * ompt include files
16  ****************************************************************************/
17 
18 #include "ompt-internal.h"
19 #include "ompt-specific.c"
20 
21 
22 
23 /*****************************************************************************
24  * macros
25  ****************************************************************************/
26 
27 #define ompt_get_callback_success 1
28 #define ompt_get_callback_failure 0
29 
30 #define no_tool_present 0
31 
32 #define OMPT_API_ROUTINE static
33 
34 
35 
36 /*****************************************************************************
37  * types
38  ****************************************************************************/
39 
40 typedef struct {
41  const char *state_name;
42  ompt_state_t state_id;
43 } ompt_state_info_t;
44 
45 
46 
47 /*****************************************************************************
48  * global variables
49  ****************************************************************************/
50 
51 ompt_status_t ompt_status = ompt_status_ready;
52 
53 
54 ompt_state_info_t ompt_state_info[] = {
55 #define ompt_state_macro(state, code) { # state, state },
56  FOREACH_OMPT_STATE(ompt_state_macro)
57 #undef ompt_state_macro
58 };
59 
60 
61 ompt_callbacks_t ompt_callbacks;
62 
63 
64 
65 /*****************************************************************************
66  * forward declarations
67  ****************************************************************************/
68 
69 static ompt_interface_fn_t ompt_fn_lookup(const char *s);
70 
71 
72 /*****************************************************************************
73  * state
74  ****************************************************************************/
75 
76 OMPT_API_ROUTINE int ompt_enumerate_state(int current_state, int *next_state,
77  const char **next_state_name)
78 {
79  const static int len = sizeof(ompt_state_info) / sizeof(ompt_state_info_t);
80  int i = 0;
81 
82  for (i = 0; i < len - 1; i++) {
83  if (ompt_state_info[i].state_id == current_state) {
84  *next_state = ompt_state_info[i+1].state_id;
85  *next_state_name = ompt_state_info[i+1].state_name;
86  return 1;
87  }
88  }
89 
90  return 0;
91 }
92 
93 
94 
95 /*****************************************************************************
96  * callbacks
97  ****************************************************************************/
98 
99 OMPT_API_ROUTINE int ompt_set_callback(ompt_event_t evid, ompt_callback_t cb)
100 {
101  switch (evid) {
102 
103 #define ompt_event_macro(event_name, callback_type, event_id) \
104  case event_name: \
105  if (ompt_event_implementation_status(event_name)) { \
106  ompt_callbacks.ompt_callback(event_name) = (callback_type) cb; \
107  } \
108  return ompt_event_implementation_status(event_name);
109 
110  FOREACH_OMPT_EVENT(ompt_event_macro)
111 
112 #undef ompt_event_macro
113 
114  default: return ompt_set_result_registration_error;
115  }
116 }
117 
118 
119 OMPT_API_ROUTINE int ompt_get_callback(ompt_event_t evid, ompt_callback_t *cb)
120 {
121  switch (evid) {
122 
123 #define ompt_event_macro(event_name, callback_type, event_id) \
124  case event_name: \
125  if (ompt_event_implementation_status(event_name)) { \
126  ompt_callback_t mycb = \
127  (ompt_callback_t) ompt_callbacks.ompt_callback(event_name); \
128  if (mycb) { \
129  *cb = mycb; \
130  return ompt_get_callback_success; \
131  } \
132  } \
133  return ompt_get_callback_failure;
134 
135  FOREACH_OMPT_EVENT(ompt_event_macro)
136 
137 #undef ompt_event_macro
138 
139  default: return ompt_get_callback_failure;
140  }
141 }
142 
143 
144 
145 /*****************************************************************************
146  * intialization/finalization
147  ****************************************************************************/
148 
149 _OMP_EXTERN __attribute__ (( weak ))
150 int ompt_initialize(ompt_function_lookup_t ompt_fn_lookup, const char *version,
151  unsigned int ompt_version)
152 {
153  return no_tool_present;
154 }
155 
156 enum tool_setting_e {
157  omp_tool_error,
158  omp_tool_unset,
159  omp_tool_disabled,
160  omp_tool_enabled
161 };
162 
163 void ompt_init()
164 {
165  static int ompt_initialized = 0;
166 
167  if (ompt_initialized) return;
168 
169  const char *ompt_env_var = getenv("OMP_TOOL");
170  tool_setting_e tool_setting = omp_tool_error;
171 
172  if (!ompt_env_var || !strcmp(ompt_env_var, ""))
173  tool_setting = omp_tool_unset;
174  else if (!strcmp(ompt_env_var, "disabled"))
175  tool_setting = omp_tool_disabled;
176  else if (!strcmp(ompt_env_var, "enabled"))
177  tool_setting = omp_tool_enabled;
178 
179  switch(tool_setting) {
180  case omp_tool_disabled:
181  ompt_status = ompt_status_disabled;
182  break;
183 
184  case omp_tool_unset:
185  case omp_tool_enabled:
186  {
187  const char *runtime_version = __ompt_get_runtime_version_internal();
188  int ompt_init_val =
189  ompt_initialize(ompt_fn_lookup, runtime_version, OMPT_VERSION);
190 
191  if (ompt_init_val) {
192  ompt_status = ompt_status_track_callback;
193  __ompt_init_internal();
194  }
195  break;
196  }
197 
198  case omp_tool_error:
199  fprintf(stderr,
200  "Warning: OMP_TOOL has invalid value \"%s\".\n"
201  " legal values are (NULL,\"\",\"disabled\","
202  "\"enabled\").\n", ompt_env_var);
203  break;
204  }
205 
206  ompt_initialized = 1;
207 }
208 
209 
210 void ompt_fini()
211 {
212  if (ompt_status == ompt_status_track_callback) {
213  if (ompt_callbacks.ompt_callback(ompt_event_runtime_shutdown)) {
214  ompt_callbacks.ompt_callback(ompt_event_runtime_shutdown)();
215  }
216  }
217 
218  ompt_status = ompt_status_disabled;
219 }
220 
221 
222 
223 /*****************************************************************************
224  * parallel regions
225  ****************************************************************************/
226 
227 OMPT_API_ROUTINE ompt_parallel_id_t ompt_get_parallel_id(int ancestor_level)
228 {
229  return __ompt_get_parallel_id_internal(ancestor_level);
230 }
231 
232 
233 OMPT_API_ROUTINE int ompt_get_parallel_team_size(int ancestor_level)
234 {
235  return __ompt_get_parallel_team_size_internal(ancestor_level);
236 }
237 
238 
239 OMPT_API_ROUTINE void *ompt_get_parallel_function(int ancestor_level)
240 {
241  return __ompt_get_parallel_function_internal(ancestor_level);
242 }
243 
244 
245 OMPT_API_ROUTINE ompt_state_t ompt_get_state(ompt_wait_id_t *ompt_wait_id)
246 {
247  ompt_state_t thread_state = __ompt_get_state_internal(ompt_wait_id);
248 
249  if (thread_state == ompt_state_undefined) {
250  thread_state = ompt_state_work_serial;
251  }
252 
253  return thread_state;
254 }
255 
256 
257 
258 /*****************************************************************************
259  * threads
260  ****************************************************************************/
261 
262 
263 OMPT_API_ROUTINE void *ompt_get_idle_frame()
264 {
265  return __ompt_get_idle_frame_internal();
266 }
267 
268 
269 
270 /*****************************************************************************
271  * tasks
272  ****************************************************************************/
273 
274 
275 OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void)
276 {
277  return __ompt_get_thread_id_internal();
278 }
279 
280 OMPT_API_ROUTINE ompt_task_id_t ompt_get_task_id(int depth)
281 {
282  return __ompt_get_task_id_internal(depth);
283 }
284 
285 
286 OMPT_API_ROUTINE ompt_frame_t *ompt_get_task_frame(int depth)
287 {
288  return __ompt_get_task_frame_internal(depth);
289 }
290 
291 
292 OMPT_API_ROUTINE void *ompt_get_task_function(int depth)
293 {
294  return __ompt_get_task_function_internal(depth);
295 }
296 
297 
298 /*****************************************************************************
299  * placeholders
300  ****************************************************************************/
301 
302 // Don't define this as static. The loader may choose to eliminate the symbol
303 // even though it is needed by tools.
304 #define OMPT_API_PLACEHOLDER
305 
306 // Ensure that placeholders don't have mangled names in the symbol table.
307 #ifdef __cplusplus
308 extern "C" {
309 #endif
310 
311 
312 OMPT_API_PLACEHOLDER void ompt_idle(void)
313 {
314  // This function is a placeholder used to represent the calling context of
315  // idle OpenMP worker threads. It is not meant to be invoked.
316  assert(0);
317 }
318 
319 
320 OMPT_API_PLACEHOLDER void ompt_overhead(void)
321 {
322  // This function is a placeholder used to represent the OpenMP context of
323  // threads working in the OpenMP runtime. It is not meant to be invoked.
324  assert(0);
325 }
326 
327 
328 OMPT_API_PLACEHOLDER void ompt_barrier_wait(void)
329 {
330  // This function is a placeholder used to represent the OpenMP context of
331  // threads waiting for a barrier in the OpenMP runtime. It is not meant
332  // to be invoked.
333  assert(0);
334 }
335 
336 
337 OMPT_API_PLACEHOLDER void ompt_task_wait(void)
338 {
339  // This function is a placeholder used to represent the OpenMP context of
340  // threads waiting for a task in the OpenMP runtime. It is not meant
341  // to be invoked.
342  assert(0);
343 }
344 
345 
346 OMPT_API_PLACEHOLDER void ompt_mutex_wait(void)
347 {
348  // This function is a placeholder used to represent the OpenMP context of
349  // threads waiting for a mutex in the OpenMP runtime. It is not meant
350  // to be invoked.
351  assert(0);
352 }
353 
354 #ifdef __cplusplus
355 };
356 #endif
357 
358 
359 /*****************************************************************************
360  * compatability
361  ****************************************************************************/
362 
363 OMPT_API_ROUTINE int ompt_get_ompt_version()
364 {
365  return OMPT_VERSION;
366 }
367 
368 
369 
370 /*****************************************************************************
371  * application-facing API
372  ****************************************************************************/
373 
374 
375 /*----------------------------------------------------------------------------
376  | control
377  ---------------------------------------------------------------------------*/
378 
379 _OMP_EXTERN void ompt_control(uint64_t command, uint64_t modifier)
380 {
381  if (ompt_status == ompt_status_track_callback &&
382  ompt_callbacks.ompt_callback(ompt_event_control)) {
383  ompt_callbacks.ompt_callback(ompt_event_control)(command, modifier);
384  }
385 }
386 
387 
388 
389 /*****************************************************************************
390  * API inquiry for tool
391  ****************************************************************************/
392 
393 static ompt_interface_fn_t ompt_fn_lookup(const char *s)
394 {
395 
396 #define ompt_interface_fn(fn) \
397  if (strcmp(s, #fn) == 0) return (ompt_interface_fn_t) fn;
398 
399  FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn)
400 
401  FOREACH_OMPT_PLACEHOLDER_FN(ompt_interface_fn)
402 
403  return (ompt_interface_fn_t) 0;
404 }