[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / openmp / tools / multiplex / ompt-multiplex.h
blob041b15233c6b0d3aa8850cc6b87fbb2b7a4b10d9
1 //===--- ompt-multiplex.h - header-only multiplexing of OMPT tools -- C -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This header file enables an OMPT tool to load another OMPT tool and
10 // automatically forwards OMPT event-callbacks to the nested tool.
12 // For details see openmp/tools/multiplex/README.md
14 //===----------------------------------------------------------------------===//
16 #ifndef OMPT_MULTIPLEX_H
17 #define OMPT_MULTIPLEX_H
19 #ifndef _GNU_SOURCE
20 #define _GNU_SOURCE
21 #endif
22 #include <dlfcn.h>
23 #include <errno.h>
24 #include <execinfo.h>
25 #include <inttypes.h>
26 #include <omp-tools.h>
27 #include <omp.h>
28 #include <stdio.h>
29 #include <string.h>
31 static ompt_set_callback_t ompt_multiplex_set_callback;
32 static ompt_get_task_info_t ompt_multiplex_get_task_info;
33 static ompt_get_thread_data_t ompt_multiplex_get_thread_data;
34 static ompt_get_parallel_info_t ompt_multiplex_get_parallel_info;
36 // contains name of the environment var in which the tool path is specified
37 #ifndef CLIENT_TOOL_LIBRARIES_VAR
38 #error CLIENT_TOOL_LIBRARIES_VAR should be defined before including of ompt-multiplex.h
39 #endif
41 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) && \
42 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
43 #error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA is set
44 #endif
46 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA) && \
47 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA)
48 #error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA is set
49 #endif
51 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA) && \
52 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA)
53 #error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA is set
54 #endif
56 #define OMPT_API_ROUTINE static
58 #define OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(macro) \
59 macro(callback_thread_begin, ompt_callback_thread_begin_t, 1); \
60 macro(callback_thread_end, ompt_callback_thread_end_t, 2); \
61 macro(callback_parallel_begin, ompt_callback_parallel_begin_t, 3); \
62 macro(callback_parallel_end, ompt_callback_parallel_end_t, 4); \
63 macro(callback_task_create, ompt_callback_task_create_t, 5); \
64 macro(callback_task_schedule, ompt_callback_task_schedule_t, 6); \
65 macro(callback_implicit_task, ompt_callback_implicit_task_t, 7); \
66 macro(callback_target, ompt_callback_target_t, 8); \
67 macro(callback_target_data_op, ompt_callback_target_data_op_t, 9); \
68 macro(callback_target_submit, ompt_callback_target_submit_t, 10); \
69 macro(callback_control_tool, ompt_callback_control_tool_t, 11); \
70 macro(callback_device_initialize, ompt_callback_device_initialize_t, 12); \
71 macro(callback_device_finalize, ompt_callback_device_finalize_t, 13); \
72 macro(callback_device_load, ompt_callback_device_load_t, 14); \
73 macro(callback_device_unload, ompt_callback_device_unload_t, 15); \
74 macro(callback_sync_region_wait, ompt_callback_sync_region_t, 16); \
75 macro(callback_mutex_released, ompt_callback_mutex_t, 17); \
76 macro(callback_dependences, ompt_callback_dependences_t, 18); \
77 macro(callback_task_dependence, ompt_callback_task_dependence_t, 19); \
78 macro(callback_work, ompt_callback_work_t, 20); \
79 macro(callback_master, ompt_callback_master_t, 21); \
80 macro(callback_target_map, ompt_callback_target_map_t, 22); \
81 macro(callback_sync_region, ompt_callback_sync_region_t, 23); \
82 macro(callback_lock_init, ompt_callback_mutex_acquire_t, 24); \
83 macro(callback_lock_destroy, ompt_callback_mutex_t, 25); \
84 macro(callback_mutex_acquire, ompt_callback_mutex_acquire_t, 26); \
85 macro(callback_mutex_acquired, ompt_callback_mutex_t, 27); \
86 macro(callback_nest_lock, ompt_callback_nest_lock_t, 28); \
87 macro(callback_flush, ompt_callback_flush_t, 29); \
88 macro(callback_cancel, ompt_callback_cancel_t, 30); \
89 macro(callback_reduction, ompt_callback_sync_region_t, 31); \
90 macro(callback_dispatch, ompt_callback_dispatch_t, 32);
92 typedef struct ompt_multiplex_callbacks_s {
93 #define ompt_event_macro(event, callback, eventid) callback ompt_##event
95 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
97 #undef ompt_event_macro
98 } ompt_multiplex_callbacks_t;
100 typedef struct ompt_multiplex_callback_implementation_status_s {
101 #define ompt_event_macro(event, callback, eventid) int ompt_##event
103 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
105 #undef ompt_event_macro
106 } ompt_multiplex_callback_implementation_status_t;
108 ompt_start_tool_result_t *ompt_multiplex_own_fns;
109 ompt_start_tool_result_t *ompt_multiplex_client_fns;
110 ompt_function_lookup_t ompt_multiplex_lookup_function;
111 ompt_multiplex_callbacks_t ompt_multiplex_own_callbacks,
112 ompt_multiplex_client_callbacks;
113 ompt_multiplex_callback_implementation_status_t
114 ompt_multiplex_implementation_status;
116 typedef struct ompt_multiplex_data_pair_s {
117 ompt_data_t own_data;
118 ompt_data_t client_data;
119 } ompt_multiplex_data_pair_t;
121 #if !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) || \
122 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) || \
123 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
124 static ompt_multiplex_data_pair_t *
125 ompt_multiplex_allocate_data_pair(ompt_data_t *data_pointer) {
126 data_pointer->ptr = malloc(sizeof(ompt_multiplex_data_pair_t));
127 if (!data_pointer->ptr) {
128 printf("Malloc ERROR\n");
129 exit(-1);
131 ompt_multiplex_data_pair_t *data_pair =
132 (ompt_multiplex_data_pair_t *)data_pointer->ptr;
133 data_pair->own_data.ptr = NULL;
134 data_pair->client_data.ptr = NULL;
135 return data_pair;
138 static void ompt_multiplex_free_data_pair(ompt_data_t *data_pointer) {
139 free((*data_pointer).ptr);
142 static ompt_data_t *ompt_multiplex_get_own_ompt_data(ompt_data_t *data) {
143 if (!data)
144 return NULL;
145 ompt_multiplex_data_pair_t *data_pair =
146 (ompt_multiplex_data_pair_t *)data->ptr;
147 return &(data_pair->own_data);
150 static ompt_data_t *ompt_multiplex_get_client_ompt_data(ompt_data_t *data) {
151 if (!data)
152 return NULL;
153 ompt_multiplex_data_pair_t *data_pair =
154 (ompt_multiplex_data_pair_t *)data->ptr;
155 return &(data_pair->client_data);
157 #endif //! defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) ||
158 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) ||
159 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
161 static ompt_data_t *ompt_multiplex_get_own_thread_data(ompt_data_t *data) {
162 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
163 return ompt_multiplex_get_own_ompt_data(data);
164 #else
165 return data;
166 #endif
169 static ompt_data_t *ompt_multiplex_get_own_parallel_data(ompt_data_t *data) {
170 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
171 return ompt_multiplex_get_own_ompt_data(data);
172 #else
173 return data;
174 #endif
177 static ompt_data_t *ompt_multiplex_get_own_task_data(ompt_data_t *data) {
178 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
179 return ompt_multiplex_get_own_ompt_data(data);
180 #else
181 return data;
182 #endif
185 static ompt_data_t *ompt_multiplex_get_client_thread_data(ompt_data_t *data) {
186 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
187 return ompt_multiplex_get_client_ompt_data(data);
188 #else
189 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(data);
190 #endif
193 static ompt_data_t *ompt_multiplex_get_client_parallel_data(ompt_data_t *data) {
194 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
195 return ompt_multiplex_get_client_ompt_data(data);
196 #else
197 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(data);
198 #endif
201 static ompt_data_t *ompt_multiplex_get_client_task_data(ompt_data_t *data) {
202 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
203 return ompt_multiplex_get_client_ompt_data(data);
204 #else
205 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(data);
206 #endif
209 static void ompt_multiplex_callback_mutex_acquire(ompt_mutex_t kind,
210 unsigned int hint,
211 unsigned int impl,
212 ompt_wait_id_t wait_id,
213 const void *codeptr_ra) {
214 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire) {
215 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire(
216 kind, hint, impl, wait_id, codeptr_ra);
218 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire) {
219 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire(
220 kind, hint, impl, wait_id, codeptr_ra);
224 static void ompt_multiplex_callback_mutex_acquired(ompt_mutex_t kind,
225 ompt_wait_id_t wait_id,
226 const void *codeptr_ra) {
227 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired) {
228 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired(kind, wait_id,
229 codeptr_ra);
231 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired) {
232 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired(kind, wait_id,
233 codeptr_ra);
237 static void ompt_multiplex_callback_mutex_released(ompt_mutex_t kind,
238 ompt_wait_id_t wait_id,
239 const void *codeptr_ra) {
240 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_released) {
241 ompt_multiplex_own_callbacks.ompt_callback_mutex_released(kind, wait_id,
242 codeptr_ra);
244 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_released) {
245 ompt_multiplex_client_callbacks.ompt_callback_mutex_released(kind, wait_id,
246 codeptr_ra);
250 static void ompt_multiplex_callback_nest_lock(ompt_scope_endpoint_t endpoint,
251 ompt_wait_id_t wait_id,
252 const void *codeptr_ra) {
253 if (ompt_multiplex_own_callbacks.ompt_callback_nest_lock) {
254 ompt_multiplex_own_callbacks.ompt_callback_nest_lock(endpoint, wait_id,
255 codeptr_ra);
257 if (ompt_multiplex_client_callbacks.ompt_callback_nest_lock) {
258 ompt_multiplex_client_callbacks.ompt_callback_nest_lock(endpoint, wait_id,
259 codeptr_ra);
263 static void ompt_multiplex_callback_sync_region(ompt_sync_region_t kind,
264 ompt_scope_endpoint_t endpoint,
265 ompt_data_t *parallel_data,
266 ompt_data_t *task_data,
267 const void *codeptr_ra) {
268 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region) {
269 ompt_multiplex_own_callbacks.ompt_callback_sync_region(
270 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
271 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
273 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region) {
274 ompt_multiplex_client_callbacks.ompt_callback_sync_region(
275 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
276 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
280 static void ompt_multiplex_callback_sync_region_wait(
281 ompt_sync_region_t kind, ompt_scope_endpoint_t endpoint,
282 ompt_data_t *parallel_data, ompt_data_t *task_data,
283 const void *codeptr_ra) {
284 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait) {
285 ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait(
286 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
287 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
289 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait) {
290 ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait(
291 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
292 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
296 static void ompt_multiplex_callback_flush(ompt_data_t *thread_data,
297 const void *codeptr_ra) {
298 if (ompt_multiplex_own_callbacks.ompt_callback_flush) {
299 ompt_multiplex_own_callbacks.ompt_callback_flush(
300 ompt_multiplex_get_own_thread_data(thread_data), codeptr_ra);
302 if (ompt_multiplex_client_callbacks.ompt_callback_flush) {
303 ompt_multiplex_client_callbacks.ompt_callback_flush(
304 ompt_multiplex_get_client_thread_data(thread_data), codeptr_ra);
308 static void ompt_multiplex_callback_cancel(ompt_data_t *task_data, int flags,
309 const void *codeptr_ra) {
310 if (ompt_multiplex_own_callbacks.ompt_callback_cancel) {
311 ompt_multiplex_own_callbacks.ompt_callback_cancel(
312 ompt_multiplex_get_own_task_data(task_data), flags, codeptr_ra);
314 if (ompt_multiplex_client_callbacks.ompt_callback_cancel) {
315 ompt_multiplex_client_callbacks.ompt_callback_cancel(
316 ompt_multiplex_get_client_task_data(task_data), flags, codeptr_ra);
320 static void ompt_multiplex_callback_implicit_task(
321 ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data,
322 ompt_data_t *task_data, unsigned int team_size, unsigned int thread_num,
323 int flags) {
324 if (endpoint == ompt_scope_begin) {
325 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
326 ompt_multiplex_allocate_data_pair(task_data);
327 #endif
328 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
329 if (flags & ompt_task_initial)
330 ompt_multiplex_allocate_data_pair(parallel_data);
331 #endif
332 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
333 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
334 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
335 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
336 flags);
338 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {
339 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(
340 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
341 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,
342 flags);
344 } else {
345 // defines to make sure, callbacks are called in correct order depending on
346 // defines set by the user
347 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \
348 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
349 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
350 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
351 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
352 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
353 flags);
355 #endif
357 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {
358 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(
359 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
360 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,
361 flags);
364 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \
365 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
366 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
367 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
368 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
369 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
370 flags);
372 #endif
374 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
375 ompt_multiplex_free_data_pair(task_data);
376 #endif
378 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
379 if (flags & ompt_task_initial)
380 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);
381 #endif
382 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
383 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(task_data);
384 #endif
388 static void ompt_multiplex_callback_lock_init(ompt_mutex_t kind,
389 unsigned int hint,
390 unsigned int impl,
391 ompt_wait_id_t wait_id,
392 const void *codeptr_ra) {
393 if (ompt_multiplex_own_callbacks.ompt_callback_lock_init) {
394 ompt_multiplex_own_callbacks.ompt_callback_lock_init(kind, hint, impl,
395 wait_id, codeptr_ra);
397 if (ompt_multiplex_client_callbacks.ompt_callback_lock_init) {
398 ompt_multiplex_client_callbacks.ompt_callback_lock_init(
399 kind, hint, impl, wait_id, codeptr_ra);
403 static void ompt_multiplex_callback_lock_destroy(ompt_mutex_t kind,
404 ompt_wait_id_t wait_id,
405 const void *codeptr_ra) {
406 if (ompt_multiplex_own_callbacks.ompt_callback_lock_destroy) {
407 ompt_multiplex_own_callbacks.ompt_callback_lock_destroy(kind, wait_id,
408 codeptr_ra);
410 if (ompt_multiplex_client_callbacks.ompt_callback_lock_destroy) {
411 ompt_multiplex_client_callbacks.ompt_callback_lock_destroy(kind, wait_id,
412 codeptr_ra);
416 static void ompt_multiplex_callback_work(ompt_work_t wstype,
417 ompt_scope_endpoint_t endpoint,
418 ompt_data_t *parallel_data,
419 ompt_data_t *task_data, uint64_t count,
420 const void *codeptr_ra) {
421 if (ompt_multiplex_own_callbacks.ompt_callback_work) {
422 ompt_multiplex_own_callbacks.ompt_callback_work(
423 wstype, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
424 ompt_multiplex_get_own_task_data(task_data), count, codeptr_ra);
426 if (ompt_multiplex_client_callbacks.ompt_callback_work) {
427 ompt_multiplex_client_callbacks.ompt_callback_work(
428 wstype, endpoint,
429 ompt_multiplex_get_client_parallel_data(parallel_data),
430 ompt_multiplex_get_client_task_data(task_data), count, codeptr_ra);
434 static void ompt_multiplex_callback_master(ompt_scope_endpoint_t endpoint,
435 ompt_data_t *parallel_data,
436 ompt_data_t *task_data,
437 const void *codeptr_ra) {
438 if (ompt_multiplex_own_callbacks.ompt_callback_master) {
439 ompt_multiplex_own_callbacks.ompt_callback_master(
440 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
441 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
443 if (ompt_multiplex_client_callbacks.ompt_callback_master) {
444 ompt_multiplex_client_callbacks.ompt_callback_master(
445 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
446 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
450 static void ompt_multiplex_callback_parallel_begin(
451 ompt_data_t *parent_task_data, const ompt_frame_t *parent_task_frame,
452 ompt_data_t *parallel_data, uint32_t requested_team_size, int flag,
453 const void *codeptr_ra) {
454 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
455 ompt_multiplex_allocate_data_pair(parallel_data);
456 #endif
457 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_begin) {
458 ompt_multiplex_own_callbacks.ompt_callback_parallel_begin(
459 ompt_multiplex_get_own_task_data(parent_task_data), parent_task_frame,
460 ompt_multiplex_get_own_parallel_data(parallel_data),
461 requested_team_size, flag, codeptr_ra);
463 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_begin) {
464 ompt_multiplex_client_callbacks.ompt_callback_parallel_begin(
465 ompt_multiplex_get_client_task_data(parent_task_data),
466 parent_task_frame,
467 ompt_multiplex_get_client_parallel_data(parallel_data),
468 requested_team_size, flag, codeptr_ra);
472 static void ompt_multiplex_callback_parallel_end(ompt_data_t *parallel_data,
473 ompt_data_t *task_data,
474 int flag,
475 const void *codeptr_ra) {
476 // defines to make sure, callbacks are called in correct order depending on
477 // defines set by the user
478 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA) || \
479 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA)
480 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {
481 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(
482 ompt_multiplex_get_own_parallel_data(parallel_data),
483 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);
485 #endif
487 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_end) {
488 ompt_multiplex_client_callbacks.ompt_callback_parallel_end(
489 ompt_multiplex_get_client_parallel_data(parallel_data),
490 ompt_multiplex_get_client_task_data(task_data), flag, codeptr_ra);
493 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) && \
494 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
495 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {
496 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(
497 ompt_multiplex_get_own_parallel_data(parallel_data),
498 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);
500 #endif
502 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
503 ompt_multiplex_free_data_pair(parallel_data);
504 #endif
506 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
507 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);
508 #endif
511 static void ompt_multiplex_callback_task_create(
512 ompt_data_t *parent_task_data, const ompt_frame_t *parent_frame,
513 ompt_data_t *new_task_data, int type, int has_dependences,
514 const void *codeptr_ra) {
515 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
516 ompt_multiplex_allocate_data_pair(new_task_data);
517 #endif
519 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
520 if (type & ompt_task_initial) {
521 ompt_data_t *parallel_data;
522 ompt_multiplex_get_parallel_info(0, &parallel_data, NULL);
523 ompt_multiplex_allocate_data_pair(parallel_data);
525 #endif
527 if (ompt_multiplex_own_callbacks.ompt_callback_task_create) {
528 ompt_multiplex_own_callbacks.ompt_callback_task_create(
529 ompt_multiplex_get_own_task_data(parent_task_data), parent_frame,
530 ompt_multiplex_get_own_task_data(new_task_data), type, has_dependences,
531 codeptr_ra);
533 if (ompt_multiplex_client_callbacks.ompt_callback_task_create) {
534 ompt_multiplex_client_callbacks.ompt_callback_task_create(
535 ompt_multiplex_get_client_task_data(parent_task_data), parent_frame,
536 ompt_multiplex_get_client_task_data(new_task_data), type,
537 has_dependences, codeptr_ra);
541 static void
542 ompt_multiplex_callback_task_schedule(ompt_data_t *first_task_data,
543 ompt_task_status_t prior_task_status,
544 ompt_data_t *second_task_data) {
545 if (prior_task_status != ompt_task_complete) {
546 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
547 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
548 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
549 ompt_multiplex_get_own_task_data(second_task_data));
551 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {
552 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(
553 ompt_multiplex_get_client_task_data(first_task_data),
554 prior_task_status,
555 ompt_multiplex_get_client_task_data(second_task_data));
557 } else {
558 // defines to make sure, callbacks are called in correct order depending on
559 // defines set by the user
560 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \
561 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
562 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
563 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
564 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
565 ompt_multiplex_get_own_task_data(second_task_data));
567 #endif
569 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {
570 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(
571 ompt_multiplex_get_client_task_data(first_task_data),
572 prior_task_status,
573 ompt_multiplex_get_client_task_data(second_task_data));
576 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \
577 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
578 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
579 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
580 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
581 ompt_multiplex_get_own_task_data(second_task_data));
583 #endif
585 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
586 ompt_multiplex_free_data_pair(first_task_data);
587 #endif
589 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
590 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(first_task_data);
591 #endif
595 static void ompt_multiplex_callback_dependences(ompt_data_t *task_data,
596 const ompt_dependence_t *deps,
597 int ndeps) {
598 if (ompt_multiplex_own_callbacks.ompt_callback_dependences) {
599 ompt_multiplex_own_callbacks.ompt_callback_dependences(
600 ompt_multiplex_get_own_task_data(task_data), deps, ndeps);
602 if (ompt_multiplex_client_callbacks.ompt_callback_dependences) {
603 ompt_multiplex_client_callbacks.ompt_callback_dependences(
604 ompt_multiplex_get_client_task_data(task_data), deps, ndeps);
608 static void
609 ompt_multiplex_callback_task_dependence(ompt_data_t *first_task_data,
610 ompt_data_t *second_task_data) {
611 if (ompt_multiplex_own_callbacks.ompt_callback_task_dependence) {
612 ompt_multiplex_own_callbacks.ompt_callback_task_dependence(
613 ompt_multiplex_get_own_task_data(first_task_data),
614 ompt_multiplex_get_own_task_data(second_task_data));
616 if (ompt_multiplex_client_callbacks.ompt_callback_task_dependence) {
617 ompt_multiplex_client_callbacks.ompt_callback_task_dependence(
618 ompt_multiplex_get_client_task_data(first_task_data),
619 ompt_multiplex_get_client_task_data(second_task_data));
623 static void ompt_multiplex_callback_thread_begin(ompt_thread_t thread_type,
624 ompt_data_t *thread_data) {
625 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
626 ompt_multiplex_allocate_data_pair(thread_data);
627 #endif
628 if (ompt_multiplex_own_callbacks.ompt_callback_thread_begin) {
629 ompt_multiplex_own_callbacks.ompt_callback_thread_begin(
630 thread_type, ompt_multiplex_get_own_thread_data(thread_data));
632 if (ompt_multiplex_client_callbacks.ompt_callback_thread_begin) {
633 ompt_multiplex_client_callbacks.ompt_callback_thread_begin(
634 thread_type, ompt_multiplex_get_client_thread_data(thread_data));
638 static void ompt_multiplex_callback_thread_end(ompt_data_t *thread_data) {
639 // defines to make sure, callbacks are called in correct order depending on
640 // defines set by the user
641 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA) || \
642 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA)
643 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {
644 ompt_multiplex_own_callbacks.ompt_callback_thread_end(
645 ompt_multiplex_get_own_thread_data(thread_data));
647 #endif
649 if (ompt_multiplex_client_callbacks.ompt_callback_thread_end) {
650 ompt_multiplex_client_callbacks.ompt_callback_thread_end(
651 ompt_multiplex_get_client_thread_data(thread_data));
654 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) && \
655 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)
656 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {
657 ompt_multiplex_own_callbacks.ompt_callback_thread_end(
658 ompt_multiplex_get_own_thread_data(thread_data));
660 #endif
662 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
663 ompt_multiplex_free_data_pair(thread_data);
664 #endif
666 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)
667 OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA(thread_data);
668 #endif
671 static int ompt_multiplex_callback_control_tool(uint64_t command,
672 uint64_t modifier, void *arg,
673 const void *codeptr_ra) {
674 int ownRet = 0, clientRet = 0;
675 if (ompt_multiplex_own_callbacks.ompt_callback_control_tool) {
676 ownRet = ompt_multiplex_own_callbacks.ompt_callback_control_tool(
677 command, modifier, arg, codeptr_ra);
679 if (ompt_multiplex_client_callbacks.ompt_callback_control_tool) {
680 clientRet = ompt_multiplex_client_callbacks.ompt_callback_control_tool(
681 command, modifier, arg, codeptr_ra);
683 return ownRet < clientRet ? ownRet : clientRet;
686 static void ompt_multiplex_callback_target(
687 ompt_target_t kind, ompt_scope_endpoint_t endpoint, int device_num,
688 ompt_data_t *task_data, ompt_id_t target_id, const void *codeptr_ra) {
689 if (ompt_multiplex_own_callbacks.ompt_callback_target) {
690 ompt_multiplex_own_callbacks.ompt_callback_target(
691 kind, endpoint, device_num, ompt_multiplex_get_own_task_data(task_data),
692 target_id, codeptr_ra);
694 if (ompt_multiplex_client_callbacks.ompt_callback_target) {
695 ompt_multiplex_client_callbacks.ompt_callback_target(
696 kind, endpoint, device_num,
697 ompt_multiplex_get_client_task_data(task_data), target_id, codeptr_ra);
701 static void ompt_multiplex_callback_target_data_op(
702 ompt_id_t target_id, ompt_id_t host_op_id, ompt_target_data_op_t optype,
703 void *src_addr, int src_device_num, void *dest_addr, int dest_device_num,
704 size_t bytes, const void *codeptr_ra) {
705 if (ompt_multiplex_own_callbacks.ompt_callback_target_data_op) {
706 ompt_multiplex_own_callbacks.ompt_callback_target_data_op(
707 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,
708 dest_device_num, bytes, codeptr_ra);
710 if (ompt_multiplex_client_callbacks.ompt_callback_target_data_op) {
711 ompt_multiplex_client_callbacks.ompt_callback_target_data_op(
712 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,
713 dest_device_num, bytes, codeptr_ra);
717 static void
718 ompt_multiplex_callback_target_submit(ompt_id_t target_id, ompt_id_t host_op_id,
719 unsigned int requested_num_teams) {
720 if (ompt_multiplex_own_callbacks.ompt_callback_target_submit) {
721 ompt_multiplex_own_callbacks.ompt_callback_target_submit(
722 target_id, host_op_id, requested_num_teams);
724 if (ompt_multiplex_client_callbacks.ompt_callback_target_submit) {
725 ompt_multiplex_client_callbacks.ompt_callback_target_submit(
726 target_id, host_op_id, requested_num_teams);
730 static void ompt_multiplex_callback_device_initialize(
731 int device_num, const char *type, ompt_device_t *device,
732 ompt_function_lookup_t lookup, const char *documentation) {
733 if (ompt_multiplex_own_callbacks.ompt_callback_device_initialize) {
734 ompt_multiplex_own_callbacks.ompt_callback_device_initialize(
735 device_num, type, device, lookup, documentation);
737 if (ompt_multiplex_client_callbacks.ompt_callback_device_initialize) {
738 ompt_multiplex_client_callbacks.ompt_callback_device_initialize(
739 device_num, type, device, lookup, documentation);
743 static void ompt_multiplex_callback_device_finalize(int device_num) {
744 if (ompt_multiplex_own_callbacks.ompt_callback_device_finalize) {
745 ompt_multiplex_own_callbacks.ompt_callback_device_finalize(device_num);
747 if (ompt_multiplex_client_callbacks.ompt_callback_device_finalize) {
748 ompt_multiplex_client_callbacks.ompt_callback_device_finalize(device_num);
752 static void
753 ompt_multiplex_callback_device_load(int device_num, const char *filename,
754 int64_t offset_in_file, void *vma_in_file,
755 size_t bytes, void *host_addr,
756 void *device_addr, uint64_t module_id) {
757 if (ompt_multiplex_own_callbacks.ompt_callback_device_load) {
758 ompt_multiplex_own_callbacks.ompt_callback_device_load(
759 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,
760 device_addr, module_id);
762 if (ompt_multiplex_client_callbacks.ompt_callback_device_load) {
763 ompt_multiplex_client_callbacks.ompt_callback_device_load(
764 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,
765 device_addr, module_id);
769 static void ompt_multiplex_callback_device_unload(int device_num,
770 uint64_t module_id) {
771 if (ompt_multiplex_own_callbacks.ompt_callback_device_unload) {
772 ompt_multiplex_own_callbacks.ompt_callback_device_unload(device_num,
773 module_id);
775 if (ompt_multiplex_client_callbacks.ompt_callback_device_unload) {
776 ompt_multiplex_client_callbacks.ompt_callback_device_unload(device_num,
777 module_id);
781 static void
782 ompt_multiplex_callback_target_map(ompt_id_t target_id, unsigned int nitems,
783 void **host_addr, void **device_addr,
784 size_t *bytes, unsigned int *mapping_flags,
785 const void *codeptr_ra) {
786 if (ompt_multiplex_own_callbacks.ompt_callback_target_map) {
787 ompt_multiplex_own_callbacks.ompt_callback_target_map(
788 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,
789 codeptr_ra);
791 if (ompt_multiplex_client_callbacks.ompt_callback_target_map) {
792 ompt_multiplex_client_callbacks.ompt_callback_target_map(
793 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,
794 codeptr_ra);
798 static void ompt_multiplex_callback_reduction(ompt_sync_region_t kind,
799 ompt_scope_endpoint_t endpoint,
800 ompt_data_t *parallel_data,
801 ompt_data_t *task_data,
802 const void *codeptr_ra) {
803 if (ompt_multiplex_own_callbacks.ompt_callback_reduction) {
804 ompt_multiplex_own_callbacks.ompt_callback_reduction(
805 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
806 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
808 if (ompt_multiplex_client_callbacks.ompt_callback_reduction) {
809 ompt_multiplex_client_callbacks.ompt_callback_reduction(
810 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
811 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
815 static void ompt_multiplex_callback_dispatch(ompt_data_t *parallel_data,
816 ompt_data_t *task_data,
817 ompt_dispatch_t kind,
818 ompt_data_t instance) {
819 if (ompt_multiplex_own_callbacks.ompt_callback_dispatch) {
820 ompt_multiplex_own_callbacks.ompt_callback_dispatch(
821 ompt_multiplex_get_own_parallel_data(parallel_data),
822 ompt_multiplex_get_own_task_data(task_data), kind, instance);
824 if (ompt_multiplex_client_callbacks.ompt_callback_dispatch) {
825 ompt_multiplex_client_callbacks.ompt_callback_dispatch(
826 ompt_multiplex_get_client_parallel_data(parallel_data),
827 ompt_multiplex_get_client_task_data(task_data), kind, instance);
831 // runtime entry functions
833 int ompt_multiplex_own_get_task_info(int ancestor_level, int *type,
834 ompt_data_t **task_data,
835 ompt_frame_t **task_frame,
836 ompt_data_t **parallel_data,
837 int *thread_num) {
838 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,
839 task_frame, parallel_data, thread_num);
841 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
842 if (task_data)
843 *task_data = ompt_multiplex_get_own_ompt_data(*task_data);
844 #endif
845 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
846 if (parallel_data)
847 *parallel_data = ompt_multiplex_get_own_ompt_data(*parallel_data);
848 #endif
849 return ret;
852 int ompt_multiplex_client_get_task_info(int ancestor_level, int *type,
853 ompt_data_t **task_data,
854 ompt_frame_t **task_frame,
855 ompt_data_t **parallel_data,
856 int *thread_num) {
857 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,
858 task_frame, parallel_data, thread_num);
860 if (task_data)
861 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
862 *task_data = ompt_multiplex_get_client_ompt_data(*task_data);
863 #else
864 *task_data = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(*task_data);
865 #endif
867 if (parallel_data)
868 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
869 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);
870 #else
871 *parallel_data =
872 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);
873 #endif
874 return ret;
877 ompt_data_t *ompt_multiplex_own_get_thread_data() {
878 ompt_data_t *ret;
879 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
880 ret = ompt_multiplex_get_own_ompt_data(ompt_multiplex_get_thread_data());
881 #else
882 ret = ompt_multiplex_get_thread_data();
883 #endif
884 return ret;
887 ompt_data_t *ompt_multiplex_client_get_thread_data() {
888 ompt_data_t *ret;
889 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
890 ret = ompt_multiplex_get_client_ompt_data(ompt_multiplex_get_thread_data());
891 #else
892 ret = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(
893 ompt_multiplex_get_thread_data());
894 #endif
895 return ret;
898 int ompt_multiplex_own_get_parallel_info(int ancestor_level,
899 ompt_data_t **parallel_data,
900 int *team_size) {
901 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,
902 team_size);
903 if (parallel_data)
904 *parallel_data = ompt_multiplex_get_own_parallel_data(*parallel_data);
905 return ret;
908 int ompt_multiplex_client_get_parallel_info(int ancestor_level,
909 ompt_data_t **parallel_data,
910 int *team_size) {
911 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,
912 team_size);
913 if (parallel_data)
914 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
915 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);
916 #else
917 *parallel_data =
918 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);
919 #endif
920 return ret;
923 OMPT_API_ROUTINE int ompt_multiplex_own_set_callback(ompt_callbacks_t which,
924 ompt_callback_t callback) {
925 switch (which) {
927 #define ompt_event_macro(event_name, callback_type, event_id) \
928 case ompt_##event_name: \
929 ompt_multiplex_own_callbacks.ompt_##event_name = (callback_type)callback; \
930 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \
931 return ompt_multiplex_implementation_status.ompt_##event_name = \
932 ompt_multiplex_set_callback( \
933 ompt_##event_name, \
934 (ompt_callback_t)&ompt_multiplex_##event_name); \
935 else \
936 return ompt_multiplex_implementation_status.ompt_##event_name
938 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
940 #undef ompt_event_macro
942 default:
943 return ompt_set_error;
947 OMPT_API_ROUTINE int
948 ompt_multiplex_client_set_callback(ompt_callbacks_t which,
949 ompt_callback_t callback) {
950 switch (which) {
952 #define ompt_event_macro(event_name, callback_type, event_id) \
953 case ompt_##event_name: \
954 ompt_multiplex_client_callbacks.ompt_##event_name = \
955 (callback_type)callback; \
956 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \
957 return ompt_multiplex_implementation_status.ompt_##event_name = \
958 ompt_multiplex_set_callback( \
959 ompt_##event_name, \
960 (ompt_callback_t)&ompt_multiplex_##event_name); \
961 else \
962 return ompt_multiplex_implementation_status.ompt_##event_name
964 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
966 #undef ompt_event_macro
968 default:
969 return ompt_set_error;
973 ompt_interface_fn_t ompt_multiplex_own_lookup(const char *name) {
974 if (!strcmp(name, "ompt_set_callback"))
975 return (ompt_interface_fn_t)&ompt_multiplex_own_set_callback;
976 else if (!strcmp(name, "ompt_get_task_info"))
977 return (ompt_interface_fn_t)&ompt_multiplex_own_get_task_info;
978 else if (!strcmp(name, "ompt_get_thread_data"))
979 return (ompt_interface_fn_t)&ompt_multiplex_own_get_thread_data;
980 else if (!strcmp(name, "ompt_get_parallel_info"))
981 return (ompt_interface_fn_t)&ompt_multiplex_own_get_parallel_info;
982 else
983 return ompt_multiplex_lookup_function(name);
986 ompt_interface_fn_t ompt_multiplex_client_lookup(const char *name) {
987 if (!strcmp(name, "ompt_set_callback"))
988 return (ompt_interface_fn_t)&ompt_multiplex_client_set_callback;
989 else if (!strcmp(name, "ompt_get_task_info"))
990 return (ompt_interface_fn_t)&ompt_multiplex_client_get_task_info;
991 else if (!strcmp(name, "ompt_get_thread_data"))
992 return (ompt_interface_fn_t)&ompt_multiplex_client_get_thread_data;
993 else if (!strcmp(name, "ompt_get_parallel_info"))
994 return (ompt_interface_fn_t)&ompt_multiplex_client_get_parallel_info;
995 else
996 return ompt_multiplex_lookup_function(name);
999 int ompt_multiplex_initialize(ompt_function_lookup_t lookup,
1000 int initial_device_num, ompt_data_t *data) {
1001 ompt_multiplex_lookup_function = lookup;
1002 ompt_multiplex_set_callback =
1003 (ompt_set_callback_t)lookup("ompt_set_callback");
1004 ompt_multiplex_get_task_info =
1005 (ompt_get_task_info_t)lookup("ompt_get_task_info");
1006 ompt_multiplex_get_thread_data =
1007 (ompt_get_thread_data_t)lookup("ompt_get_thread_data");
1008 ompt_multiplex_get_parallel_info =
1009 (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info");
1011 // initialize ompt_multiplex_implementation_status
1012 #define ompt_event_macro(event_name, callback_type, event_id) \
1013 ompt_multiplex_implementation_status.ompt_##event_name = -1
1015 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
1017 #undef ompt_event_macro
1019 int ownRet = ompt_multiplex_own_fns->initialize(
1020 ompt_multiplex_own_lookup, initial_device_num,
1021 &(ompt_multiplex_own_fns->tool_data));
1022 int clientRet = 0;
1023 if (ompt_multiplex_client_fns)
1024 clientRet = ompt_multiplex_client_fns->initialize(
1025 ompt_multiplex_client_lookup, initial_device_num,
1026 &(ompt_multiplex_client_fns->tool_data));
1028 return ownRet > clientRet ? ownRet : clientRet;
1031 void ompt_multiplex_finalize(ompt_data_t *fns) {
1032 if (ompt_multiplex_client_fns)
1033 ompt_multiplex_client_fns->finalize(
1034 &(ompt_multiplex_client_fns->tool_data));
1035 ompt_multiplex_own_fns->finalize(&(ompt_multiplex_own_fns->tool_data));
1038 #ifdef __cplusplus
1039 extern "C" {
1040 #endif
1041 ompt_start_tool_result_t *
1042 ompt_multiplex_own_start_tool(unsigned int omp_version,
1043 const char *runtime_version);
1045 ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
1046 const char *runtime_version) {
1047 // try loading client tool
1048 ompt_multiplex_client_fns = NULL;
1049 ompt_start_tool_result_t *(*client_start_tool)(unsigned int, const char *) =
1050 NULL;
1052 const char *tool_libs = getenv(CLIENT_TOOL_LIBRARIES_VAR);
1053 if (tool_libs) {
1054 // copy environement variable
1055 char *tool_libs_buffer = strdup(tool_libs);
1056 if (!tool_libs_buffer) {
1057 printf("strdup Error (%i)\n", errno);
1058 exit(-1);
1061 int progress = 0;
1062 while (progress < strlen(tool_libs)) {
1063 int tmp_progress = progress;
1064 while (tmp_progress < strlen(tool_libs) &&
1065 tool_libs_buffer[tmp_progress] != ':')
1066 tmp_progress++;
1067 if (tmp_progress < strlen(tool_libs))
1068 tool_libs_buffer[tmp_progress] = 0;
1069 void *h = dlopen(tool_libs_buffer + progress, RTLD_LAZY);
1070 if (h) {
1071 client_start_tool =
1072 (ompt_start_tool_result_t * (*)(unsigned int, const char *))
1073 dlsym(h, "ompt_start_tool");
1074 if (client_start_tool &&
1075 (ompt_multiplex_client_fns =
1076 (*client_start_tool)(omp_version, runtime_version))) {
1077 break;
1079 } else {
1080 printf("Loading %s from %s failed with: %s\n",
1081 tool_libs_buffer + progress, CLIENT_TOOL_LIBRARIES_VAR,
1082 dlerror());
1084 progress = tmp_progress + 1;
1086 free(tool_libs_buffer);
1088 // load own tool
1089 ompt_multiplex_own_fns =
1090 ompt_multiplex_own_start_tool(omp_version, runtime_version);
1092 // return multiplexed versions
1093 static ompt_start_tool_result_t ompt_start_tool_result = {
1094 &ompt_multiplex_initialize, &ompt_multiplex_finalize, {0}};
1095 return &ompt_start_tool_result;
1097 #ifdef __cplusplus
1099 #endif
1101 // We rename the ompt_start_tool function of the OMPT tool and call the
1102 // renamed function from the ompt_start_tool function defined above.
1103 #define ompt_start_tool ompt_multiplex_own_start_tool
1105 #endif /* OMPT_MULTIPLEX_H */