1211 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This header file enables an OMPT tool to load another OMPT tool and10// automatically forwards OMPT event-callbacks to the nested tool.11//12// For details see openmp/tools/multiplex/README.md13//14//===----------------------------------------------------------------------===//15 16#ifndef OMPT_MULTIPLEX_H17#define OMPT_MULTIPLEX_H18 19#ifndef _GNU_SOURCE20#define _GNU_SOURCE21#endif22#include <dlfcn.h>23#include <errno.h>24#ifndef __HAIKU__25#include <execinfo.h>26#endif27#include <inttypes.h>28#include <omp-tools.h>29#include <omp.h>30#include <stdio.h>31#include <string.h>32 33static ompt_set_callback_t ompt_multiplex_set_callback;34static ompt_get_task_info_t ompt_multiplex_get_task_info;35static ompt_get_thread_data_t ompt_multiplex_get_thread_data;36static ompt_get_parallel_info_t ompt_multiplex_get_parallel_info;37 38// If OMPT_MULTIPLEX_TOOL_NAME is defined, use the tool name as prefix39// contains name of the environment var in which the tool path is specified40// for TOOL_LIBRARIES and VERBOSE_INIT variables. Only overwrite, if41// they are not explicitly defined.42#ifdef OMPT_MULTIPLEX_TOOL_NAME43#ifndef CLIENT_TOOL_LIBRARIES_VAR44#define CLIENT_TOOL_LIBRARIES_VAR OMPT_MULTIPLEX_TOOL_NAME "_TOOL_LIBRARIES"45#endif46#ifndef CLIENT_TOOL_VERBOSE_INIT_VAR47#define CLIENT_TOOL_VERBOSE_INIT_VAR \48 OMPT_MULTIPLEX_TOOL_NAME "_TOOL_VERBOSE_INIT"49#endif50#endif51 52// If CLIENT_TOOL_VERBOSE_INIT_VAR is still not defined, use the OMPT53// env var.54#ifndef CLIENT_TOOL_VERBOSE_INIT_VAR55#warning CLIENT_TOOL_VERBOSE_INIT_VAR redefined to OMP_TOOL_VERBOSE_INIT56#define CLIENT_TOOL_VERBOSE_INIT_VAR "OMP_TOOL_VERBOSE_INIT"57#endif58 59// contains name of the environment var in which the tool path is specified60#ifndef CLIENT_TOOL_LIBRARIES_VAR61#error CLIENT_TOOL_LIBRARIES_VAR should be defined before including of ompt-multiplex.h62#endif63 64#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) && \65 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)66#error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA is set67#endif68 69#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA) && \70 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA)71#error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA is set72#endif73 74#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA) && \75 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA)76#error OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA must be set if OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA is set77#endif78 79#define OMPT_API_ROUTINE static80 81#ifndef OMPT_STR_MATCH82#define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))83#endif84 85// prints for an enabled OMP_TOOL_VERBOSE_INIT.86// In the future a prefix could be added in the first define, the second define87// omits the prefix to allow for continued lines. Example: "PREFIX: Start88// tool... Success." instead of "PREFIX: Start tool... PREFIX: Success."89#define OMPT_VERBOSE_INIT_PRINT(...) \90 if (verbose_init) \91 fprintf(verbose_file, __VA_ARGS__)92#define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...) \93 if (verbose_init) \94 fprintf(verbose_file, __VA_ARGS__)95 96static FILE *verbose_file;97static int verbose_init;98 99void setup_verbose_init() {100 const char *ompt_env_verbose_init = getenv(CLIENT_TOOL_VERBOSE_INIT_VAR);101 // possible options: disabled | stdout | stderr | <filename>102 // if set, not empty and not disabled -> prepare for logging103 if (ompt_env_verbose_init && strcmp(ompt_env_verbose_init, "") &&104 !OMPT_STR_MATCH(ompt_env_verbose_init, "disabled")) {105 verbose_init = 1;106 if (OMPT_STR_MATCH(ompt_env_verbose_init, "STDERR"))107 verbose_file = stderr;108 else if (OMPT_STR_MATCH(ompt_env_verbose_init, "STDOUT"))109 verbose_file = stdout;110 else if (!OMPT_STR_MATCH(ompt_env_verbose_init,111 getenv("OMP_TOOL_VERBOSE_INIT")))112 verbose_file = fopen(ompt_env_verbose_init, "w");113 else {114 verbose_init = 0;115 printf("Multiplex: Can not open file defined in OMP_TOOL_VERBOSE_INIT "116 "twice.");117 }118 } else119 verbose_init = 0;120}121 122#define OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(macro) \123 macro(callback_thread_begin, ompt_callback_thread_begin_t, 1); \124 macro(callback_thread_end, ompt_callback_thread_end_t, 2); \125 macro(callback_parallel_begin, ompt_callback_parallel_begin_t, 3); \126 macro(callback_parallel_end, ompt_callback_parallel_end_t, 4); \127 macro(callback_task_create, ompt_callback_task_create_t, 5); \128 macro(callback_task_schedule, ompt_callback_task_schedule_t, 6); \129 macro(callback_implicit_task, ompt_callback_implicit_task_t, 7); \130 macro(callback_target, ompt_callback_target_t, 8); \131 macro(callback_target_data_op, ompt_callback_target_data_op_t, 9); \132 macro(callback_target_submit, ompt_callback_target_submit_t, 10); \133 macro(callback_control_tool, ompt_callback_control_tool_t, 11); \134 macro(callback_device_initialize, ompt_callback_device_initialize_t, 12); \135 macro(callback_device_finalize, ompt_callback_device_finalize_t, 13); \136 macro(callback_device_load, ompt_callback_device_load_t, 14); \137 macro(callback_device_unload, ompt_callback_device_unload_t, 15); \138 macro(callback_sync_region_wait, ompt_callback_sync_region_t, 16); \139 macro(callback_mutex_released, ompt_callback_mutex_t, 17); \140 macro(callback_dependences, ompt_callback_dependences_t, 18); \141 macro(callback_task_dependence, ompt_callback_task_dependence_t, 19); \142 macro(callback_work, ompt_callback_work_t, 20); \143 macro(callback_masked, ompt_callback_masked_t, 21); \144 macro(callback_target_map, ompt_callback_target_map_t, 22); \145 macro(callback_sync_region, ompt_callback_sync_region_t, 23); \146 macro(callback_lock_init, ompt_callback_mutex_acquire_t, 24); \147 macro(callback_lock_destroy, ompt_callback_mutex_t, 25); \148 macro(callback_mutex_acquire, ompt_callback_mutex_acquire_t, 26); \149 macro(callback_mutex_acquired, ompt_callback_mutex_t, 27); \150 macro(callback_nest_lock, ompt_callback_nest_lock_t, 28); \151 macro(callback_flush, ompt_callback_flush_t, 29); \152 macro(callback_cancel, ompt_callback_cancel_t, 30); \153 macro(callback_reduction, ompt_callback_sync_region_t, 31); \154 macro(callback_dispatch, ompt_callback_dispatch_t, 32);155 156typedef struct ompt_multiplex_callbacks_s {157#define ompt_event_macro(event, callback, eventid) callback ompt_##event158 159 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)160 161#undef ompt_event_macro162} ompt_multiplex_callbacks_t;163 164typedef struct ompt_multiplex_callback_implementation_status_s {165#define ompt_event_macro(event, callback, eventid) int ompt_##event166 167 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)168 169#undef ompt_event_macro170} ompt_multiplex_callback_implementation_status_t;171 172ompt_start_tool_result_t *ompt_multiplex_own_fns = NULL;173ompt_start_tool_result_t *ompt_multiplex_client_fns = NULL;174ompt_function_lookup_t ompt_multiplex_lookup_function;175ompt_multiplex_callbacks_t ompt_multiplex_own_callbacks,176 ompt_multiplex_client_callbacks;177ompt_multiplex_callback_implementation_status_t178 ompt_multiplex_implementation_status;179 180typedef struct ompt_multiplex_data_pair_s {181 ompt_data_t own_data;182 ompt_data_t client_data;183} ompt_multiplex_data_pair_t;184 185#if !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) || \186 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) || \187 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)188static ompt_multiplex_data_pair_t *189ompt_multiplex_allocate_data_pair(ompt_data_t *data_pointer) {190 data_pointer->ptr = malloc(sizeof(ompt_multiplex_data_pair_t));191 if (!data_pointer->ptr) {192 printf("Malloc ERROR\n");193 exit(-1);194 }195 ompt_multiplex_data_pair_t *data_pair =196 (ompt_multiplex_data_pair_t *)data_pointer->ptr;197 data_pair->own_data.ptr = NULL;198 data_pair->client_data.ptr = NULL;199 return data_pair;200}201 202static void ompt_multiplex_free_data_pair(ompt_data_t *data_pointer) {203 free((*data_pointer).ptr);204}205 206static ompt_data_t *ompt_multiplex_get_own_ompt_data(ompt_data_t *data) {207 if (!data)208 return NULL;209 if (!data->ptr)210 return NULL;211 ompt_multiplex_data_pair_t *data_pair =212 (ompt_multiplex_data_pair_t *)data->ptr;213 return &(data_pair->own_data);214}215 216static ompt_data_t *ompt_multiplex_get_client_ompt_data(ompt_data_t *data) {217 if (!data)218 return NULL;219 if (!data->ptr)220 return NULL;221 ompt_multiplex_data_pair_t *data_pair =222 (ompt_multiplex_data_pair_t *)data->ptr;223 return &(data_pair->client_data);224}225#endif //! defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) ||226 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) ||227 //! !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)228 229static ompt_data_t *ompt_multiplex_get_own_thread_data(ompt_data_t *data) {230#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA231 return ompt_multiplex_get_own_ompt_data(data);232#else233 return data;234#endif235}236 237static ompt_data_t *ompt_multiplex_get_own_parallel_data(ompt_data_t *data) {238#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA239 return ompt_multiplex_get_own_ompt_data(data);240#else241 return data;242#endif243}244 245static ompt_data_t *ompt_multiplex_get_own_task_data(ompt_data_t *data) {246#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA247 return ompt_multiplex_get_own_ompt_data(data);248#else249 return data;250#endif251}252 253static ompt_data_t *ompt_multiplex_get_client_thread_data(ompt_data_t *data) {254#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA255 return ompt_multiplex_get_client_ompt_data(data);256#else257 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(data);258#endif259}260 261static ompt_data_t *ompt_multiplex_get_client_parallel_data(ompt_data_t *data) {262#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA263 return ompt_multiplex_get_client_ompt_data(data);264#else265 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(data);266#endif267}268 269static ompt_data_t *ompt_multiplex_get_client_task_data(ompt_data_t *data) {270#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA271 return ompt_multiplex_get_client_ompt_data(data);272#else273 return OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(data);274#endif275}276 277static void ompt_multiplex_callback_mutex_acquire(ompt_mutex_t kind,278 unsigned int hint,279 unsigned int impl,280 ompt_wait_id_t wait_id,281 const void *codeptr_ra) {282 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire) {283 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquire(284 kind, hint, impl, wait_id, codeptr_ra);285 }286 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire) {287 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquire(288 kind, hint, impl, wait_id, codeptr_ra);289 }290}291 292static void ompt_multiplex_callback_mutex_acquired(ompt_mutex_t kind,293 ompt_wait_id_t wait_id,294 const void *codeptr_ra) {295 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired) {296 ompt_multiplex_own_callbacks.ompt_callback_mutex_acquired(kind, wait_id,297 codeptr_ra);298 }299 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired) {300 ompt_multiplex_client_callbacks.ompt_callback_mutex_acquired(kind, wait_id,301 codeptr_ra);302 }303}304 305static void ompt_multiplex_callback_mutex_released(ompt_mutex_t kind,306 ompt_wait_id_t wait_id,307 const void *codeptr_ra) {308 if (ompt_multiplex_own_callbacks.ompt_callback_mutex_released) {309 ompt_multiplex_own_callbacks.ompt_callback_mutex_released(kind, wait_id,310 codeptr_ra);311 }312 if (ompt_multiplex_client_callbacks.ompt_callback_mutex_released) {313 ompt_multiplex_client_callbacks.ompt_callback_mutex_released(kind, wait_id,314 codeptr_ra);315 }316}317 318static void ompt_multiplex_callback_nest_lock(ompt_scope_endpoint_t endpoint,319 ompt_wait_id_t wait_id,320 const void *codeptr_ra) {321 if (ompt_multiplex_own_callbacks.ompt_callback_nest_lock) {322 ompt_multiplex_own_callbacks.ompt_callback_nest_lock(endpoint, wait_id,323 codeptr_ra);324 }325 if (ompt_multiplex_client_callbacks.ompt_callback_nest_lock) {326 ompt_multiplex_client_callbacks.ompt_callback_nest_lock(endpoint, wait_id,327 codeptr_ra);328 }329}330 331static void ompt_multiplex_callback_sync_region(ompt_sync_region_t kind,332 ompt_scope_endpoint_t endpoint,333 ompt_data_t *parallel_data,334 ompt_data_t *task_data,335 const void *codeptr_ra) {336 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region) {337 ompt_multiplex_own_callbacks.ompt_callback_sync_region(338 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),339 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);340 }341 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region) {342 ompt_multiplex_client_callbacks.ompt_callback_sync_region(343 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),344 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);345 }346}347 348static void ompt_multiplex_callback_sync_region_wait(349 ompt_sync_region_t kind, ompt_scope_endpoint_t endpoint,350 ompt_data_t *parallel_data, ompt_data_t *task_data,351 const void *codeptr_ra) {352 if (ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait) {353 ompt_multiplex_own_callbacks.ompt_callback_sync_region_wait(354 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),355 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);356 }357 if (ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait) {358 ompt_multiplex_client_callbacks.ompt_callback_sync_region_wait(359 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),360 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);361 }362}363 364static void ompt_multiplex_callback_flush(ompt_data_t *thread_data,365 const void *codeptr_ra) {366 if (ompt_multiplex_own_callbacks.ompt_callback_flush) {367 ompt_multiplex_own_callbacks.ompt_callback_flush(368 ompt_multiplex_get_own_thread_data(thread_data), codeptr_ra);369 }370 if (ompt_multiplex_client_callbacks.ompt_callback_flush) {371 ompt_multiplex_client_callbacks.ompt_callback_flush(372 ompt_multiplex_get_client_thread_data(thread_data), codeptr_ra);373 }374}375 376static void ompt_multiplex_callback_cancel(ompt_data_t *task_data, int flags,377 const void *codeptr_ra) {378 if (ompt_multiplex_own_callbacks.ompt_callback_cancel) {379 ompt_multiplex_own_callbacks.ompt_callback_cancel(380 ompt_multiplex_get_own_task_data(task_data), flags, codeptr_ra);381 }382 if (ompt_multiplex_client_callbacks.ompt_callback_cancel) {383 ompt_multiplex_client_callbacks.ompt_callback_cancel(384 ompt_multiplex_get_client_task_data(task_data), flags, codeptr_ra);385 }386}387 388static void ompt_multiplex_callback_implicit_task(389 ompt_scope_endpoint_t endpoint, ompt_data_t *parallel_data,390 ompt_data_t *task_data, unsigned int team_size, unsigned int thread_num,391 int flags) {392 if (endpoint == ompt_scope_begin) {393#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA394 ompt_multiplex_allocate_data_pair(task_data);395#endif396#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA397 if (flags & ompt_task_initial)398 ompt_multiplex_allocate_data_pair(parallel_data);399#endif400 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {401 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(402 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),403 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,404 flags);405 }406 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {407 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(408 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),409 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,410 flags);411 }412 } else {413// defines to make sure, callbacks are called in correct order depending on414// defines set by the user415#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \416 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)417 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {418 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(419 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),420 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,421 flags);422 }423#endif424 425 if (ompt_multiplex_client_callbacks.ompt_callback_implicit_task) {426 ompt_multiplex_client_callbacks.ompt_callback_implicit_task(427 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),428 ompt_multiplex_get_client_task_data(task_data), team_size, thread_num,429 flags);430 }431 432#if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \433 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)434 if (ompt_multiplex_own_callbacks.ompt_callback_implicit_task) {435 ompt_multiplex_own_callbacks.ompt_callback_implicit_task(436 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),437 ompt_multiplex_get_own_task_data(task_data), team_size, thread_num,438 flags);439 }440#endif441 442#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA443 ompt_multiplex_free_data_pair(task_data);444#endif445 446#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)447 if (flags & ompt_task_initial)448 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);449#endif450#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)451 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(task_data);452#endif453 }454}455 456static void ompt_multiplex_callback_lock_init(ompt_mutex_t kind,457 unsigned int hint,458 unsigned int impl,459 ompt_wait_id_t wait_id,460 const void *codeptr_ra) {461 if (ompt_multiplex_own_callbacks.ompt_callback_lock_init) {462 ompt_multiplex_own_callbacks.ompt_callback_lock_init(kind, hint, impl,463 wait_id, codeptr_ra);464 }465 if (ompt_multiplex_client_callbacks.ompt_callback_lock_init) {466 ompt_multiplex_client_callbacks.ompt_callback_lock_init(467 kind, hint, impl, wait_id, codeptr_ra);468 }469}470 471static void ompt_multiplex_callback_lock_destroy(ompt_mutex_t kind,472 ompt_wait_id_t wait_id,473 const void *codeptr_ra) {474 if (ompt_multiplex_own_callbacks.ompt_callback_lock_destroy) {475 ompt_multiplex_own_callbacks.ompt_callback_lock_destroy(kind, wait_id,476 codeptr_ra);477 }478 if (ompt_multiplex_client_callbacks.ompt_callback_lock_destroy) {479 ompt_multiplex_client_callbacks.ompt_callback_lock_destroy(kind, wait_id,480 codeptr_ra);481 }482}483 484static void ompt_multiplex_callback_work(ompt_work_t wstype,485 ompt_scope_endpoint_t endpoint,486 ompt_data_t *parallel_data,487 ompt_data_t *task_data, uint64_t count,488 const void *codeptr_ra) {489 if (ompt_multiplex_own_callbacks.ompt_callback_work) {490 ompt_multiplex_own_callbacks.ompt_callback_work(491 wstype, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),492 ompt_multiplex_get_own_task_data(task_data), count, codeptr_ra);493 }494 if (ompt_multiplex_client_callbacks.ompt_callback_work) {495 ompt_multiplex_client_callbacks.ompt_callback_work(496 wstype, endpoint,497 ompt_multiplex_get_client_parallel_data(parallel_data),498 ompt_multiplex_get_client_task_data(task_data), count, codeptr_ra);499 }500}501 502static void ompt_multiplex_callback_masked(ompt_scope_endpoint_t endpoint,503 ompt_data_t *parallel_data,504 ompt_data_t *task_data,505 const void *codeptr_ra) {506 if (ompt_multiplex_own_callbacks.ompt_callback_masked) {507 ompt_multiplex_own_callbacks.ompt_callback_masked(508 endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),509 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);510 }511 if (ompt_multiplex_client_callbacks.ompt_callback_masked) {512 ompt_multiplex_client_callbacks.ompt_callback_masked(513 endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),514 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);515 }516}517 518static void ompt_multiplex_callback_parallel_begin(519 ompt_data_t *parent_task_data, const ompt_frame_t *parent_task_frame,520 ompt_data_t *parallel_data, uint32_t requested_team_size, int flag,521 const void *codeptr_ra) {522#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA523 ompt_multiplex_allocate_data_pair(parallel_data);524#endif525 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_begin) {526 ompt_multiplex_own_callbacks.ompt_callback_parallel_begin(527 ompt_multiplex_get_own_task_data(parent_task_data), parent_task_frame,528 ompt_multiplex_get_own_parallel_data(parallel_data),529 requested_team_size, flag, codeptr_ra);530 }531 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_begin) {532 ompt_multiplex_client_callbacks.ompt_callback_parallel_begin(533 ompt_multiplex_get_client_task_data(parent_task_data),534 parent_task_frame,535 ompt_multiplex_get_client_parallel_data(parallel_data),536 requested_team_size, flag, codeptr_ra);537 }538}539 540static void ompt_multiplex_callback_parallel_end(ompt_data_t *parallel_data,541 ompt_data_t *task_data,542 int flag,543 const void *codeptr_ra) {544// defines to make sure, callbacks are called in correct order depending on545// defines set by the user546#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA) || \547 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA)548 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {549 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(550 ompt_multiplex_get_own_parallel_data(parallel_data),551 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);552 }553#endif554 555 if (ompt_multiplex_client_callbacks.ompt_callback_parallel_end) {556 ompt_multiplex_client_callbacks.ompt_callback_parallel_end(557 ompt_multiplex_get_client_parallel_data(parallel_data),558 ompt_multiplex_get_client_task_data(task_data), flag, codeptr_ra);559 }560 561#if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA) && \562 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)563 if (ompt_multiplex_own_callbacks.ompt_callback_parallel_end) {564 ompt_multiplex_own_callbacks.ompt_callback_parallel_end(565 ompt_multiplex_get_own_parallel_data(parallel_data),566 ompt_multiplex_get_own_task_data(task_data), flag, codeptr_ra);567 }568#endif569 570#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA571 ompt_multiplex_free_data_pair(parallel_data);572#endif573 574#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA)575 OMPT_MULTIPLEX_CUSTOM_DELETE_PARALLEL_DATA(parallel_data);576#endif577}578 579static void ompt_multiplex_callback_task_create(580 ompt_data_t *parent_task_data, const ompt_frame_t *parent_frame,581 ompt_data_t *new_task_data, int type, int has_dependences,582 const void *codeptr_ra) {583#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA584 ompt_multiplex_allocate_data_pair(new_task_data);585#endif586 587#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA588 if (type & ompt_task_initial) {589 ompt_data_t *parallel_data;590 ompt_multiplex_get_parallel_info(0, ¶llel_data, NULL);591 ompt_multiplex_allocate_data_pair(parallel_data);592 }593#endif594 595 if (ompt_multiplex_own_callbacks.ompt_callback_task_create) {596 ompt_multiplex_own_callbacks.ompt_callback_task_create(597 ompt_multiplex_get_own_task_data(parent_task_data), parent_frame,598 ompt_multiplex_get_own_task_data(new_task_data), type, has_dependences,599 codeptr_ra);600 }601 if (ompt_multiplex_client_callbacks.ompt_callback_task_create) {602 ompt_multiplex_client_callbacks.ompt_callback_task_create(603 ompt_multiplex_get_client_task_data(parent_task_data), parent_frame,604 ompt_multiplex_get_client_task_data(new_task_data), type,605 has_dependences, codeptr_ra);606 }607}608 609static void610ompt_multiplex_callback_task_schedule(ompt_data_t *first_task_data,611 ompt_task_status_t prior_task_status,612 ompt_data_t *second_task_data) {613 if (prior_task_status != ompt_task_complete) {614 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {615 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(616 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,617 ompt_multiplex_get_own_task_data(second_task_data));618 }619 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {620 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(621 ompt_multiplex_get_client_task_data(first_task_data),622 prior_task_status,623 ompt_multiplex_get_client_task_data(second_task_data));624 }625 } else {626// defines to make sure, callbacks are called in correct order depending on627// defines set by the user628#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA) || \629 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA)630 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {631 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(632 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,633 ompt_multiplex_get_own_task_data(second_task_data));634 }635#endif636 637 if (ompt_multiplex_client_callbacks.ompt_callback_task_schedule) {638 ompt_multiplex_client_callbacks.ompt_callback_task_schedule(639 ompt_multiplex_get_client_task_data(first_task_data),640 prior_task_status,641 ompt_multiplex_get_client_task_data(second_task_data));642 }643 644#if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA) && \645 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)646 if (ompt_multiplex_own_callbacks.ompt_callback_task_schedule) {647 ompt_multiplex_own_callbacks.ompt_callback_task_schedule(648 ompt_multiplex_get_own_task_data(first_task_data), prior_task_status,649 ompt_multiplex_get_own_task_data(second_task_data));650 }651#endif652 653#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA654 ompt_multiplex_free_data_pair(first_task_data);655#endif656 657#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA)658 OMPT_MULTIPLEX_CUSTOM_DELETE_TASK_DATA(first_task_data);659#endif660 }661}662 663static void ompt_multiplex_callback_dependences(ompt_data_t *task_data,664 const ompt_dependence_t *deps,665 int ndeps) {666 if (ompt_multiplex_own_callbacks.ompt_callback_dependences) {667 ompt_multiplex_own_callbacks.ompt_callback_dependences(668 ompt_multiplex_get_own_task_data(task_data), deps, ndeps);669 }670 if (ompt_multiplex_client_callbacks.ompt_callback_dependences) {671 ompt_multiplex_client_callbacks.ompt_callback_dependences(672 ompt_multiplex_get_client_task_data(task_data), deps, ndeps);673 }674}675 676static void677ompt_multiplex_callback_task_dependence(ompt_data_t *first_task_data,678 ompt_data_t *second_task_data) {679 if (ompt_multiplex_own_callbacks.ompt_callback_task_dependence) {680 ompt_multiplex_own_callbacks.ompt_callback_task_dependence(681 ompt_multiplex_get_own_task_data(first_task_data),682 ompt_multiplex_get_own_task_data(second_task_data));683 }684 if (ompt_multiplex_client_callbacks.ompt_callback_task_dependence) {685 ompt_multiplex_client_callbacks.ompt_callback_task_dependence(686 ompt_multiplex_get_client_task_data(first_task_data),687 ompt_multiplex_get_client_task_data(second_task_data));688 }689}690 691static void ompt_multiplex_callback_thread_begin(ompt_thread_t thread_type,692 ompt_data_t *thread_data) {693#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA694 ompt_multiplex_allocate_data_pair(thread_data);695#endif696 if (ompt_multiplex_own_callbacks.ompt_callback_thread_begin) {697 ompt_multiplex_own_callbacks.ompt_callback_thread_begin(698 thread_type, ompt_multiplex_get_own_thread_data(thread_data));699 }700 if (ompt_multiplex_client_callbacks.ompt_callback_thread_begin) {701 ompt_multiplex_client_callbacks.ompt_callback_thread_begin(702 thread_type, ompt_multiplex_get_client_thread_data(thread_data));703 }704}705 706static void ompt_multiplex_callback_thread_end(ompt_data_t *thread_data) {707// defines to make sure, callbacks are called in correct order depending on708// defines set by the user709#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA) || \710 !defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA)711 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {712 ompt_multiplex_own_callbacks.ompt_callback_thread_end(713 ompt_multiplex_get_own_thread_data(thread_data));714 }715#endif716 717 if (ompt_multiplex_client_callbacks.ompt_callback_thread_end) {718 ompt_multiplex_client_callbacks.ompt_callback_thread_end(719 ompt_multiplex_get_client_thread_data(thread_data));720 }721 722#if defined(OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA) && \723 !defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)724 if (ompt_multiplex_own_callbacks.ompt_callback_thread_end) {725 ompt_multiplex_own_callbacks.ompt_callback_thread_end(726 ompt_multiplex_get_own_thread_data(thread_data));727 }728#endif729 730#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA731 ompt_multiplex_free_data_pair(thread_data);732#endif733 734#if defined(OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA)735 OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA(thread_data);736#endif737}738 739static int ompt_multiplex_callback_control_tool(uint64_t command,740 uint64_t modifier, void *arg,741 const void *codeptr_ra) {742 int ownRet = 0, clientRet = 0;743 if (ompt_multiplex_own_callbacks.ompt_callback_control_tool) {744 ownRet = ompt_multiplex_own_callbacks.ompt_callback_control_tool(745 command, modifier, arg, codeptr_ra);746 }747 if (ompt_multiplex_client_callbacks.ompt_callback_control_tool) {748 clientRet = ompt_multiplex_client_callbacks.ompt_callback_control_tool(749 command, modifier, arg, codeptr_ra);750 }751 return ownRet < clientRet ? ownRet : clientRet;752}753 754static void ompt_multiplex_callback_target(755 ompt_target_t kind, ompt_scope_endpoint_t endpoint, int device_num,756 ompt_data_t *task_data, ompt_id_t target_id, const void *codeptr_ra) {757 if (ompt_multiplex_own_callbacks.ompt_callback_target) {758 ompt_multiplex_own_callbacks.ompt_callback_target(759 kind, endpoint, device_num, ompt_multiplex_get_own_task_data(task_data),760 target_id, codeptr_ra);761 }762 if (ompt_multiplex_client_callbacks.ompt_callback_target) {763 ompt_multiplex_client_callbacks.ompt_callback_target(764 kind, endpoint, device_num,765 ompt_multiplex_get_client_task_data(task_data), target_id, codeptr_ra);766 }767}768 769static void ompt_multiplex_callback_target_data_op(770 ompt_id_t target_id, ompt_id_t host_op_id, ompt_target_data_op_t optype,771 void *src_addr, int src_device_num, void *dest_addr, int dest_device_num,772 size_t bytes, const void *codeptr_ra) {773 if (ompt_multiplex_own_callbacks.ompt_callback_target_data_op) {774 ompt_multiplex_own_callbacks.ompt_callback_target_data_op(775 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,776 dest_device_num, bytes, codeptr_ra);777 }778 if (ompt_multiplex_client_callbacks.ompt_callback_target_data_op) {779 ompt_multiplex_client_callbacks.ompt_callback_target_data_op(780 target_id, host_op_id, optype, src_addr, src_device_num, dest_addr,781 dest_device_num, bytes, codeptr_ra);782 }783}784 785static void786ompt_multiplex_callback_target_submit(ompt_id_t target_id, ompt_id_t host_op_id,787 unsigned int requested_num_teams) {788 if (ompt_multiplex_own_callbacks.ompt_callback_target_submit) {789 ompt_multiplex_own_callbacks.ompt_callback_target_submit(790 target_id, host_op_id, requested_num_teams);791 }792 if (ompt_multiplex_client_callbacks.ompt_callback_target_submit) {793 ompt_multiplex_client_callbacks.ompt_callback_target_submit(794 target_id, host_op_id, requested_num_teams);795 }796}797 798static void ompt_multiplex_callback_device_initialize(799 int device_num, const char *type, ompt_device_t *device,800 ompt_function_lookup_t lookup, const char *documentation) {801 if (ompt_multiplex_own_callbacks.ompt_callback_device_initialize) {802 ompt_multiplex_own_callbacks.ompt_callback_device_initialize(803 device_num, type, device, lookup, documentation);804 }805 if (ompt_multiplex_client_callbacks.ompt_callback_device_initialize) {806 ompt_multiplex_client_callbacks.ompt_callback_device_initialize(807 device_num, type, device, lookup, documentation);808 }809}810 811static void ompt_multiplex_callback_device_finalize(int device_num) {812 if (ompt_multiplex_own_callbacks.ompt_callback_device_finalize) {813 ompt_multiplex_own_callbacks.ompt_callback_device_finalize(device_num);814 }815 if (ompt_multiplex_client_callbacks.ompt_callback_device_finalize) {816 ompt_multiplex_client_callbacks.ompt_callback_device_finalize(device_num);817 }818}819 820static void821ompt_multiplex_callback_device_load(int device_num, const char *filename,822 int64_t offset_in_file, void *vma_in_file,823 size_t bytes, void *host_addr,824 void *device_addr, uint64_t module_id) {825 if (ompt_multiplex_own_callbacks.ompt_callback_device_load) {826 ompt_multiplex_own_callbacks.ompt_callback_device_load(827 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,828 device_addr, module_id);829 }830 if (ompt_multiplex_client_callbacks.ompt_callback_device_load) {831 ompt_multiplex_client_callbacks.ompt_callback_device_load(832 device_num, filename, offset_in_file, vma_in_file, bytes, host_addr,833 device_addr, module_id);834 }835}836 837static void ompt_multiplex_callback_device_unload(int device_num,838 uint64_t module_id) {839 if (ompt_multiplex_own_callbacks.ompt_callback_device_unload) {840 ompt_multiplex_own_callbacks.ompt_callback_device_unload(device_num,841 module_id);842 }843 if (ompt_multiplex_client_callbacks.ompt_callback_device_unload) {844 ompt_multiplex_client_callbacks.ompt_callback_device_unload(device_num,845 module_id);846 }847}848 849static void850ompt_multiplex_callback_target_map(ompt_id_t target_id, unsigned int nitems,851 void **host_addr, void **device_addr,852 size_t *bytes, unsigned int *mapping_flags,853 const void *codeptr_ra) {854 if (ompt_multiplex_own_callbacks.ompt_callback_target_map) {855 ompt_multiplex_own_callbacks.ompt_callback_target_map(856 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,857 codeptr_ra);858 }859 if (ompt_multiplex_client_callbacks.ompt_callback_target_map) {860 ompt_multiplex_client_callbacks.ompt_callback_target_map(861 target_id, nitems, host_addr, device_addr, bytes, mapping_flags,862 codeptr_ra);863 }864}865 866static void ompt_multiplex_callback_reduction(ompt_sync_region_t kind,867 ompt_scope_endpoint_t endpoint,868 ompt_data_t *parallel_data,869 ompt_data_t *task_data,870 const void *codeptr_ra) {871 if (ompt_multiplex_own_callbacks.ompt_callback_reduction) {872 ompt_multiplex_own_callbacks.ompt_callback_reduction(873 kind, endpoint, ompt_multiplex_get_own_parallel_data(parallel_data),874 ompt_multiplex_get_own_task_data(task_data), codeptr_ra);875 }876 if (ompt_multiplex_client_callbacks.ompt_callback_reduction) {877 ompt_multiplex_client_callbacks.ompt_callback_reduction(878 kind, endpoint, ompt_multiplex_get_client_parallel_data(parallel_data),879 ompt_multiplex_get_client_task_data(task_data), codeptr_ra);880 }881}882 883static void ompt_multiplex_callback_dispatch(ompt_data_t *parallel_data,884 ompt_data_t *task_data,885 ompt_dispatch_t kind,886 ompt_data_t instance) {887 if (ompt_multiplex_own_callbacks.ompt_callback_dispatch) {888 ompt_multiplex_own_callbacks.ompt_callback_dispatch(889 ompt_multiplex_get_own_parallel_data(parallel_data),890 ompt_multiplex_get_own_task_data(task_data), kind, instance);891 }892 if (ompt_multiplex_client_callbacks.ompt_callback_dispatch) {893 ompt_multiplex_client_callbacks.ompt_callback_dispatch(894 ompt_multiplex_get_client_parallel_data(parallel_data),895 ompt_multiplex_get_client_task_data(task_data), kind, instance);896 }897}898 899// runtime entry functions900 901int ompt_multiplex_own_get_task_info(int ancestor_level, int *type,902 ompt_data_t **task_data,903 ompt_frame_t **task_frame,904 ompt_data_t **parallel_data,905 int *thread_num) {906 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,907 task_frame, parallel_data, thread_num);908 909#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA910 if (task_data)911 *task_data = ompt_multiplex_get_own_ompt_data(*task_data);912#endif913#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA914 if (parallel_data)915 *parallel_data = ompt_multiplex_get_own_ompt_data(*parallel_data);916#endif917 return ret;918}919 920int ompt_multiplex_client_get_task_info(int ancestor_level, int *type,921 ompt_data_t **task_data,922 ompt_frame_t **task_frame,923 ompt_data_t **parallel_data,924 int *thread_num) {925 int ret = ompt_multiplex_get_task_info(ancestor_level, type, task_data,926 task_frame, parallel_data, thread_num);927 928 if (task_data)929#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA930 *task_data = ompt_multiplex_get_client_ompt_data(*task_data);931#else932 *task_data = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA(*task_data);933#endif934 935 if (parallel_data)936#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA937 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);938#else939 *parallel_data =940 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);941#endif942 return ret;943}944 945ompt_data_t *ompt_multiplex_own_get_thread_data() {946 ompt_data_t *ret;947#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA948 ret = ompt_multiplex_get_own_ompt_data(ompt_multiplex_get_thread_data());949#else950 ret = ompt_multiplex_get_thread_data();951#endif952 return ret;953}954 955ompt_data_t *ompt_multiplex_client_get_thread_data() {956 ompt_data_t *ret;957#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA958 ret = ompt_multiplex_get_client_ompt_data(ompt_multiplex_get_thread_data());959#else960 ret = OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_THREAD_DATA(961 ompt_multiplex_get_thread_data());962#endif963 return ret;964}965 966int ompt_multiplex_own_get_parallel_info(int ancestor_level,967 ompt_data_t **parallel_data,968 int *team_size) {969 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,970 team_size);971 if (parallel_data)972 *parallel_data = ompt_multiplex_get_own_parallel_data(*parallel_data);973 return ret;974}975 976int ompt_multiplex_client_get_parallel_info(int ancestor_level,977 ompt_data_t **parallel_data,978 int *team_size) {979 int ret = ompt_multiplex_get_parallel_info(ancestor_level, parallel_data,980 team_size);981 if (parallel_data)982#ifndef OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA983 *parallel_data = ompt_multiplex_get_client_ompt_data(*parallel_data);984#else985 *parallel_data =986 OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_PARALLEL_DATA(*parallel_data);987#endif988 return ret;989}990 991OMPT_API_ROUTINE int ompt_multiplex_own_set_callback(ompt_callbacks_t which,992 ompt_callback_t callback) {993 switch (which) {994 995#define ompt_event_macro(event_name, callback_type, event_id) \996 case ompt_##event_name: \997 ompt_multiplex_own_callbacks.ompt_##event_name = (callback_type)callback; \998 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \999 return ompt_multiplex_implementation_status.ompt_##event_name = \1000 ompt_multiplex_set_callback( \1001 ompt_##event_name, \1002 (ompt_callback_t)&ompt_multiplex_##event_name); \1003 else \1004 return ompt_multiplex_implementation_status.ompt_##event_name1005 1006 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)1007 1008#undef ompt_event_macro1009 1010 default:1011 return ompt_set_error;1012 }1013}1014 1015OMPT_API_ROUTINE int1016ompt_multiplex_client_set_callback(ompt_callbacks_t which,1017 ompt_callback_t callback) {1018 switch (which) {1019 1020#define ompt_event_macro(event_name, callback_type, event_id) \1021 case ompt_##event_name: \1022 ompt_multiplex_client_callbacks.ompt_##event_name = \1023 (callback_type)callback; \1024 if (ompt_multiplex_implementation_status.ompt_##event_name == -1) \1025 return ompt_multiplex_implementation_status.ompt_##event_name = \1026 ompt_multiplex_set_callback( \1027 ompt_##event_name, \1028 (ompt_callback_t)&ompt_multiplex_##event_name); \1029 else \1030 return ompt_multiplex_implementation_status.ompt_##event_name1031 1032 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)1033 1034#undef ompt_event_macro1035 1036 default:1037 return ompt_set_error;1038 }1039}1040 1041ompt_interface_fn_t ompt_multiplex_own_lookup(const char *name) {1042 if (!strcmp(name, "ompt_set_callback"))1043 return (ompt_interface_fn_t)&ompt_multiplex_own_set_callback;1044 else if (!strcmp(name, "ompt_get_task_info"))1045 return (ompt_interface_fn_t)&ompt_multiplex_own_get_task_info;1046 else if (!strcmp(name, "ompt_get_thread_data"))1047 return (ompt_interface_fn_t)&ompt_multiplex_own_get_thread_data;1048 else if (!strcmp(name, "ompt_get_parallel_info"))1049 return (ompt_interface_fn_t)&ompt_multiplex_own_get_parallel_info;1050 else1051 return ompt_multiplex_lookup_function(name);1052}1053 1054ompt_interface_fn_t ompt_multiplex_client_lookup(const char *name) {1055 if (!strcmp(name, "ompt_set_callback"))1056 return (ompt_interface_fn_t)&ompt_multiplex_client_set_callback;1057 else if (!strcmp(name, "ompt_get_task_info"))1058 return (ompt_interface_fn_t)&ompt_multiplex_client_get_task_info;1059 else if (!strcmp(name, "ompt_get_thread_data"))1060 return (ompt_interface_fn_t)&ompt_multiplex_client_get_thread_data;1061 else if (!strcmp(name, "ompt_get_parallel_info"))1062 return (ompt_interface_fn_t)&ompt_multiplex_client_get_parallel_info;1063 else1064 return ompt_multiplex_lookup_function(name);1065}1066 1067int ompt_multiplex_initialize(ompt_function_lookup_t lookup,1068 int initial_device_num, ompt_data_t *data) {1069 ompt_multiplex_lookup_function = lookup;1070 ompt_multiplex_set_callback =1071 (ompt_set_callback_t)lookup("ompt_set_callback");1072 ompt_multiplex_get_task_info =1073 (ompt_get_task_info_t)lookup("ompt_get_task_info");1074 ompt_multiplex_get_thread_data =1075 (ompt_get_thread_data_t)lookup("ompt_get_thread_data");1076 ompt_multiplex_get_parallel_info =1077 (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info");1078 1079 // initialize ompt_multiplex_implementation_status1080#define ompt_event_macro(event_name, callback_type, event_id) \1081 ompt_multiplex_implementation_status.ompt_##event_name = -11082 1083 OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(ompt_event_macro)1084 1085#undef ompt_event_macro1086 1087 int ownRet = ompt_multiplex_own_fns->initialize(1088 ompt_multiplex_own_lookup, initial_device_num,1089 &(ompt_multiplex_own_fns->tool_data));1090 int clientRet = 0;1091 if (ompt_multiplex_client_fns)1092 clientRet = ompt_multiplex_client_fns->initialize(1093 ompt_multiplex_client_lookup, initial_device_num,1094 &(ompt_multiplex_client_fns->tool_data));1095 1096 return ownRet > clientRet ? ownRet : clientRet;1097}1098 1099void ompt_multiplex_finalize(ompt_data_t *fns) {1100 if (ompt_multiplex_client_fns)1101 ompt_multiplex_client_fns->finalize(1102 &(ompt_multiplex_client_fns->tool_data));1103 ompt_multiplex_own_fns->finalize(&(ompt_multiplex_own_fns->tool_data));1104}1105 1106#ifdef __cplusplus1107extern "C" {1108#endif1109 1110// forward declaration because of name shifting from ompt_start_tool1111// to ompt_multiplex_own_start_tool below1112ompt_start_tool_result_t *1113ompt_multiplex_own_start_tool(unsigned int omp_version,1114 const char *runtime_version);1115 1116ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,1117 const char *runtime_version) {1118 setup_verbose_init();1119 OMPT_VERBOSE_INIT_PRINT(1120 "----- START LOGGING OF CLIENT TOOL REGISTRATION -----\n");1121 // try loading client tool1122 OMPT_VERBOSE_INIT_PRINT("Search for " CLIENT_TOOL_LIBRARIES_VAR1123 " env var... ");1124 const char *tool_libs = getenv(CLIENT_TOOL_LIBRARIES_VAR);1125 if (tool_libs) {1126 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Sucess.\n");1127 OMPT_VERBOSE_INIT_PRINT(CLIENT_TOOL_LIBRARIES_VAR " = %s\n", tool_libs);1128 // copy environement variable1129 char *tool_libs_buffer = strdup(tool_libs);1130 if (!tool_libs_buffer) {1131 printf("strdup Error (%i)\n", errno);1132 exit(-1);1133 }1134 1135 int progress = 0;1136 // Reset dl-error1137 dlerror();1138 while (progress < strlen(tool_libs)) {1139 ompt_multiplex_client_fns = NULL;1140 ompt_start_tool_result_t *(*client_start_tool)(unsigned int,1141 const char *) = NULL;1142 OMPT_VERBOSE_INIT_PRINT(1143 "Look for candidates within " CLIENT_TOOL_LIBRARIES_VAR "...\n");1144 int tmp_progress = progress;1145 while (tmp_progress < strlen(tool_libs) &&1146 tool_libs_buffer[tmp_progress] != ':')1147 tmp_progress++;1148 if (tmp_progress < strlen(tool_libs))1149 tool_libs_buffer[tmp_progress] = 0;1150 OMPT_VERBOSE_INIT_PRINT("Try out one candidate...\n");1151 char *fname = tool_libs_buffer + progress;1152 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname);1153 void *h = dlopen(fname, RTLD_LAZY);1154 if (h) {1155 client_start_tool =1156 (ompt_start_tool_result_t * (*)(unsigned int, const char *))1157 dlsym(h, "ompt_start_tool");1158 if (client_start_tool &&1159 (ompt_multiplex_client_fns =1160 (*client_start_tool)(omp_version, runtime_version))) {1161 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Sucess.\n");1162 OMPT_VERBOSE_INIT_PRINT(1163 "Tool was started and is using the OMPT interface.\n");1164 break;1165 } else {1166 OMPT_VERBOSE_INIT_CONTINUED_PRINT(1167 "Failed: client_start_tool = %p, ompt_multiplex_client_fns = %p, "1168 "%s\n",1169 client_start_tool, ompt_multiplex_client_fns, dlerror());1170 }1171 } else {1172 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());1173 printf("Loading %s from %s failed with: %s\n",1174 tool_libs_buffer + progress, CLIENT_TOOL_LIBRARIES_VAR,1175 dlerror());1176 }1177 progress = tmp_progress + 1;1178 }1179 free(tool_libs_buffer);1180 OMPT_VERBOSE_INIT_PRINT(1181 "----- END LOGGING OF CLIENT TOOL REGISTRATION -----\n");1182 }1183 // load own tool1184 OMPT_VERBOSE_INIT_PRINT(1185 "----- START LOGGING OF OWN TOOL REGISTRATION -----\n");1186 ompt_multiplex_own_fns =1187 ompt_multiplex_own_start_tool(omp_version, runtime_version);1188 OMPT_VERBOSE_INIT_PRINT("ompt_multiplex_own_fns = %p\n",1189 ompt_multiplex_own_fns);1190 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF OWN TOOL REGISTRATION -----\n");1191 // return multiplexed versions1192 static ompt_start_tool_result_t ompt_start_tool_result = {1193 &ompt_multiplex_initialize, &ompt_multiplex_finalize, {0}};1194 if (verbose_init && verbose_file != stderr && verbose_file != stdout)1195 fclose(verbose_file);1196 if (!ompt_multiplex_client_fns)1197 return ompt_multiplex_own_fns;1198 if (!ompt_multiplex_own_fns)1199 return ompt_multiplex_client_fns;1200 return &ompt_start_tool_result;1201}1202#ifdef __cplusplus1203}1204#endif1205 1206// We rename the ompt_start_tool function of the OMPT tool and call the1207// renamed function from the ompt_start_tool function defined above.1208#define ompt_start_tool ompt_multiplex_own_start_tool1209 1210#endif /* OMPT_MULTIPLEX_H */1211