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.
11 //
12 // For details see openmp/tools/multiplex/README.md
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef OMPT_MULTIPLEX_H
17 #define OMPT_MULTIPLEX_H
18 
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>
30 
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;
35 
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
40 
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
45 
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
50 
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
55 
56 #define OMPT_API_ROUTINE static
57 
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);
91 
92 typedef struct ompt_multiplex_callbacks_s {
93 #define ompt_event_macro(event, callback, eventid) callback ompt_##event
94 
95   OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
96 
97 #undef ompt_event_macro
98 } ompt_multiplex_callbacks_t;
99 
100 typedef struct ompt_multiplex_callback_implementation_status_s {
101 #define ompt_event_macro(event, callback, eventid) int ompt_##event
102 
103   OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
104 
105 #undef ompt_event_macro
106 } ompt_multiplex_callback_implementation_status_t;
107 
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;
115 
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;
120 
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 *
ompt_multiplex_allocate_data_pair(ompt_data_t * data_pointer)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);
130   }
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;
136 }
137 
ompt_multiplex_free_data_pair(ompt_data_t * data_pointer)138 static void ompt_multiplex_free_data_pair(ompt_data_t *data_pointer) {
139   free((*data_pointer).ptr);
140 }
141 
ompt_multiplex_get_own_ompt_data(ompt_data_t * data)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);
148 }
149 
ompt_multiplex_get_client_ompt_data(ompt_data_t * 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);
156 }
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)
160 
ompt_multiplex_get_own_thread_data(ompt_data_t * 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
167 }
168 
ompt_multiplex_get_own_parallel_data(ompt_data_t * data)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
175 }
176 
ompt_multiplex_get_own_task_data(ompt_data_t * data)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
183 }
184 
ompt_multiplex_get_client_thread_data(ompt_data_t * data)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
191 }
192 
ompt_multiplex_get_client_parallel_data(ompt_data_t * data)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
199 }
200 
ompt_multiplex_get_client_task_data(ompt_data_t * data)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
207 }
208 
ompt_multiplex_callback_mutex_acquire(ompt_mutex_t kind,unsigned int hint,unsigned int impl,ompt_wait_id_t wait_id,const void * codeptr_ra)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);
217   }
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);
221   }
222 }
223 
ompt_multiplex_callback_mutex_acquired(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * 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);
230   }
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);
234   }
235 }
236 
ompt_multiplex_callback_mutex_released(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * 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);
243   }
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);
247   }
248 }
249 
ompt_multiplex_callback_nest_lock(ompt_scope_endpoint_t endpoint,ompt_wait_id_t wait_id,const void * 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);
256   }
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);
260   }
261 }
262 
ompt_multiplex_callback_sync_region(ompt_sync_region_t kind,ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,const void * 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);
272   }
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);
277   }
278 }
279 
ompt_multiplex_callback_sync_region_wait(ompt_sync_region_t kind,ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,const void * 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);
288   }
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);
293   }
294 }
295 
ompt_multiplex_callback_flush(ompt_data_t * thread_data,const void * 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);
301   }
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);
305   }
306 }
307 
ompt_multiplex_callback_cancel(ompt_data_t * task_data,int flags,const void * 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);
313   }
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);
317   }
318 }
319 
ompt_multiplex_callback_implicit_task(ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,unsigned int team_size,unsigned int thread_num,int flags)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);
337     }
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);
343     }
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);
354     }
355 #endif
356 
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);
362     }
363 
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);
371     }
372 #endif
373 
374 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
375     ompt_multiplex_free_data_pair(task_data);
376 #endif
377 
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
385   }
386 }
387 
ompt_multiplex_callback_lock_init(ompt_mutex_t kind,unsigned int hint,unsigned int impl,ompt_wait_id_t wait_id,const void * codeptr_ra)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);
396   }
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);
400   }
401 }
402 
ompt_multiplex_callback_lock_destroy(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * 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);
409   }
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);
413   }
414 }
415 
ompt_multiplex_callback_work(ompt_work_t wstype,ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,uint64_t count,const void * 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);
425   }
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);
431   }
432 }
433 
ompt_multiplex_callback_master(ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,const void * 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);
442   }
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);
447   }
448 }
449 
ompt_multiplex_callback_parallel_begin(ompt_data_t * parent_task_data,const ompt_frame_t * parent_task_frame,ompt_data_t * parallel_data,uint32_t requested_team_size,int flag,const void * 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);
462   }
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);
469   }
470 }
471 
ompt_multiplex_callback_parallel_end(ompt_data_t * parallel_data,ompt_data_t * task_data,int flag,const void * 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);
484   }
485 #endif
486 
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);
491   }
492 
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);
499   }
500 #endif
501 
502 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
503   ompt_multiplex_free_data_pair(parallel_data);
504 #endif
505 
506 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
507   OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);
508 #endif
509 }
510 
ompt_multiplex_callback_task_create(ompt_data_t * parent_task_data,const ompt_frame_t * parent_frame,ompt_data_t * new_task_data,int type,int has_dependences,const void * codeptr_ra)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
518 
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);
524   }
525 #endif
526 
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);
532   }
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);
538   }
539 }
540 
541 static void
ompt_multiplex_callback_task_schedule(ompt_data_t * first_task_data,ompt_task_status_t prior_task_status,ompt_data_t * second_task_data)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));
550     }
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));
556     }
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));
566     }
567 #endif
568 
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));
574     }
575 
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));
582     }
583 #endif
584 
585 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
586     ompt_multiplex_free_data_pair(first_task_data);
587 #endif
588 
589 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
590     OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(first_task_data);
591 #endif
592   }
593 }
594 
ompt_multiplex_callback_dependences(ompt_data_t * task_data,const ompt_dependence_t * deps,int ndeps)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);
601   }
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);
605   }
606 }
607 
608 static void
ompt_multiplex_callback_task_dependence(ompt_data_t * first_task_data,ompt_data_t * second_task_data)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));
615   }
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));
620   }
621 }
622 
ompt_multiplex_callback_thread_begin(ompt_thread_t thread_type,ompt_data_t * thread_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));
631   }
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));
635   }
636 }
637 
ompt_multiplex_callback_thread_end(ompt_data_t * 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));
646   }
647 #endif
648 
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));
652   }
653 
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));
659   }
660 #endif
661 
662 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
663   ompt_multiplex_free_data_pair(thread_data);
664 #endif
665 
666 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)
667   OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA(thread_data);
668 #endif
669 }
670 
ompt_multiplex_callback_control_tool(uint64_t command,uint64_t modifier,void * arg,const void * codeptr_ra)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);
678   }
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);
682   }
683   return ownRet < clientRet ? ownRet : clientRet;
684 }
685 
ompt_multiplex_callback_target(ompt_target_t kind,ompt_scope_endpoint_t endpoint,int device_num,ompt_data_t * task_data,ompt_id_t target_id,const void * codeptr_ra)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);
693   }
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);
698   }
699 }
700 
ompt_multiplex_callback_target_data_op(ompt_id_t target_id,ompt_id_t host_op_id,ompt_target_data_op_t optype,void * src_addr,int src_device_num,void * dest_addr,int dest_device_num,size_t bytes,const void * 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);
709   }
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);
714   }
715 }
716 
717 static void
ompt_multiplex_callback_target_submit(ompt_id_t target_id,ompt_id_t host_op_id,unsigned int requested_num_teams)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);
723   }
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);
727   }
728 }
729 
ompt_multiplex_callback_device_initialize(int device_num,const char * type,ompt_device_t * device,ompt_function_lookup_t lookup,const char * documentation)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);
736   }
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);
740   }
741 }
742 
ompt_multiplex_callback_device_finalize(int device_num)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);
746   }
747   if (ompt_multiplex_client_callbacks.ompt_callback_device_finalize) {
748     ompt_multiplex_client_callbacks.ompt_callback_device_finalize(device_num);
749   }
750 }
751 
752 static void
ompt_multiplex_callback_device_load(int device_num,const char * filename,int64_t offset_in_file,void * vma_in_file,size_t bytes,void * host_addr,void * device_addr,uint64_t module_id)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);
761   }
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);
766   }
767 }
768 
ompt_multiplex_callback_device_unload(int device_num,uint64_t 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);
774   }
775   if (ompt_multiplex_client_callbacks.ompt_callback_device_unload) {
776     ompt_multiplex_client_callbacks.ompt_callback_device_unload(device_num,
777                                                                 module_id);
778   }
779 }
780 
781 static void
ompt_multiplex_callback_target_map(ompt_id_t target_id,unsigned int nitems,void ** host_addr,void ** device_addr,size_t * bytes,unsigned int * mapping_flags,const void * codeptr_ra)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);
790   }
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);
795   }
796 }
797 
ompt_multiplex_callback_reduction(ompt_sync_region_t kind,ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,const void * 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);
807   }
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);
812   }
813 }
814 
ompt_multiplex_callback_dispatch(ompt_data_t * parallel_data,ompt_data_t * task_data,ompt_dispatch_t kind,ompt_data_t instance)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);
823   }
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);
828   }
829 }
830 
831 // runtime entry functions
832 
ompt_multiplex_own_get_task_info(int ancestor_level,int * type,ompt_data_t ** task_data,ompt_frame_t ** task_frame,ompt_data_t ** parallel_data,int * thread_num)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);
840 
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;
850 }
851 
ompt_multiplex_client_get_task_info(int ancestor_level,int * type,ompt_data_t ** task_data,ompt_frame_t ** task_frame,ompt_data_t ** parallel_data,int * thread_num)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);
859 
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
866 
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;
875 }
876 
ompt_multiplex_own_get_thread_data()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;
885 }
886 
ompt_multiplex_client_get_thread_data()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;
896 }
897 
ompt_multiplex_own_get_parallel_info(int ancestor_level,ompt_data_t ** parallel_data,int * team_size)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;
906 }
907 
ompt_multiplex_client_get_parallel_info(int ancestor_level,ompt_data_t ** parallel_data,int * team_size)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;
921 }
922 
ompt_multiplex_own_set_callback(ompt_callbacks_t which,ompt_callback_t callback)923 OMPT_API_ROUTINE int ompt_multiplex_own_set_callback(ompt_callbacks_t which,
924                                                      ompt_callback_t callback) {
925   switch (which) {
926 
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
937 
938     OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
939 
940 #undef ompt_event_macro
941 
942   default:
943     return ompt_set_error;
944   }
945 }
946 
947 OMPT_API_ROUTINE int
ompt_multiplex_client_set_callback(ompt_callbacks_t which,ompt_callback_t callback)948 ompt_multiplex_client_set_callback(ompt_callbacks_t which,
949                                    ompt_callback_t callback) {
950   switch (which) {
951 
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
963 
964     OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
965 
966 #undef ompt_event_macro
967 
968   default:
969     return ompt_set_error;
970   }
971 }
972 
ompt_multiplex_own_lookup(const char * name)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);
984 }
985 
ompt_multiplex_client_lookup(const char * 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);
997 }
998 
ompt_multiplex_initialize(ompt_function_lookup_t lookup,int initial_device_num,ompt_data_t * data)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");
1010 
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
1014 
1015   OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
1016 
1017 #undef ompt_event_macro
1018 
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));
1027 
1028   return ownRet > clientRet ? ownRet : clientRet;
1029 }
1030 
ompt_multiplex_finalize(ompt_data_t * fns)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));
1036 }
1037 
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);
1044 
ompt_start_tool(unsigned int omp_version,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;
1051 
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);
1059     }
1060 
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;
1078         }
1079       } else {
1080         printf("Loading %s from %s failed with: %s\n",
1081                tool_libs_buffer + progress, CLIENT_TOOL_LIBRARIES_VAR,
1082                dlerror());
1083       }
1084       progress = tmp_progress + 1;
1085     }
1086     free(tool_libs_buffer);
1087   }
1088   // load own tool
1089   ompt_multiplex_own_fns =
1090       ompt_multiplex_own_start_tool(omp_version, runtime_version);
1091 
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;
1096 }
1097 #ifdef __cplusplus
1098 }
1099 #endif
1100 
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
1104 
1105 #endif /* OMPT_MULTIPLEX_H */
1106