brintos

brintos / llvm-project-archived public Read only

0
0
Text · 51.1 KiB · 4c17802 Raw
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, &parallel_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