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 <execinfo.h>
24 #include <inttypes.h>
25 #include <omp-tools.h>
26 #include <omp.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <errno.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(CUSTOM_DELETE_DATA) && !defined(CUSTOM_GET_CLIENT_DATA)
42 #error CUSTOM_GET_CLIENT_DATA must be set if CUSTOM_DELETE_DATA is set
43 #endif
44
45 #define OMPT_API_ROUTINE static
46
47 #define OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(macro) \
48 macro(callback_thread_begin, ompt_callback_thread_begin_t, 1); \
49 macro(callback_thread_end, ompt_callback_thread_end_t, 2); \
50 macro(callback_parallel_begin, ompt_callback_parallel_begin_t, 3); \
51 macro(callback_parallel_end, ompt_callback_parallel_end_t, 4); \
52 macro(callback_task_create, ompt_callback_task_create_t, 5); \
53 macro(callback_task_schedule, ompt_callback_task_schedule_t, 6); \
54 macro(callback_implicit_task, ompt_callback_implicit_task_t, 7); \
55 macro(callback_target, ompt_callback_target_t, 8); \
56 macro(callback_target_data_op, ompt_callback_target_data_op_t, 9); \
57 macro(callback_target_submit, ompt_callback_target_submit_t, 10); \
58 macro(callback_control_tool, ompt_callback_control_tool_t, 11); \
59 macro(callback_device_initialize, ompt_callback_device_initialize_t, 12); \
60 macro(callback_device_finalize, ompt_callback_device_finalize_t, 13); \
61 macro(callback_device_load, ompt_callback_device_load_t, 14); \
62 macro(callback_device_unload, ompt_callback_device_unload_t, 15); \
63 macro(callback_sync_region_wait, ompt_callback_sync_region_t, 16); \
64 macro(callback_mutex_released, ompt_callback_mutex_t, 17); \
65 macro(callback_dependences, ompt_callback_dependences_t, 18); \
66 macro(callback_task_dependence, ompt_callback_task_dependence_t, 19); \
67 macro(callback_work, ompt_callback_work_t, 20); \
68 macro(callback_master, ompt_callback_master_t, 21); \
69 macro(callback_target_map, ompt_callback_target_map_t, 22); \
70 macro(callback_sync_region, ompt_callback_sync_region_t, 23); \
71 macro(callback_lock_init, ompt_callback_mutex_acquire_t, 24); \
72 macro(callback_lock_destroy, ompt_callback_mutex_t, 25); \
73 macro(callback_mutex_acquire, ompt_callback_mutex_acquire_t, 26); \
74 macro(callback_mutex_acquired, ompt_callback_mutex_t, 27); \
75 macro(callback_nest_lock, ompt_callback_nest_lock_t, 28); \
76 macro(callback_flush, ompt_callback_flush_t, 29); \
77 macro(callback_cancel, ompt_callback_cancel_t, 30); \
78 macro(callback_reduction, ompt_callback_sync_region_t, 31); \
79 macro(callback_dispatch, ompt_callback_dispatch_t, 32);
80
81 typedef struct ompt_multiplex_callbacks_s {
82 #define ompt_event_macro(event, callback, eventid) callback ompt_##event
83
84 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
85
86 #undef ompt_event_macro
87 } ompt_multiplex_callbacks_t;
88
89 typedef struct ompt_multiplex_callback_implementation_status_s {
90 #define ompt_event_macro(event, callback, eventid) int ompt_##event
91
92 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
93
94 #undef ompt_event_macro
95 } ompt_multiplex_callback_implementation_status_t;
96
97 ompt_start_tool_result_t *ompt_multiplex_own_fns;
98 ompt_start_tool_result_t *ompt_multiplex_client_fns;
99 ompt_function_lookup_t ompt_multiplex_lookup_function;
100 ompt_multiplex_callbacks_t ompt_multiplex_own_callbacks,
101 ompt_multiplex_client_callbacks;
102 ompt_multiplex_callback_implementation_status_t
103 ompt_multiplex_implementation_status;
104
105 typedef struct ompt_multiplex_data_pair_s {
106 ompt_data_t own_data;
107 ompt_data_t client_data;
108 } ompt_multiplex_data_pair_t;
109
110 #if !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) || \
111 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) || \
112 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
113 static ompt_multiplex_data_pair_t *
ompt_multiplex_allocate_data_pair(ompt_data_t * data_pointer)114 ompt_multiplex_allocate_data_pair(ompt_data_t *data_pointer) {
115 data_pointer->ptr = malloc(sizeof(ompt_multiplex_data_pair_t));
116 if (!data_pointer->ptr) {
117 printf("Malloc ERROR\n");
118 exit(-1);
119 }
120 ompt_multiplex_data_pair_t *data_pair =
121 (ompt_multiplex_data_pair_t *)data_pointer->ptr;
122 data_pair->own_data.ptr = NULL;
123 data_pair->client_data.ptr = NULL;
124 return data_pair;
125 }
126
ompt_multiplex_free_data_pair(ompt_data_t * data_pointer)127 static void ompt_multiplex_free_data_pair(ompt_data_t *data_pointer) {
128 free((*data_pointer).ptr);
129 }
130
ompt_multiplex_get_own_ompt_data(ompt_data_t * data)131 static ompt_data_t *ompt_multiplex_get_own_ompt_data(ompt_data_t *data) {
132 if (!data)
133 return NULL;
134 ompt_multiplex_data_pair_t *data_pair =
135 (ompt_multiplex_data_pair_t *)data->ptr;
136 return &(data_pair->own_data);
137 }
138
ompt_multiplex_get_client_ompt_data(ompt_data_t * data)139 static ompt_data_t *ompt_multiplex_get_client_ompt_data(ompt_data_t *data) {
140 if (!data)
141 return NULL;
142 ompt_multiplex_data_pair_t *data_pair =
143 (ompt_multiplex_data_pair_t *)data->ptr;
144 return &(data_pair->client_data);
145 }
146 #endif //! defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) ||
147 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) ||
148 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
149
ompt_multiplex_get_own_thread_data(ompt_data_t * data)150 static ompt_data_t *ompt_multiplex_get_own_thread_data(ompt_data_t *data) {
151 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
152 return ompt_multiplex_get_own_ompt_data(data);
153 #else
154 return data;
155 #endif
156 }
157
ompt_multiplex_get_own_parallel_data(ompt_data_t * data)158 static ompt_data_t *ompt_multiplex_get_own_parallel_data(ompt_data_t *data) {
159 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
160 return ompt_multiplex_get_own_ompt_data(data);
161 #else
162 return data;
163 #endif
164 }
165
ompt_multiplex_get_own_task_data(ompt_data_t * data)166 static ompt_data_t *ompt_multiplex_get_own_task_data(ompt_data_t *data) {
167 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
168 return ompt_multiplex_get_own_ompt_data(data);
169 #else
170 return data;
171 #endif
172 }
173
ompt_multiplex_get_client_thread_data(ompt_data_t * data)174 static ompt_data_t *ompt_multiplex_get_client_thread_data(ompt_data_t *data) {
175 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
176 return ompt_multiplex_get_client_ompt_data(data);
177 #else
178 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(data);
179 #endif
180 }
181
ompt_multiplex_get_client_parallel_data(ompt_data_t * data)182 static ompt_data_t *ompt_multiplex_get_client_parallel_data(ompt_data_t *data) {
183 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
184 return ompt_multiplex_get_client_ompt_data(data);
185 #else
186 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(data);
187 #endif
188 }
189
ompt_multiplex_get_client_task_data(ompt_data_t * data)190 static ompt_data_t *ompt_multiplex_get_client_task_data(ompt_data_t *data) {
191 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
192 return ompt_multiplex_get_client_ompt_data(data);
193 #else
194 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(data);
195 #endif
196 }
197
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)198 static void ompt_multiplex_callback_mutex_acquire(ompt_mutex_t kind,
199 unsigned int hint,
200 unsigned int impl,
201 ompt_wait_id_t wait_id,
202 const void *codeptr_ra) {
203 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire) {
204 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire(
205 kind, hint, impl, wait_id, codeptr_ra);
206 }
207 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire) {
208 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire(
209 kind, hint, impl, wait_id, codeptr_ra);
210 }
211 }
212
ompt_multiplex_callback_mutex_acquired(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * codeptr_ra)213 static void ompt_multiplex_callback_mutex_acquired(ompt_mutex_t kind,
214 ompt_wait_id_t wait_id,
215 const void *codeptr_ra) {
216 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired) {
217 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired(kind, wait_id,
218 codeptr_ra);
219 }
220 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired) {
221 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired(kind, wait_id,
222 codeptr_ra);
223 }
224 }
225
ompt_multiplex_callback_mutex_released(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * codeptr_ra)226 static void ompt_multiplex_callback_mutex_released(ompt_mutex_t kind,
227 ompt_wait_id_t wait_id,
228 const void *codeptr_ra) {
229 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_released) {
230 ompt_multiplex_own_callbacks.ompt_callback_mutex_released(kind, wait_id,
231 codeptr_ra);
232 }
233 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_released) {
234 ompt_multiplex_client_callbacks.ompt_callback_mutex_released(kind, wait_id,
235 codeptr_ra);
236 }
237 }
238
ompt_multiplex_callback_nest_lock(ompt_scope_endpoint_t endpoint,ompt_wait_id_t wait_id,const void * codeptr_ra)239 static void ompt_multiplex_callback_nest_lock(ompt_scope_endpoint_t endpoint,
240 ompt_wait_id_t wait_id,
241 const void *codeptr_ra) {
242 if (ompt_multiplex_own_callbacks.ompt_callback_nest_lock) {
243 ompt_multiplex_own_callbacks.ompt_callback_nest_lock(endpoint, wait_id,
244 codeptr_ra);
245 }
246 if (ompt_multiplex_client_callbacks.ompt_callback_nest_lock) {
247 ompt_multiplex_client_callbacks.ompt_callback_nest_lock(endpoint, wait_id,
248 codeptr_ra);
249 }
250 }
251
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)252 static void ompt_multiplex_callback_sync_region(ompt_sync_region_t kind,
253 ompt_scope_endpoint_t endpoint,
254 ompt_data_t *parallel_data,
255 ompt_data_t *task_data,
256 const void *codeptr_ra) {
257 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region) {
258 ompt_multiplex_own_callbacks.ompt_callback_sync_region(
259 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
260 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
261 }
262 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region) {
263 ompt_multiplex_client_callbacks.ompt_callback_sync_region(
264 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
265 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
266 }
267 }
268
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)269 static void ompt_multiplex_callback_sync_region_wait(
270 ompt_sync_region_t kind, ompt_scope_endpoint_t endpoint,
271 ompt_data_t *parallel_data, ompt_data_t *task_data,
272 const void *codeptr_ra) {
273 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait) {
274 ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait(
275 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
276 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
277 }
278 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait) {
279 ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait(
280 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
281 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
282 }
283 }
284
ompt_multiplex_callback_flush(ompt_data_t * thread_data,const void * codeptr_ra)285 static void ompt_multiplex_callback_flush(ompt_data_t *thread_data,
286 const void *codeptr_ra) {
287 if (ompt_multiplex_own_callbacks.ompt_callback_flush) {
288 ompt_multiplex_own_callbacks.ompt_callback_flush(
289 ompt_multiplex_get_own_thread_data(thread_data), codeptr_ra);
290 }
291 if (ompt_multiplex_client_callbacks.ompt_callback_flush) {
292 ompt_multiplex_client_callbacks.ompt_callback_flush(
293 ompt_multiplex_get_client_thread_data(thread_data), codeptr_ra);
294 }
295 }
296
ompt_multiplex_callback_cancel(ompt_data_t * task_data,int flags,const void * codeptr_ra)297 static void ompt_multiplex_callback_cancel(ompt_data_t *task_data, int flags,
298 const void *codeptr_ra) {
299 if (ompt_multiplex_own_callbacks.ompt_callback_cancel) {
300 ompt_multiplex_own_callbacks.ompt_callback_cancel(
301 ompt_multiplex_get_own_task_data(task_data), flags, codeptr_ra);
302 }
303 if (ompt_multiplex_client_callbacks.ompt_callback_cancel) {
304 ompt_multiplex_client_callbacks.ompt_callback_cancel(
305 ompt_multiplex_get_client_task_data(task_data), flags, codeptr_ra);
306 }
307 }
308
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)309 static void ompt_multiplex_callback_implicit_task(
310 ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data,
311 ompt_data_t *task_data, unsigned int team_size, unsigned int thread_num,
312 int flags) {
313 if (endpoint == ompt_scope_begin) {
314 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
315 ompt_multiplex_allocate_data_pair(task_data);
316 #endif
317 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
318 if (flags & ompt_task_initial)
319 ompt_multiplex_allocate_data_pair(parallel_data);
320 #endif
321 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
322 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
323 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
324 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
325 flags);
326 }
327 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {
328 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(
329 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
330 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,
331 flags);
332 }
333 } else {
334 // defines to make sure, callbacks are called in correct order depending on
335 // defines set by the user
336 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \
337 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
338 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
339 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
340 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
341 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
342 flags);
343 }
344 #endif
345
346 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {
347 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(
348 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
349 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,
350 flags);
351 }
352
353 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \
354 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
355 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {
356 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(
357 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
358 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,
359 flags);
360 }
361 #endif
362
363 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
364 ompt_multiplex_free_data_pair(task_data);
365 #endif
366
367 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
368 if (flags & ompt_task_initial)
369 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);
370 #endif
371 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
372 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(task_data);
373 #endif
374 }
375 }
376
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)377 static void ompt_multiplex_callback_lock_init(ompt_mutex_t kind,
378 unsigned int hint,
379 unsigned int impl,
380 ompt_wait_id_t wait_id,
381 const void *codeptr_ra) {
382 if (ompt_multiplex_own_callbacks.ompt_callback_lock_init) {
383 ompt_multiplex_own_callbacks.ompt_callback_lock_init(kind, hint, impl,
384 wait_id, codeptr_ra);
385 }
386 if (ompt_multiplex_client_callbacks.ompt_callback_lock_init) {
387 ompt_multiplex_client_callbacks.ompt_callback_lock_init(
388 kind, hint, impl, wait_id, codeptr_ra);
389 }
390 }
391
ompt_multiplex_callback_lock_destroy(ompt_mutex_t kind,ompt_wait_id_t wait_id,const void * codeptr_ra)392 static void ompt_multiplex_callback_lock_destroy(ompt_mutex_t kind,
393 ompt_wait_id_t wait_id,
394 const void *codeptr_ra) {
395 if (ompt_multiplex_own_callbacks.ompt_callback_lock_destroy) {
396 ompt_multiplex_own_callbacks.ompt_callback_lock_destroy(kind, wait_id,
397 codeptr_ra);
398 }
399 if (ompt_multiplex_client_callbacks.ompt_callback_lock_destroy) {
400 ompt_multiplex_client_callbacks.ompt_callback_lock_destroy(kind, wait_id,
401 codeptr_ra);
402 }
403 }
404
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)405 static void ompt_multiplex_callback_work(ompt_work_t wstype,
406 ompt_scope_endpoint_t endpoint,
407 ompt_data_t *parallel_data,
408 ompt_data_t *task_data, uint64_t count,
409 const void *codeptr_ra) {
410 if (ompt_multiplex_own_callbacks.ompt_callback_work) {
411 ompt_multiplex_own_callbacks.ompt_callback_work(
412 wstype, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
413 ompt_multiplex_get_own_task_data(task_data), count, codeptr_ra);
414 }
415 if (ompt_multiplex_client_callbacks.ompt_callback_work) {
416 ompt_multiplex_client_callbacks.ompt_callback_work(
417 wstype, endpoint,
418 ompt_multiplex_get_client_parallel_data(parallel_data),
419 ompt_multiplex_get_client_task_data(task_data), count, codeptr_ra);
420 }
421 }
422
ompt_multiplex_callback_master(ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,const void * codeptr_ra)423 static void ompt_multiplex_callback_master(ompt_scope_endpoint_t endpoint,
424 ompt_data_t *parallel_data,
425 ompt_data_t *task_data,
426 const void *codeptr_ra) {
427 if (ompt_multiplex_own_callbacks.ompt_callback_master) {
428 ompt_multiplex_own_callbacks.ompt_callback_master(
429 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
430 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
431 }
432 if (ompt_multiplex_client_callbacks.ompt_callback_master) {
433 ompt_multiplex_client_callbacks.ompt_callback_master(
434 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
435 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
436 }
437 }
438
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)439 static void ompt_multiplex_callback_parallel_begin(
440 ompt_data_t *parent_task_data, const ompt_frame_t *parent_task_frame,
441 ompt_data_t *parallel_data, uint32_t requested_team_size, int flag,
442 const void *codeptr_ra) {
443 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
444 ompt_multiplex_allocate_data_pair(parallel_data);
445 #endif
446 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_begin) {
447 ompt_multiplex_own_callbacks.ompt_callback_parallel_begin(
448 ompt_multiplex_get_own_task_data(parent_task_data), parent_task_frame,
449 ompt_multiplex_get_own_parallel_data(parallel_data),
450 requested_team_size, flag, codeptr_ra);
451 }
452 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_begin) {
453 ompt_multiplex_client_callbacks.ompt_callback_parallel_begin(
454 ompt_multiplex_get_client_task_data(parent_task_data),
455 parent_task_frame,
456 ompt_multiplex_get_client_parallel_data(parallel_data),
457 requested_team_size, flag, codeptr_ra);
458 }
459 }
460
ompt_multiplex_callback_parallel_end(ompt_data_t * parallel_data,ompt_data_t * task_data,int flag,const void * codeptr_ra)461 static void ompt_multiplex_callback_parallel_end(ompt_data_t *parallel_data,
462 ompt_data_t *task_data,
463 int flag,
464 const void *codeptr_ra) {
465 // defines to make sure, callbacks are called in correct order depending on
466 // defines set by the user
467 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA) || \
468 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA)
469 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {
470 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(
471 ompt_multiplex_get_own_parallel_data(parallel_data),
472 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);
473 }
474 #endif
475
476 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_end) {
477 ompt_multiplex_client_callbacks.ompt_callback_parallel_end(
478 ompt_multiplex_get_client_parallel_data(parallel_data),
479 ompt_multiplex_get_client_task_data(task_data), flag, codeptr_ra);
480 }
481
482 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) && \
483 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
484 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {
485 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(
486 ompt_multiplex_get_own_parallel_data(parallel_data),
487 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);
488 }
489 #endif
490
491 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
492 ompt_multiplex_free_data_pair(parallel_data);
493 #endif
494
495 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)
496 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);
497 #endif
498 }
499
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)500 static void ompt_multiplex_callback_task_create(
501 ompt_data_t *parent_task_data, const ompt_frame_t *parent_frame,
502 ompt_data_t *new_task_data, int type, int has_dependences,
503 const void *codeptr_ra) {
504 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
505 ompt_multiplex_allocate_data_pair(new_task_data);
506 #endif
507
508 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
509 if (type & ompt_task_initial) {
510 ompt_data_t *parallel_data;
511 ompt_multiplex_get_parallel_info(0, ¶llel_data, NULL);
512 ompt_multiplex_allocate_data_pair(parallel_data);
513 }
514 #endif
515
516 if (ompt_multiplex_own_callbacks.ompt_callback_task_create) {
517 ompt_multiplex_own_callbacks.ompt_callback_task_create(
518 ompt_multiplex_get_own_task_data(parent_task_data), parent_frame,
519 ompt_multiplex_get_own_task_data(new_task_data), type, has_dependences,
520 codeptr_ra);
521 }
522 if (ompt_multiplex_client_callbacks.ompt_callback_task_create) {
523 ompt_multiplex_client_callbacks.ompt_callback_task_create(
524 ompt_multiplex_get_client_task_data(parent_task_data), parent_frame,
525 ompt_multiplex_get_client_task_data(new_task_data), type,
526 has_dependences, codeptr_ra);
527 }
528 }
529
530 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)531 ompt_multiplex_callback_task_schedule(ompt_data_t *first_task_data,
532 ompt_task_status_t prior_task_status,
533 ompt_data_t *second_task_data) {
534 if (prior_task_status != ompt_task_complete) {
535 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
536 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
537 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
538 ompt_multiplex_get_own_task_data(second_task_data));
539 }
540 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {
541 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(
542 ompt_multiplex_get_client_task_data(first_task_data),
543 prior_task_status,
544 ompt_multiplex_get_client_task_data(second_task_data));
545 }
546 } else {
547 // defines to make sure, callbacks are called in correct order depending on
548 // defines set by the user
549 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \
550 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)
551 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
552 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
553 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
554 ompt_multiplex_get_own_task_data(second_task_data));
555 }
556 #endif
557
558 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {
559 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(
560 ompt_multiplex_get_client_task_data(first_task_data),
561 prior_task_status,
562 ompt_multiplex_get_client_task_data(second_task_data));
563 }
564
565 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \
566 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
567 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {
568 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(
569 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,
570 ompt_multiplex_get_own_task_data(second_task_data));
571 }
572 #endif
573
574 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
575 ompt_multiplex_free_data_pair(first_task_data);
576 #endif
577
578 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)
579 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(first_task_data);
580 #endif
581 }
582 }
583
ompt_multiplex_callback_dependences(ompt_data_t * task_data,const ompt_dependence_t * deps,int ndeps)584 static void ompt_multiplex_callback_dependences(ompt_data_t *task_data,
585 const ompt_dependence_t *deps,
586 int ndeps) {
587 if (ompt_multiplex_own_callbacks.ompt_callback_dependences) {
588 ompt_multiplex_own_callbacks.ompt_callback_dependences(
589 ompt_multiplex_get_own_task_data(task_data), deps, ndeps);
590 }
591 if (ompt_multiplex_client_callbacks.ompt_callback_dependences) {
592 ompt_multiplex_client_callbacks.ompt_callback_dependences(
593 ompt_multiplex_get_client_task_data(task_data), deps, ndeps);
594 }
595 }
596
597 static void
ompt_multiplex_callback_task_dependence(ompt_data_t * first_task_data,ompt_data_t * second_task_data)598 ompt_multiplex_callback_task_dependence(ompt_data_t *first_task_data,
599 ompt_data_t *second_task_data) {
600 if (ompt_multiplex_own_callbacks.ompt_callback_task_dependence) {
601 ompt_multiplex_own_callbacks.ompt_callback_task_dependence(
602 ompt_multiplex_get_own_task_data(first_task_data),
603 ompt_multiplex_get_own_task_data(second_task_data));
604 }
605 if (ompt_multiplex_client_callbacks.ompt_callback_task_dependence) {
606 ompt_multiplex_client_callbacks.ompt_callback_task_dependence(
607 ompt_multiplex_get_client_task_data(first_task_data),
608 ompt_multiplex_get_client_task_data(second_task_data));
609 }
610 }
611
ompt_multiplex_callback_thread_begin(ompt_thread_t thread_type,ompt_data_t * thread_data)612 static void ompt_multiplex_callback_thread_begin(ompt_thread_t thread_type,
613 ompt_data_t *thread_data) {
614 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
615 ompt_multiplex_allocate_data_pair(thread_data);
616 #endif
617 if (ompt_multiplex_own_callbacks.ompt_callback_thread_begin) {
618 ompt_multiplex_own_callbacks.ompt_callback_thread_begin(
619 thread_type, ompt_multiplex_get_own_thread_data(thread_data));
620 }
621 if (ompt_multiplex_client_callbacks.ompt_callback_thread_begin) {
622 ompt_multiplex_client_callbacks.ompt_callback_thread_begin(
623 thread_type, ompt_multiplex_get_client_thread_data(thread_data));
624 }
625 }
626
ompt_multiplex_callback_thread_end(ompt_data_t * thread_data)627 static void ompt_multiplex_callback_thread_end(ompt_data_t *thread_data) {
628 // defines to make sure, callbacks are called in correct order depending on
629 // defines set by the user
630 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA) || \
631 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA)
632 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {
633 ompt_multiplex_own_callbacks.ompt_callback_thread_end(
634 ompt_multiplex_get_own_thread_data(thread_data));
635 }
636 #endif
637
638 if (ompt_multiplex_client_callbacks.ompt_callback_thread_end) {
639 ompt_multiplex_client_callbacks.ompt_callback_thread_end(
640 ompt_multiplex_get_client_thread_data(thread_data));
641 }
642
643 #if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) && \
644 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)
645 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {
646 ompt_multiplex_own_callbacks.ompt_callback_thread_end(
647 ompt_multiplex_get_own_thread_data(thread_data));
648 }
649 #endif
650
651 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
652 ompt_multiplex_free_data_pair(thread_data);
653 #endif
654
655 #if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)
656 OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA(thread_data);
657 #endif
658 }
659
ompt_multiplex_callback_control_tool(uint64_t command,uint64_t modifier,void * arg,const void * codeptr_ra)660 static int ompt_multiplex_callback_control_tool(uint64_t command,
661 uint64_t modifier, void *arg,
662 const void *codeptr_ra) {
663 int ownRet = 0, clientRet = 0;
664 if (ompt_multiplex_own_callbacks.ompt_callback_control_tool) {
665 ownRet = ompt_multiplex_own_callbacks.ompt_callback_control_tool(
666 command, modifier, arg, codeptr_ra);
667 }
668 if (ompt_multiplex_client_callbacks.ompt_callback_control_tool) {
669 clientRet = ompt_multiplex_client_callbacks.ompt_callback_control_tool(
670 command, modifier, arg, codeptr_ra);
671 }
672 return ownRet < clientRet ? ownRet : clientRet;
673 }
674
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)675 static void ompt_multiplex_callback_target(
676 ompt_target_t kind, ompt_scope_endpoint_t endpoint, int device_num,
677 ompt_data_t *task_data, ompt_id_t target_id, const void *codeptr_ra) {
678 if (ompt_multiplex_own_callbacks.ompt_callback_target) {
679 ompt_multiplex_own_callbacks.ompt_callback_target(
680 kind, endpoint, device_num, ompt_multiplex_get_own_task_data(task_data),
681 target_id, codeptr_ra);
682 }
683 if (ompt_multiplex_client_callbacks.ompt_callback_target) {
684 ompt_multiplex_client_callbacks.ompt_callback_target(
685 kind, endpoint, device_num,
686 ompt_multiplex_get_client_task_data(task_data), target_id, codeptr_ra);
687 }
688 }
689
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)690 static void ompt_multiplex_callback_target_data_op(
691 ompt_id_t target_id, ompt_id_t host_op_id, ompt_target_data_op_t optype,
692 void *src_addr, int src_device_num, void *dest_addr, int dest_device_num,
693 size_t bytes, const void *codeptr_ra) {
694 if (ompt_multiplex_own_callbacks.ompt_callback_target_data_op) {
695 ompt_multiplex_own_callbacks.ompt_callback_target_data_op(
696 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,
697 dest_device_num, bytes, codeptr_ra);
698 }
699 if (ompt_multiplex_client_callbacks.ompt_callback_target_data_op) {
700 ompt_multiplex_client_callbacks.ompt_callback_target_data_op(
701 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,
702 dest_device_num, bytes, codeptr_ra);
703 }
704 }
705
706 static void
ompt_multiplex_callback_target_submit(ompt_id_t target_id,ompt_id_t host_op_id,unsigned int requested_num_teams)707 ompt_multiplex_callback_target_submit(ompt_id_t target_id, ompt_id_t host_op_id,
708 unsigned int requested_num_teams) {
709 if (ompt_multiplex_own_callbacks.ompt_callback_target_submit) {
710 ompt_multiplex_own_callbacks.ompt_callback_target_submit(
711 target_id, host_op_id, requested_num_teams);
712 }
713 if (ompt_multiplex_client_callbacks.ompt_callback_target_submit) {
714 ompt_multiplex_client_callbacks.ompt_callback_target_submit(
715 target_id, host_op_id, requested_num_teams);
716 }
717 }
718
ompt_multiplex_callback_device_initialize(int device_num,const char * type,ompt_device_t * device,ompt_function_lookup_t lookup,const char * documentation)719 static void ompt_multiplex_callback_device_initialize(
720 int device_num, const char *type, ompt_device_t *device,
721 ompt_function_lookup_t lookup, const char *documentation) {
722 if (ompt_multiplex_own_callbacks.ompt_callback_device_initialize) {
723 ompt_multiplex_own_callbacks.ompt_callback_device_initialize(
724 device_num, type, device, lookup, documentation);
725 }
726 if (ompt_multiplex_client_callbacks.ompt_callback_device_initialize) {
727 ompt_multiplex_client_callbacks.ompt_callback_device_initialize(
728 device_num, type, device, lookup, documentation);
729 }
730 }
731
ompt_multiplex_callback_device_finalize(int device_num)732 static void ompt_multiplex_callback_device_finalize(int device_num) {
733 if (ompt_multiplex_own_callbacks.ompt_callback_device_finalize) {
734 ompt_multiplex_own_callbacks.ompt_callback_device_finalize(device_num);
735 }
736 if (ompt_multiplex_client_callbacks.ompt_callback_device_finalize) {
737 ompt_multiplex_client_callbacks.ompt_callback_device_finalize(device_num);
738 }
739 }
740
741 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)742 ompt_multiplex_callback_device_load(int device_num, const char *filename,
743 int64_t offset_in_file, void *vma_in_file,
744 size_t bytes, void *host_addr,
745 void *device_addr, uint64_t module_id) {
746 if (ompt_multiplex_own_callbacks.ompt_callback_device_load) {
747 ompt_multiplex_own_callbacks.ompt_callback_device_load(
748 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,
749 device_addr, module_id);
750 }
751 if (ompt_multiplex_client_callbacks.ompt_callback_device_load) {
752 ompt_multiplex_client_callbacks.ompt_callback_device_load(
753 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,
754 device_addr, module_id);
755 }
756 }
757
ompt_multiplex_callback_device_unload(int device_num,uint64_t module_id)758 static void ompt_multiplex_callback_device_unload(int device_num,
759 uint64_t module_id) {
760 if (ompt_multiplex_own_callbacks.ompt_callback_device_unload) {
761 ompt_multiplex_own_callbacks.ompt_callback_device_unload(device_num,
762 module_id);
763 }
764 if (ompt_multiplex_client_callbacks.ompt_callback_device_unload) {
765 ompt_multiplex_client_callbacks.ompt_callback_device_unload(device_num,
766 module_id);
767 }
768 }
769
770 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)771 ompt_multiplex_callback_target_map(ompt_id_t target_id, unsigned int nitems,
772 void **host_addr, void **device_addr,
773 size_t *bytes, unsigned int *mapping_flags,
774 const void *codeptr_ra) {
775 if (ompt_multiplex_own_callbacks.ompt_callback_target_map) {
776 ompt_multiplex_own_callbacks.ompt_callback_target_map(
777 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,
778 codeptr_ra);
779 }
780 if (ompt_multiplex_client_callbacks.ompt_callback_target_map) {
781 ompt_multiplex_client_callbacks.ompt_callback_target_map(
782 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,
783 codeptr_ra);
784 }
785 }
786
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)787 static void ompt_multiplex_callback_reduction(ompt_sync_region_t kind,
788 ompt_scope_endpoint_t endpoint,
789 ompt_data_t *parallel_data,
790 ompt_data_t *task_data,
791 const void *codeptr_ra) {
792 if (ompt_multiplex_own_callbacks.ompt_callback_reduction) {
793 ompt_multiplex_own_callbacks.ompt_callback_reduction(
794 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),
795 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);
796 }
797 if (ompt_multiplex_client_callbacks.ompt_callback_reduction) {
798 ompt_multiplex_client_callbacks.ompt_callback_reduction(
799 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),
800 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);
801 }
802 }
803
ompt_multiplex_callback_dispatch(ompt_data_t * parallel_data,ompt_data_t * task_data,ompt_dispatch_t kind,ompt_data_t instance)804 static void ompt_multiplex_callback_dispatch(ompt_data_t *parallel_data,
805 ompt_data_t *task_data,
806 ompt_dispatch_t kind,
807 ompt_data_t instance) {
808 if (ompt_multiplex_own_callbacks.ompt_callback_dispatch) {
809 ompt_multiplex_own_callbacks.ompt_callback_dispatch(
810 ompt_multiplex_get_own_parallel_data(parallel_data),
811 ompt_multiplex_get_own_task_data(task_data), kind, instance);
812 }
813 if (ompt_multiplex_client_callbacks.ompt_callback_dispatch) {
814 ompt_multiplex_client_callbacks.ompt_callback_dispatch(
815 ompt_multiplex_get_client_parallel_data(parallel_data),
816 ompt_multiplex_get_client_task_data(task_data), kind, instance);
817 }
818 }
819
820 // runtime entry functions
821
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)822 int ompt_multiplex_own_get_task_info(int ancestor_level, int *type,
823 ompt_data_t **task_data,
824 ompt_frame_t **task_frame,
825 ompt_data_t **parallel_data,
826 int *thread_num) {
827 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,
828 task_frame, parallel_data, thread_num);
829
830 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
831 if (task_data)
832 *task_data = ompt_multiplex_get_own_ompt_data(*task_data);
833 #endif
834 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
835 if (parallel_data)
836 *parallel_data = ompt_multiplex_get_own_ompt_data(*parallel_data);
837 #endif
838 return ret;
839 }
840
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)841 int ompt_multiplex_client_get_task_info(int ancestor_level, int *type,
842 ompt_data_t **task_data,
843 ompt_frame_t **task_frame,
844 ompt_data_t **parallel_data,
845 int *thread_num) {
846 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,
847 task_frame, parallel_data, thread_num);
848
849 if (task_data)
850 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA
851 *task_data = ompt_multiplex_get_client_ompt_data(*task_data);
852 #else
853 *task_data = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(*task_data);
854 #endif
855
856 if (parallel_data)
857 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
858 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);
859 #else
860 *parallel_data =
861 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);
862 #endif
863 return ret;
864 }
865
ompt_multiplex_own_get_thread_data()866 ompt_data_t *ompt_multiplex_own_get_thread_data() {
867 ompt_data_t *ret;
868 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
869 ret = ompt_multiplex_get_own_ompt_data(ompt_multiplex_get_thread_data());
870 #else
871 ret = ompt_multiplex_get_thread_data();
872 #endif
873 return ret;
874 }
875
ompt_multiplex_client_get_thread_data()876 ompt_data_t *ompt_multiplex_client_get_thread_data() {
877 ompt_data_t *ret;
878 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA
879 ret = ompt_multiplex_get_client_ompt_data(ompt_multiplex_get_thread_data());
880 #else
881 ret = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(
882 ompt_multiplex_get_thread_data());
883 #endif
884 return ret;
885 }
886
ompt_multiplex_own_get_parallel_info(int ancestor_level,ompt_data_t ** parallel_data,int * team_size)887 int ompt_multiplex_own_get_parallel_info(int ancestor_level,
888 ompt_data_t **parallel_data,
889 int *team_size) {
890 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,
891 team_size);
892 if (parallel_data)
893 *parallel_data = ompt_multiplex_get_own_parallel_data(*parallel_data);
894 return ret;
895 }
896
ompt_multiplex_client_get_parallel_info(int ancestor_level,ompt_data_t ** parallel_data,int * team_size)897 int ompt_multiplex_client_get_parallel_info(int ancestor_level,
898 ompt_data_t **parallel_data,
899 int *team_size) {
900 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,
901 team_size);
902 if (parallel_data)
903 #ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA
904 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);
905 #else
906 *parallel_data =
907 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);
908 #endif
909 return ret;
910 }
911
ompt_multiplex_own_set_callback(ompt_callbacks_t which,ompt_callback_t callback)912 OMPT_API_ROUTINE int ompt_multiplex_own_set_callback(ompt_callbacks_t which,
913 ompt_callback_t callback) {
914 switch (which) {
915
916 #define ompt_event_macro(event_name, callback_type, event_id) \
917 case ompt_##event_name: \
918 ompt_multiplex_own_callbacks.ompt_##event_name = (callback_type)callback; \
919 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \
920 return ompt_multiplex_implementation_status.ompt_##event_name = \
921 ompt_multiplex_set_callback( \
922 ompt_##event_name, \
923 (ompt_callback_t)&ompt_multiplex_##event_name); \
924 else \
925 return ompt_multiplex_implementation_status.ompt_##event_name
926
927 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
928
929 #undef ompt_event_macro
930
931 default:
932 return ompt_set_error;
933 }
934 }
935
936 OMPT_API_ROUTINE int
ompt_multiplex_client_set_callback(ompt_callbacks_t which,ompt_callback_t callback)937 ompt_multiplex_client_set_callback(ompt_callbacks_t which,
938 ompt_callback_t callback) {
939 switch (which) {
940
941 #define ompt_event_macro(event_name, callback_type, event_id) \
942 case ompt_##event_name: \
943 ompt_multiplex_client_callbacks.ompt_##event_name = \
944 (callback_type)callback; \
945 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \
946 return ompt_multiplex_implementation_status.ompt_##event_name = \
947 ompt_multiplex_set_callback( \
948 ompt_##event_name, \
949 (ompt_callback_t)&ompt_multiplex_##event_name); \
950 else \
951 return ompt_multiplex_implementation_status.ompt_##event_name
952
953 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
954
955 #undef ompt_event_macro
956
957 default:
958 return ompt_set_error;
959 }
960 }
961
ompt_multiplex_own_lookup(const char * name)962 ompt_interface_fn_t ompt_multiplex_own_lookup(const char *name) {
963 if (!strcmp(name, "ompt_set_callback"))
964 return (ompt_interface_fn_t)&ompt_multiplex_own_set_callback;
965 else if (!strcmp(name, "ompt_get_task_info"))
966 return (ompt_interface_fn_t)&ompt_multiplex_own_get_task_info;
967 else if (!strcmp(name, "ompt_get_thread_data"))
968 return (ompt_interface_fn_t)&ompt_multiplex_own_get_thread_data;
969 else if (!strcmp(name, "ompt_get_parallel_info"))
970 return (ompt_interface_fn_t)&ompt_multiplex_own_get_parallel_info;
971 else
972 return ompt_multiplex_lookup_function(name);
973 }
974
ompt_multiplex_client_lookup(const char * name)975 ompt_interface_fn_t ompt_multiplex_client_lookup(const char *name) {
976 if (!strcmp(name, "ompt_set_callback"))
977 return (ompt_interface_fn_t)&ompt_multiplex_client_set_callback;
978 else if (!strcmp(name, "ompt_get_task_info"))
979 return (ompt_interface_fn_t)&ompt_multiplex_client_get_task_info;
980 else if (!strcmp(name, "ompt_get_thread_data"))
981 return (ompt_interface_fn_t)&ompt_multiplex_client_get_thread_data;
982 else if (!strcmp(name, "ompt_get_parallel_info"))
983 return (ompt_interface_fn_t)&ompt_multiplex_client_get_parallel_info;
984 else
985 return ompt_multiplex_lookup_function(name);
986 }
987
ompt_multiplex_initialize(ompt_function_lookup_t lookup,int initial_device_num,ompt_data_t * data)988 int ompt_multiplex_initialize(ompt_function_lookup_t lookup,
989 int initial_device_num, ompt_data_t *data) {
990 ompt_multiplex_lookup_function = lookup;
991 ompt_multiplex_set_callback =
992 (ompt_set_callback_t)lookup("ompt_set_callback");
993 ompt_multiplex_get_task_info =
994 (ompt_get_task_info_t)lookup("ompt_get_task_info");
995 ompt_multiplex_get_thread_data =
996 (ompt_get_thread_data_t)lookup("ompt_get_thread_data");
997 ompt_multiplex_get_parallel_info =
998 (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info");
999
1000 // initialize ompt_multiplex_implementation_status
1001 #define ompt_event_macro(event_name, callback_type, event_id) \
1002 ompt_multiplex_implementation_status.ompt_##event_name = -1
1003
1004 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)
1005
1006 #undef ompt_event_macro
1007
1008 int ownRet = ompt_multiplex_own_fns->initialize(
1009 ompt_multiplex_own_lookup, initial_device_num,
1010 &(ompt_multiplex_own_fns->tool_data));
1011 int clientRet = 0;
1012 if (ompt_multiplex_client_fns)
1013 clientRet = ompt_multiplex_client_fns->initialize(
1014 ompt_multiplex_client_lookup, initial_device_num,
1015 &(ompt_multiplex_client_fns->tool_data));
1016
1017 return ownRet > clientRet ? ownRet : clientRet;
1018 }
1019
ompt_multiplex_finalize(ompt_data_t * fns)1020 void ompt_multiplex_finalize(ompt_data_t *fns) {
1021 if (ompt_multiplex_client_fns)
1022 ompt_multiplex_client_fns->finalize(
1023 &(ompt_multiplex_client_fns->tool_data));
1024 ompt_multiplex_own_fns->finalize(&(ompt_multiplex_own_fns->tool_data));
1025 }
1026
1027 #ifdef __cplusplus
1028 extern "C" {
1029 #endif
1030 ompt_start_tool_result_t *
1031 ompt_multiplex_own_start_tool(unsigned int omp_version,
1032 const char *runtime_version);
1033
ompt_start_tool(unsigned int omp_version,const char * runtime_version)1034 ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
1035 const char *runtime_version) {
1036 // try loading client tool
1037 ompt_multiplex_client_fns = NULL;
1038 ompt_start_tool_result_t *(*client_start_tool)(unsigned int, const char *) =
1039 NULL;
1040
1041 const char *tool_libs = getenv(CLIENT_TOOL_LIBRARIES_VAR);
1042 if (tool_libs) {
1043 // copy environement variable
1044 char *tool_libs_buffer = strdup(tool_libs);
1045 if (!tool_libs_buffer) {
1046 printf("strdup Error (%i)\n", errno);
1047 exit(-1);
1048 }
1049
1050 int progress = 0;
1051 while (progress < strlen(tool_libs)) {
1052 int tmp_progress = progress;
1053 while (tmp_progress < strlen(tool_libs) &&
1054 tool_libs_buffer[tmp_progress] != ':')
1055 tmp_progress++;
1056 if (tmp_progress < strlen(tool_libs))
1057 tool_libs_buffer[tmp_progress] = 0;
1058 void *h = dlopen(tool_libs_buffer + progress, RTLD_LAZY);
1059 if (h) {
1060 client_start_tool =
1061 (ompt_start_tool_result_t * (*)(unsigned int, const char *))
1062 dlsym(h, "ompt_start_tool");
1063 if (client_start_tool &&
1064 (ompt_multiplex_client_fns =
1065 (*client_start_tool)(omp_version, runtime_version))) {
1066 break;
1067 }
1068 } else {
1069 printf("Loading %s from %s failed with: %s\n",
1070 tool_libs_buffer + progress, CLIENT_TOOL_LIBRARIES_VAR,
1071 dlerror());
1072 }
1073 progress = tmp_progress + 1;
1074 }
1075 free(tool_libs_buffer);
1076 }
1077 // load own tool
1078 ompt_multiplex_own_fns =
1079 ompt_multiplex_own_start_tool(omp_version, runtime_version);
1080
1081 // return multiplexed versions
1082 static ompt_start_tool_result_t ompt_start_tool_result = {
1083 &ompt_multiplex_initialize, &ompt_multiplex_finalize, {0}};
1084 return &ompt_start_tool_result;
1085 }
1086 #ifdef __cplusplus
1087 }
1088 #endif
1089
1090 // We rename the ompt_start_tool function of the OMPT tool and call the
1091 // renamed function from the ompt_start_tool function defined above.
1092 #define ompt_start_tool ompt_multiplex_own_start_tool
1093
1094 #endif /* OMPT_MULTIPLEX_H */
1095