brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.7 KiB · cd8acb5 Raw
1101 lines · c
1#ifndef _BSD_SOURCE2#define _BSD_SOURCE3#endif4#ifndef _DEFAULT_SOURCE5#define _DEFAULT_SOURCE6#endif7#include <stdio.h>8#ifndef __STDC_FORMAT_MACROS9#define __STDC_FORMAT_MACROS10#endif11#include <inttypes.h>12#include <omp.h>13#include <omp-tools.h>14#include "ompt-signal.h"15#include <stdlib.h>16#include <assert.h>17 18// Used to detect architecture19#include "../../src/kmp_platform.h"20 21#ifndef _TOOL_PREFIX22#define _TOOL_PREFIX ""23// If no _TOOL_PREFIX is set, we assume that we run as part of an OMPT test24#define _OMPT_TESTS25#endif26 27static const char *ompt_thread_t_values[] = {28    "ompt_thread_UNDEFINED", "ompt_thread_initial", "ompt_thread_worker",29    "ompt_thread_other"};30 31static const char *ompt_task_status_t_values[] = {32    "ompt_task_UNDEFINED",33    "ompt_task_complete", // 134    "ompt_task_yield", // 235    "ompt_task_cancel", // 336    "ompt_task_detach", // 437    "ompt_task_early_fulfill", // 538    "ompt_task_late_fulfill", // 639    "ompt_task_switch", // 740    "ompt_taskwait_complete" // 841};42static const char *ompt_cancel_flag_t_values[] = {43    "ompt_cancel_parallel",      "ompt_cancel_sections",44    "ompt_cancel_loop",          "ompt_cancel_taskgroup",45    "ompt_cancel_activated",     "ompt_cancel_detected",46    "ompt_cancel_discarded_task"};47 48static const char *ompt_work_t_values[] = {"undefined",49                                           "ompt_work_loop",50                                           "ompt_work_sections",51                                           "ompt_work_single_executor",52                                           "ompt_work_single_other",53                                           "ompt_work_workshare",54                                           "ompt_work_distribute",55                                           "ompt_work_taskloop",56                                           "ompt_work_scope",57                                           "ompt_work_workdistribute",58                                           "ompt_work_loop_static",59                                           "ompt_work_loop_dynamic",60                                           "ompt_work_loop_guided",61                                           "ompt_work_loop_other"};62 63static const char *ompt_work_events_t_values[] = {"undefined",64                                                  "ompt_event_loop",65                                                  "ompt_event_sections",66                                                  "ompt_event_single_in_block",67                                                  "ompt_event_single_others",68                                                  "ompt_event_workshare",69                                                  "ompt_event_distribute",70                                                  "ompt_event_taskloop",71                                                  "ompt_event_scope",72                                                  "ompt_event_workdistribute",73                                                  "ompt_event_loop_static",74                                                  "ompt_event_loop_dynamic",75                                                  "ompt_event_loop_guided",76                                                  "ompt_event_loop_other"};77 78static const char *ompt_dependence_type_t_values[36] = {79    "ompt_dependence_type_UNDEFINED",80    "ompt_dependence_type_in", // 181    "ompt_dependence_type_out", // 282    "ompt_dependence_type_inout", // 383    "ompt_dependence_type_mutexinoutset", // 484    "ompt_dependence_type_source", // 585    "ompt_dependence_type_sink", // 686    "ompt_dependence_type_inoutset", // 787    "",88    "",89    "",90    "",91    "",92    "", // 8-1393    "",94    "",95    "",96    "",97    "",98    "",99    "",100    "",101    "",102    "", // 14-23103    "",104    "",105    "",106    "",107    "",108    "",109    "",110    "",111    "",112    "", // 24-33113    "ompt_dependence_type_out_all_memory", // 34114    "ompt_dependence_type_inout_all_memory" // 35115};116 117static const char *ompt_sync_region_t_values[] = {"undefined",118                                                  "barrier",119                                                  "barrier_implicit",120                                                  "barrier_explicit",121                                                  "barrier_implementation",122                                                  "taskwait",123                                                  "taskgroup",124                                                  "reduction",125                                                  "barrier_implicit_workshare",126                                                  "barrier_implicit_parallel",127                                                  "barrier_teams"};128 129static void format_task_type(int type, char *buffer) {130  char *progress = buffer;131  if (type & ompt_task_initial)132    progress += sprintf(progress, "ompt_task_initial");133  if (type & ompt_task_implicit)134    progress += sprintf(progress, "ompt_task_implicit");135  if (type & ompt_task_explicit)136    progress += sprintf(progress, "ompt_task_explicit");137  if (type & ompt_task_target)138    progress += sprintf(progress, "ompt_task_target");139  if (type & ompt_task_taskwait)140    progress += sprintf(progress, "ompt_task_taskwait");141  if (type & ompt_task_undeferred)142    progress += sprintf(progress, "|ompt_task_undeferred");143  if (type & ompt_task_untied)144    progress += sprintf(progress, "|ompt_task_untied");145  if (type & ompt_task_final)146    progress += sprintf(progress, "|ompt_task_final");147  if (type & ompt_task_mergeable)148    progress += sprintf(progress, "|ompt_task_mergeable");149  if (type & ompt_task_merged)150    progress += sprintf(progress, "|ompt_task_merged");151}152 153static ompt_set_callback_t ompt_set_callback;154static ompt_get_callback_t ompt_get_callback;155static ompt_get_state_t ompt_get_state;156static ompt_get_task_info_t ompt_get_task_info;157static ompt_get_task_memory_t ompt_get_task_memory;158static ompt_get_thread_data_t ompt_get_thread_data;159static ompt_get_parallel_info_t ompt_get_parallel_info;160static ompt_get_unique_id_t ompt_get_unique_id;161static ompt_finalize_tool_t ompt_finalize_tool;162static ompt_get_num_procs_t ompt_get_num_procs;163static ompt_get_num_places_t ompt_get_num_places;164static ompt_get_place_proc_ids_t ompt_get_place_proc_ids;165static ompt_get_place_num_t ompt_get_place_num;166static ompt_get_partition_place_nums_t ompt_get_partition_place_nums;167static ompt_get_proc_id_t ompt_get_proc_id;168static ompt_enumerate_states_t ompt_enumerate_states;169static ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls;170 171void assert_frame_flags(int enterf, int exitf) {172  if (!(enterf == (ompt_frame_application | ompt_frame_cfa) ||173        enterf == (ompt_frame_runtime | ompt_frame_cfa))) {174    printf("enter_frame_flags (%i) is invalid\n", enterf);175    fflush(NULL);176  }177  if (!(exitf == (ompt_frame_application | ompt_frame_cfa) ||178        exitf == (ompt_frame_runtime | ompt_frame_cfa))) {179    printf("exit_frame_flags (%i) is invalid\n", exitf);180    fflush(NULL);181  }182  assert(enterf == (ompt_frame_application | ompt_frame_cfa) ||183         enterf == (ompt_frame_runtime | ompt_frame_cfa));184  assert(exitf == (ompt_frame_application | ompt_frame_cfa) ||185         exitf == (ompt_frame_runtime | ompt_frame_cfa));186}187static void print_ids(int level) {188  int task_type, thread_num;189  ompt_frame_t *frame;190  ompt_data_t *task_parallel_data;191  ompt_data_t *task_data;192  int exists_task = ompt_get_task_info(level, &task_type, &task_data, &frame,193                                       &task_parallel_data, &thread_num);194  char buffer[2048];195  format_task_type(task_type, buffer);196  if (frame) {197    printf("%" PRIu64 ": task level %d: parallel_id=%" PRIx64198           ", task_id=%" PRIx64 ", exit_frame=%p, reenter_frame=%p, "199           "task_type=%s=%d, thread_num=%d\n",200           ompt_get_thread_data()->value, level,201           exists_task ? task_parallel_data->value : 0,202           exists_task ? task_data->value : 0, frame->exit_frame.ptr,203           frame->enter_frame.ptr, buffer, task_type, thread_num);204    assert_frame_flags(frame->enter_frame_flags, frame->exit_frame_flags);205  }206}207 208#define get_frame_address(level) __builtin_frame_address(level)209 210#define print_frame(level)                                                     \211  printf("%" PRIu64 ": __builtin_frame_address(%d)=%p\n",                      \212         ompt_get_thread_data()->value, level, get_frame_address(level))213 214// clang (version 5.0 and above) adds an intermediate function call with debug215// flag (-g)216#if defined(TEST_NEED_PRINT_FRAME_FROM_OUTLINED_FN)217#if defined(DEBUG) && defined(__clang__) && __clang_major__ >= 5218#define print_frame_from_outlined_fn(level) print_frame(level + 1)219#else220#define print_frame_from_outlined_fn(level) print_frame(level)221#endif222 223#if defined(__clang__) && __clang_major__ >= 5224#warning                                                                       \225    "Clang 5.0 and later add an additional wrapper for outlined functions when compiling with debug information."226#warning                                                                       \227    "Please define -DDEBUG iff you manually pass in -g to make the tests succeed!"228#endif229#endif230 231// This macro helps to define a label at the current position that can be used232// to get the current address in the code.233//234// For print_current_address():235//   To reliably determine the offset between the address of the label and the236//   actual return address, we insert a NOP instruction as a jump target as the237//   compiler would otherwise insert an instruction that we can't control. The238//   instruction length is target dependent and is explained below.239//240// (The empty block between "#pragma omp ..." and the __asm__ statement is a241// workaround for a bug in the Intel Compiler.)242#define define_ompt_label(id)                                                  \243  {                                                                            \244  }                                                                            \245  __asm__("nop");                                                              \246  ompt_label_##id:247 248// This macro helps to get the address of a label that is inserted by the above249// macro define_ompt_label(). The address is obtained with a GNU extension250// (&&label) that has been tested with gcc, clang and icc.251#define get_ompt_label_address(id) (&&ompt_label_##id)252 253// This macro prints the exact address that a previously called runtime function254// returns to.255#define print_current_address(id)                                              \256  define_ompt_label(id)                                                        \257      print_possible_return_addresses(get_ompt_label_address(id))258 259#if KMP_ARCH_X86 || KMP_ARCH_X86_64260// On X86 the NOP instruction is 1 byte long. In addition, the compiler inserts261// a MOV instruction for non-void runtime functions which is 3 bytes long.262#define print_possible_return_addresses(addr)                                  \263  printf("%" PRIu64 ": current_address=%p or %p for non-void functions\n",     \264         ompt_get_thread_data()->value, ((char *)addr) - 1,                    \265         ((char *)addr) - 4)266#elif KMP_ARCH_PPC64267// On Power the NOP instruction is 4 bytes long. In addition, the compiler268// inserts a second NOP instruction (another 4 bytes). For non-void runtime269// functions Clang inserts a STW instruction (but only if compiling under270// -fno-PIC which will be the default with Clang 8.0, another 4 bytes).271#define print_possible_return_addresses(addr)                                  \272  printf("%" PRIu64 ": current_address=%p or %p\n",                            \273         ompt_get_thread_data()->value, ((char *)addr) - 8,                    \274         ((char *)addr) - 12)275#elif KMP_ARCH_AARCH64 || KMP_ARCH_AARCH64_32276// On AArch64 the NOP instruction is 4 bytes long, can be followed by inserted277// store instruction (another 4 bytes long).278// FIXME: PR #65696 addded a third possibility (12 byte offset) to make the279// tests pass on Darwin. Adding the same for other OSes. However, the proper280// fix for this is to remove the extra branch instruction being generated by281// the AArch64 backend. See issue #69627.282#define print_possible_return_addresses(addr)                                  \283  printf("%" PRIu64 ": current_address=%p or %p or %p\n",                      \284         ompt_get_thread_data()->value, ((char *)addr) - 4,                    \285         ((char *)addr) - 8, ((char *)addr) - 12)286#elif KMP_ARCH_RISCV64287#if __riscv_compressed288// On RV64GC the C.NOP instruction is 2 byte long. In addition, the compiler289// inserts a J instruction (targeting the successor basic block), which290// accounts for another 4 bytes. Finally, an additional J instruction may291// appear (adding 4 more bytes) when the C.NOP is referenced elsewhere (ie.292// another branch).293#define print_possible_return_addresses(addr)                                  \294  printf("%" PRIu64 ": current_address=%p or %p\n",                            \295         ompt_get_thread_data()->value, ((char *)addr) - 6,                    \296         ((char *)addr) - 10)297#else298// On RV64G the NOP instruction is 4 byte long. In addition, the compiler299// inserts a J instruction (targeting the successor basic block), which300// accounts for another 4 bytes. Finally, an additional J instruction may301// appear (adding 4 more bytes) when the NOP is referenced elsewhere (ie.302// another branch).303#define print_possible_return_addresses(addr)                                  \304  printf("%" PRIu64 ": current_address=%p or %p\n",                            \305         ompt_get_thread_data()->value, ((char *)addr) - 8,                    \306         ((char *)addr) - 12)307#endif308#elif KMP_ARCH_LOONGARCH64309// On LoongArch64 the NOP instruction is 4 bytes long, can be followed by310// inserted jump instruction (another 4 bytes long). And an additional jump311// instruction may appear (adding 4 more bytes) when the NOP is referenced312// elsewhere (ie. another branch).313#define print_possible_return_addresses(addr)                                  \314  printf("%" PRIu64 ": current_address=%p or %p or %p\n",                      \315         ompt_get_thread_data()->value, ((char *)addr) - 4,                    \316         ((char *)addr) - 8, ((char *)addr) - 12)317#elif KMP_ARCH_VE318// On VE the NOP instruction is 8 byte long. In addition, the compiler inserts319// a ??? instruction for non-void runtime functions which is ? bytes long.320#define print_possible_return_addresses(addr)                                  \321  printf("%" PRIu64 ": current_address=%p or %p\n",                            \322         ompt_get_thread_data()->value, ((char *)addr) - 8,                    \323         ((char *)addr) - 8)324#elif KMP_ARCH_S390X325// On s390x the NOP instruction is 2 bytes long. For non-void runtime326// functions Clang inserts a STY instruction (but only if compiling under327// -fno-PIC which will be the default with Clang 8.0, another 6 bytes).328//329// Another possibility is:330//331//                brasl %r14,__kmpc_end_master@plt332//   a7 f4 00 02  j 0f333//   47 00 00 00  0: nop334//   a7 f4 00 02  j addr335//                addr:336#define print_possible_return_addresses(addr)                                  \337  printf("%" PRIu64 ": current_address=%p or %p or %p\n",                      \338         ompt_get_thread_data()->value, ((char *)addr) - 2,                    \339         ((char *)addr) - 8, ((char *)addr) - 12)340#elif KMP_ARCH_SPARC341// FIXME: Need to distinguish between 32 and 64-bit SPARC?342// On SPARC the NOP instruction is 4 bytes long.343// FIXME: Explain.  Can use __builtin_frob_return_addr?344#define print_possible_return_addresses(addr)                                  \345  printf("%" PRIu64 ": current_address=%p or %p\n",                            \346         ompt_get_thread_data()->value, ((char *)addr) - 12,                   \347         (char *)addr - 20)348#else349#error Unsupported target architecture, cannot determine address offset!350#endif351 352// This macro performs a somewhat similar job to print_current_address(), except353// that it discards a certain number of nibbles from the address and only prints354// the most significant bits / nibbles. This can be used for cases where the355// return address can only be approximated.356//357// To account for overflows (ie the most significant bits / nibbles have just358// changed as we are a few bytes above the relevant power of two) the addresses359// of the "current" and of the "previous block" are printed.360#define print_fuzzy_address(id)                                                \361  define_ompt_label(id) print_fuzzy_address_blocks(get_ompt_label_address(id))362 363// If you change this define you need to adapt all capture patterns in the tests364// to include or discard the new number of nibbles!365#define FUZZY_ADDRESS_DISCARD_NIBBLES 2366#define FUZZY_ADDRESS_DISCARD_BYTES (1 << ((FUZZY_ADDRESS_DISCARD_NIBBLES) * 4))367#define print_fuzzy_address_blocks(addr)                                       \368  printf("%" PRIu64 ": fuzzy_address=0x%" PRIx64 " or 0x%" PRIx64              \369         " or 0x%" PRIx64 " or 0x%" PRIx64 " (%p)\n",                          \370         ompt_get_thread_data()->value,                                        \371         ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES - 1,                   \372         ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES,                       \373         ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES + 1,                   \374         ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES + 2, addr)375 376#define register_ompt_callback_t(name, type)                                   \377  do {                                                                         \378    type f_##name = &on_##name;                                                \379    if (ompt_set_callback(name, (ompt_callback_t)f_##name) == ompt_set_never)  \380      printf("0: Could not register callback '" #name "'\n");                  \381  } while (0)382 383#define register_ompt_callback(name) register_ompt_callback_t(name, name##_t)384 385#ifndef USE_PRIVATE_TOOL386static void on_ompt_callback_mutex_acquire(ompt_mutex_t kind, unsigned int hint,387                                           unsigned int impl,388                                           ompt_wait_id_t wait_id,389                                           const void *codeptr_ra) {390  switch (kind) {391  case ompt_mutex_lock:392    printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_wait_lock: wait_id=%" PRIu64393           ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n",394           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);395    break;396  case ompt_mutex_test_lock:397    printf("%" PRIu64 ":" _TOOL_PREFIX398           " ompt_event_wait_test_lock: wait_id=%" PRIu64 ", hint=%" PRIu32399           ", impl=%" PRIu32 ", codeptr_ra=%p \n",400           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);401    break;402  case ompt_mutex_nest_lock:403    printf("%" PRIu64 ":" _TOOL_PREFIX404           " ompt_event_wait_nest_lock: wait_id=%" PRIu64 ", hint=%" PRIu32405           ", impl=%" PRIu32 ", codeptr_ra=%p \n",406           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);407    break;408  case ompt_mutex_test_nest_lock:409    printf("%" PRIu64 ":" _TOOL_PREFIX410           " ompt_event_wait_test_nest_lock: wait_id=%" PRIu64 ", hint=%" PRIu32411           ", impl=%" PRIu32 ", codeptr_ra=%p \n",412           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);413    break;414  case ompt_mutex_critical:415    printf("%" PRIu64 ":" _TOOL_PREFIX416           " ompt_event_wait_critical: wait_id=%" PRIu64 ", hint=%" PRIu32417           ", impl=%" PRIu32 ", codeptr_ra=%p \n",418           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);419    break;420  case ompt_mutex_atomic:421    printf("%" PRIu64 ":" _TOOL_PREFIX422           " ompt_event_wait_atomic: wait_id=%" PRIu64 ", hint=%" PRIu32423           ", impl=%" PRIu32 ", codeptr_ra=%p \n",424           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);425    break;426  case ompt_mutex_ordered:427    printf("%" PRIu64 ":" _TOOL_PREFIX428           " ompt_event_wait_ordered: wait_id=%" PRIu64 ", hint=%" PRIu32429           ", impl=%" PRIu32 ", codeptr_ra=%p \n",430           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);431    break;432  default:433    break;434  }435}436 437static void on_ompt_callback_mutex_acquired(ompt_mutex_t kind,438                                            ompt_wait_id_t wait_id,439                                            const void *codeptr_ra) {440  switch (kind) {441  case ompt_mutex_lock:442    printf("%" PRIu64 ":" _TOOL_PREFIX443           " ompt_event_acquired_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n",444           ompt_get_thread_data()->value, wait_id, codeptr_ra);445    break;446  case ompt_mutex_test_lock:447    printf("%" PRIu64 ":" _TOOL_PREFIX448           " ompt_event_acquired_test_lock: wait_id=%" PRIu64449           ", codeptr_ra=%p \n",450           ompt_get_thread_data()->value, wait_id, codeptr_ra);451    break;452  case ompt_mutex_nest_lock:453    printf("%" PRIu64 ":" _TOOL_PREFIX454           " ompt_event_acquired_nest_lock_first: wait_id=%" PRIu64455           ", codeptr_ra=%p \n",456           ompt_get_thread_data()->value, wait_id, codeptr_ra);457    break;458  case ompt_mutex_test_nest_lock:459    printf("%" PRIu64 ":" _TOOL_PREFIX460           " ompt_event_acquired_test_nest_lock_first: wait_id=%" PRIu64461           ", codeptr_ra=%p \n",462           ompt_get_thread_data()->value, wait_id, codeptr_ra);463    break;464  case ompt_mutex_critical:465    printf("%" PRIu64 ":" _TOOL_PREFIX466           " ompt_event_acquired_critical: wait_id=%" PRIu64467           ", codeptr_ra=%p \n",468           ompt_get_thread_data()->value, wait_id, codeptr_ra);469    break;470  case ompt_mutex_atomic:471    printf("%" PRIu64 ":" _TOOL_PREFIX472           " ompt_event_acquired_atomic: wait_id=%" PRIu64 ", codeptr_ra=%p \n",473           ompt_get_thread_data()->value, wait_id, codeptr_ra);474    break;475  case ompt_mutex_ordered:476    printf("%" PRIu64 ":" _TOOL_PREFIX477           " ompt_event_acquired_ordered: wait_id=%" PRIu64478           ", codeptr_ra=%p \n",479           ompt_get_thread_data()->value, wait_id, codeptr_ra);480    break;481  default:482    break;483  }484}485 486static void on_ompt_callback_mutex_released(ompt_mutex_t kind,487                                            ompt_wait_id_t wait_id,488                                            const void *codeptr_ra) {489  switch (kind) {490  case ompt_mutex_lock:491    printf("%" PRIu64 ":" _TOOL_PREFIX492           " ompt_event_release_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n",493           ompt_get_thread_data()->value, wait_id, codeptr_ra);494    break;495  case ompt_mutex_nest_lock:496    printf("%" PRIu64 ":" _TOOL_PREFIX497           " ompt_event_release_nest_lock_last: wait_id=%" PRIu64498           ", codeptr_ra=%p \n",499           ompt_get_thread_data()->value, wait_id, codeptr_ra);500    break;501  case ompt_mutex_critical:502    printf("%" PRIu64 ":" _TOOL_PREFIX503           " ompt_event_release_critical: wait_id=%" PRIu64504           ", codeptr_ra=%p \n",505           ompt_get_thread_data()->value, wait_id, codeptr_ra);506    break;507  case ompt_mutex_atomic:508    printf("%" PRIu64 ":" _TOOL_PREFIX509           " ompt_event_release_atomic: wait_id=%" PRIu64 ", codeptr_ra=%p \n",510           ompt_get_thread_data()->value, wait_id, codeptr_ra);511    break;512  case ompt_mutex_ordered:513    printf("%" PRIu64 ":" _TOOL_PREFIX514           " ompt_event_release_ordered: wait_id=%" PRIu64 ", codeptr_ra=%p \n",515           ompt_get_thread_data()->value, wait_id, codeptr_ra);516    break;517  default:518    break;519  }520}521 522static void on_ompt_callback_nest_lock(ompt_scope_endpoint_t endpoint,523                                       ompt_wait_id_t wait_id,524                                       const void *codeptr_ra) {525  switch (endpoint) {526  case ompt_scope_begin:527    printf("%" PRIu64 ":" _TOOL_PREFIX528           " ompt_event_acquired_nest_lock_next: wait_id=%" PRIu64529           ", codeptr_ra=%p \n",530           ompt_get_thread_data()->value, wait_id, codeptr_ra);531    break;532  case ompt_scope_end:533    printf("%" PRIu64 ":" _TOOL_PREFIX534           " ompt_event_release_nest_lock_prev: wait_id=%" PRIu64535           ", codeptr_ra=%p \n",536           ompt_get_thread_data()->value, wait_id, codeptr_ra);537    break;538  case ompt_scope_beginend:539    printf("ompt_scope_beginend should never be passed to %s\n", __func__);540    exit(-1);541  }542}543 544static void on_ompt_callback_sync_region(ompt_sync_region_t kind,545                                         ompt_scope_endpoint_t endpoint,546                                         ompt_data_t *parallel_data,547                                         ompt_data_t *task_data,548                                         const void *codeptr_ra) {549  if (endpoint == ompt_scope_beginend) {550    printf("ompt_scope_beginend should never be passed to %s\n", __func__);551    exit(-1);552  }553  if (kind == ompt_sync_region_reduction) {554    printf("ompt_sync_region_reduction should never be passed to %s\n",555           __func__);556    exit(-1);557  }558  uint64_t parallel_data_value = parallel_data ? parallel_data->value : 0;559  const char *begin_or_end = (endpoint == ompt_scope_begin) ? "begin" : "end";560  printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_%s_%s: parallel_id=%" PRIx64561         ", task_id=%" PRIx64 ", codeptr_ra=%p\n",562         ompt_get_thread_data()->value, ompt_sync_region_t_values[kind],563         begin_or_end, parallel_data_value, task_data->value, codeptr_ra);564  switch (kind) {565  case ompt_sync_region_barrier:566  case ompt_sync_region_barrier_implicit:567  case ompt_sync_region_barrier_implicit_workshare:568  case ompt_sync_region_barrier_implicit_parallel:569  case ompt_sync_region_barrier_teams:570  case ompt_sync_region_barrier_explicit:571  case ompt_sync_region_barrier_implementation:572    if (endpoint == ompt_scope_begin)573      print_ids(0);574  default:;575  }576}577 578static void on_ompt_callback_sync_region_wait(ompt_sync_region_t kind,579                                              ompt_scope_endpoint_t endpoint,580                                              ompt_data_t *parallel_data,581                                              ompt_data_t *task_data,582                                              const void *codeptr_ra) {583  if (endpoint == ompt_scope_beginend) {584    printf("ompt_scope_beginend should never be passed to %s\n", __func__);585    exit(-1);586  }587  if (kind == ompt_sync_region_reduction) {588    printf("ompt_sync_region_reduction should never be passed to %s\n",589           __func__);590    exit(-1);591  }592  uint64_t parallel_data_value = parallel_data ? parallel_data->value : 0;593  const char *begin_or_end = (endpoint == ompt_scope_begin) ? "begin" : "end";594  printf("%" PRIu64 ":" _TOOL_PREFIX595         " ompt_event_wait_%s_%s: parallel_id=%" PRIx64 ", task_id=%" PRIx64596         ", codeptr_ra=%p\n",597         ompt_get_thread_data()->value, ompt_sync_region_t_values[kind],598         begin_or_end, parallel_data_value, task_data->value, codeptr_ra);599}600 601static void on_ompt_callback_reduction(ompt_sync_region_t kind,602                                       ompt_scope_endpoint_t endpoint,603                                       ompt_data_t *parallel_data,604                                       ompt_data_t *task_data,605                                       const void *codeptr_ra) {606  switch (endpoint) {607  case ompt_scope_begin:608    printf("%" PRIu64 ":" _TOOL_PREFIX609           " ompt_event_reduction_begin: parallel_id=%" PRIx64610           ", task_id=%" PRIx64 ", codeptr_ra=%p\n",611           ompt_get_thread_data()->value,612           (parallel_data) ? parallel_data->value : 0, task_data->value,613           codeptr_ra);614    break;615  case ompt_scope_end:616    printf("%" PRIu64 ":" _TOOL_PREFIX617           " ompt_event_reduction_end: parallel_id=%" PRIx64618           ", task_id=%" PRIx64 ", codeptr_ra=%p\n",619           ompt_get_thread_data()->value,620           (parallel_data) ? parallel_data->value : 0, task_data->value,621           codeptr_ra);622    break;623  case ompt_scope_beginend:624    printf("ompt_scope_beginend should never be passed to %s\n", __func__);625    exit(-1);626  }627}628 629static void on_ompt_callback_flush(ompt_data_t *thread_data,630                                   const void *codeptr_ra) {631  printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_flush: codeptr_ra=%p\n",632         thread_data->value, codeptr_ra);633}634 635static void on_ompt_callback_cancel(ompt_data_t *task_data, int flags,636                                    const void *codeptr_ra) {637  const char *first_flag_value;638  const char *second_flag_value;639  if (flags & ompt_cancel_parallel)640    first_flag_value = ompt_cancel_flag_t_values[0];641  else if (flags & ompt_cancel_sections)642    first_flag_value = ompt_cancel_flag_t_values[1];643  else if (flags & ompt_cancel_loop)644    first_flag_value = ompt_cancel_flag_t_values[2];645  else if (flags & ompt_cancel_taskgroup)646    first_flag_value = ompt_cancel_flag_t_values[3];647 648  if (flags & ompt_cancel_activated)649    second_flag_value = ompt_cancel_flag_t_values[4];650  else if (flags & ompt_cancel_detected)651    second_flag_value = ompt_cancel_flag_t_values[5];652  else if (flags & ompt_cancel_discarded_task)653    second_flag_value = ompt_cancel_flag_t_values[6];654 655  printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_cancel: task_id=%" PRIx64656         ", flags=%s|%s=%" PRIu32 ", codeptr_ra=%p\n",657         ompt_get_thread_data()->value, task_data->value, first_flag_value,658         second_flag_value, flags, codeptr_ra);659}660 661static void on_ompt_callback_implicit_task(ompt_scope_endpoint_t endpoint,662                                           ompt_data_t *parallel_data,663                                           ompt_data_t *task_data,664                                           unsigned int team_size,665                                           unsigned int thread_num, int flags) {666  switch (endpoint) {667  case ompt_scope_begin:668    if (task_data->ptr)669      printf("%s\n", "0: task_data initially not null");670    task_data->value = ompt_get_unique_id();671 672    // there is no parallel_begin callback for implicit parallel region673    // thus it is initialized in initial task674    if (flags & ompt_task_initial) {675      char buffer[2048];676 677      format_task_type(flags, buffer);678      // Only check initial task not created by teams construct679      if (team_size == 1 && thread_num == 1 && parallel_data->ptr)680        printf("%s\n", "0: parallel_data initially not null");681      parallel_data->value = ompt_get_unique_id();682      printf("%" PRIu64 ":" _TOOL_PREFIX683             " ompt_event_initial_task_begin: parallel_id=%" PRIx64684             ", task_id=%" PRIx64 ", actual_parallelism=%" PRIu32685             ", index=%" PRIu32 ", flags=%" PRIu32 "\n",686             ompt_get_thread_data()->value, parallel_data->value,687             task_data->value, team_size, thread_num, flags);688    } else {689      printf("%" PRIu64 ":" _TOOL_PREFIX690             " ompt_event_implicit_task_begin: parallel_id=%" PRIx64691             ", task_id=%" PRIx64 ", team_size=%" PRIu32 ", thread_num=%" PRIu32692             "\n",693             ompt_get_thread_data()->value, parallel_data->value,694             task_data->value, team_size, thread_num);695    }696 697    break;698  case ompt_scope_end:699    if (flags & ompt_task_initial) {700      printf("%" PRIu64 ":" _TOOL_PREFIX701             " ompt_event_initial_task_end: parallel_id=%" PRIx64702             ", task_id=%" PRIx64 ", actual_parallelism=%" PRIu32703             ", index=%" PRIu32 "\n",704             ompt_get_thread_data()->value,705             (parallel_data) ? parallel_data->value : 0, task_data->value,706             team_size, thread_num);707    } else {708      printf("%" PRIu64 ":" _TOOL_PREFIX709             " ompt_event_implicit_task_end: parallel_id=%" PRIx64710             ", task_id=%" PRIx64 ", team_size=%" PRIu32 ", thread_num=%" PRIu32711             "\n",712             ompt_get_thread_data()->value,713             (parallel_data) ? parallel_data->value : 0, task_data->value,714             team_size, thread_num);715    }716    break;717  case ompt_scope_beginend:718    printf("ompt_scope_beginend should never be passed to %s\n", __func__);719    exit(-1);720  }721}722 723static void on_ompt_callback_lock_init(ompt_mutex_t kind, unsigned int hint,724                                       unsigned int impl,725                                       ompt_wait_id_t wait_id,726                                       const void *codeptr_ra) {727  switch (kind) {728  case ompt_mutex_lock:729    printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_init_lock: wait_id=%" PRIu64730           ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n",731           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);732    break;733  case ompt_mutex_nest_lock:734    printf("%" PRIu64 ":" _TOOL_PREFIX735           " ompt_event_init_nest_lock: wait_id=%" PRIu64 ", hint=%" PRIu32736           ", impl=%" PRIu32 ", codeptr_ra=%p \n",737           ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra);738    break;739  default:740    break;741  }742}743 744static void on_ompt_callback_lock_destroy(ompt_mutex_t kind,745                                          ompt_wait_id_t wait_id,746                                          const void *codeptr_ra) {747  switch (kind) {748  case ompt_mutex_lock:749    printf("%" PRIu64 ":" _TOOL_PREFIX750           " ompt_event_destroy_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n",751           ompt_get_thread_data()->value, wait_id, codeptr_ra);752    break;753  case ompt_mutex_nest_lock:754    printf("%" PRIu64 ":" _TOOL_PREFIX755           " ompt_event_destroy_nest_lock: wait_id=%" PRIu64756           ", codeptr_ra=%p \n",757           ompt_get_thread_data()->value, wait_id, codeptr_ra);758    break;759  default:760    break;761  }762}763 764static void on_ompt_callback_work(ompt_work_t wstype,765                                  ompt_scope_endpoint_t endpoint,766                                  ompt_data_t *parallel_data,767                                  ompt_data_t *task_data, uint64_t count,768                                  const void *codeptr_ra) {769  switch (endpoint) {770  case ompt_scope_begin:771    printf("%" PRIu64 ":" _TOOL_PREFIX " %s_begin: parallel_id=%" PRIx64772           ", task_id=%" PRIx64 ", codeptr_ra=%p, count=%" PRIu64 "\n",773           ompt_get_thread_data()->value, ompt_work_events_t_values[wstype],774           parallel_data->value, task_data->value, codeptr_ra, count);775    break;776  case ompt_scope_end:777    printf("%" PRIu64 ":" _TOOL_PREFIX " %s_end: parallel_id=%" PRIx64778           ", task_id=%" PRIx64 ", codeptr_ra=%p, count=%" PRIu64 "\n",779           ompt_get_thread_data()->value, ompt_work_events_t_values[wstype],780           parallel_data->value, task_data->value, codeptr_ra, count);781    break;782  case ompt_scope_beginend:783    printf("ompt_scope_beginend should never be passed to %s\n", __func__);784    exit(-1);785  }786}787 788static void on_ompt_callback_dispatch(ompt_data_t *parallel_data,789                                      ompt_data_t *task_data,790                                      ompt_dispatch_t kind,791                                      ompt_data_t instance) {792  char *event_name = NULL;793  void *codeptr_ra = NULL;794  ompt_dispatch_chunk_t *dispatch_chunk = NULL;795  switch (kind) {796  case ompt_dispatch_section:797    event_name = "ompt_event_section_begin";798    codeptr_ra = instance.ptr;799    break;800  case ompt_dispatch_ws_loop_chunk:801    event_name = "ompt_event_ws_loop_chunk_begin";802    dispatch_chunk = (ompt_dispatch_chunk_t *)instance.ptr;803    break;804  case ompt_dispatch_taskloop_chunk:805    event_name = "ompt_event_taskloop_chunk_begin";806    dispatch_chunk = (ompt_dispatch_chunk_t *)instance.ptr;807    break;808  case ompt_dispatch_distribute_chunk:809    event_name = "ompt_event_distribute_chunk_begin";810    dispatch_chunk = (ompt_dispatch_chunk_t *)instance.ptr;811    break;812  default:813    event_name = "ompt_ws_loop_iteration_begin";814  }815  printf("%" PRIu64 ":" _TOOL_PREFIX " %s: parallel_id=%" PRIx64816         ", task_id=%" PRIx64 ", codeptr_ra=%p, chunk_start=%" PRIu64817         ", chunk_iterations=%" PRIu64 "\n",818         ompt_get_thread_data()->value, event_name, parallel_data->value,819         task_data->value, codeptr_ra,820         dispatch_chunk ? dispatch_chunk->start : 0,821         dispatch_chunk ? dispatch_chunk->iterations : 0);822}823 824static void on_ompt_callback_masked(ompt_scope_endpoint_t endpoint,825                                    ompt_data_t *parallel_data,826                                    ompt_data_t *task_data,827                                    const void *codeptr_ra) {828  switch (endpoint) {829  case ompt_scope_begin:830    printf("%" PRIu64 ":" _TOOL_PREFIX831           " ompt_event_masked_begin: parallel_id=%" PRIx64 ", task_id=%" PRIx64832           ", codeptr_ra=%p\n",833           ompt_get_thread_data()->value, parallel_data->value,834           task_data->value, codeptr_ra);835    break;836  case ompt_scope_end:837    printf("%" PRIu64 ":" _TOOL_PREFIX838           " ompt_event_masked_end: parallel_id=%" PRIx64 ", task_id=%" PRIx64839           ", codeptr_ra=%p\n",840           ompt_get_thread_data()->value, parallel_data->value,841           task_data->value, codeptr_ra);842    break;843  case ompt_scope_beginend:844    printf("ompt_scope_beginend should never be passed to %s\n", __func__);845    exit(-1);846  }847}848 849static void on_ompt_callback_parallel_begin(850    ompt_data_t *encountering_task_data,851    const ompt_frame_t *encountering_task_frame, ompt_data_t *parallel_data,852    uint32_t requested_team_size, int flag, const void *codeptr_ra) {853  if (parallel_data->ptr)854    printf("0: parallel_data initially not null\n");855  parallel_data->value = ompt_get_unique_id();856  int invoker = flag & 0xF;857  const char *event = (flag & ompt_parallel_team) ? "parallel" : "teams";858  const char *size = (flag & ompt_parallel_team) ? "team_size" : "num_teams";859  printf("%" PRIu64 ":" _TOOL_PREFIX860         " ompt_event_%s_begin: parent_task_id=%" PRIx64861         ", parent_task_frame.exit=%p, parent_task_frame.reenter=%p, "862         "parallel_id=%" PRIx64 ", requested_%s=%" PRIu32863         ", codeptr_ra=%p, invoker=%d\n",864         ompt_get_thread_data()->value, event, encountering_task_data->value,865         encountering_task_frame->exit_frame.ptr,866         encountering_task_frame->enter_frame.ptr, parallel_data->value, size,867         requested_team_size, codeptr_ra, invoker);868}869 870static void on_ompt_callback_parallel_end(ompt_data_t *parallel_data,871                                          ompt_data_t *encountering_task_data,872                                          int flag, const void *codeptr_ra) {873  int invoker = flag & 0xF;874  const char *event = (flag & ompt_parallel_team) ? "parallel" : "teams";875  printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_%s_end: parallel_id=%" PRIx64876         ", task_id=%" PRIx64 ", invoker=%d, codeptr_ra=%p\n",877         ompt_get_thread_data()->value, event, parallel_data->value,878         encountering_task_data->value, invoker, codeptr_ra);879}880 881static void882on_ompt_callback_task_create(ompt_data_t *encountering_task_data,883                             const ompt_frame_t *encountering_task_frame,884                             ompt_data_t *new_task_data, int type,885                             int has_dependences, const void *codeptr_ra) {886  if (new_task_data->ptr)887    printf("0: new_task_data initially not null\n");888  new_task_data->value = ompt_get_unique_id();889  char buffer[2048];890 891  format_task_type(type, buffer);892 893  printf(894      "%" PRIu64 ":" _TOOL_PREFIX895      " ompt_event_task_create: parent_task_id=%" PRIx64896      ", parent_task_frame.exit=%p, parent_task_frame.reenter=%p, "897      "new_task_id=%" PRIx64898      ", codeptr_ra=%p, task_type=%s=%d, has_dependences=%s\n",899      ompt_get_thread_data()->value,900      encountering_task_data ? encountering_task_data->value : 0,901      encountering_task_frame ? encountering_task_frame->exit_frame.ptr : NULL,902      encountering_task_frame ? encountering_task_frame->enter_frame.ptr : NULL,903      new_task_data->value, codeptr_ra, buffer, type,904      has_dependences ? "yes" : "no");905}906 907static void on_ompt_callback_task_schedule(ompt_data_t *first_task_data,908                                           ompt_task_status_t prior_task_status,909                                           ompt_data_t *second_task_data) {910  printf("%" PRIu64 ":" _TOOL_PREFIX911         " ompt_event_task_schedule: first_task_id=%" PRIx64912         ", second_task_id=%" PRIx64 ", prior_task_status=%s=%d\n",913         ompt_get_thread_data()->value, first_task_data->value,914         (second_task_data ? second_task_data->value : -1),915         ompt_task_status_t_values[prior_task_status], prior_task_status);916  if (prior_task_status == ompt_task_complete ||917      prior_task_status == ompt_task_late_fulfill ||918      prior_task_status == ompt_taskwait_complete) {919    printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_task_end: task_id=%" PRIx64920           "\n",921           ompt_get_thread_data()->value, first_task_data->value);922  }923}924 925static void on_ompt_callback_dependences(ompt_data_t *task_data,926                                         const ompt_dependence_t *deps,927                                         int ndeps) {928  char buffer[2048];929  char *progress = buffer;930  int i;931  for (i = 0; i < ndeps && progress < buffer + 2000; i++) {932    if (deps[i].dependence_type == ompt_dependence_type_source ||933        deps[i].dependence_type == ompt_dependence_type_sink)934      progress +=935          sprintf(progress, "(%" PRIu64 ", %s), ", deps[i].variable.value,936                  ompt_dependence_type_t_values[deps[i].dependence_type]);937    else938      progress +=939          sprintf(progress, "(%p, %s), ", deps[i].variable.ptr,940                  ompt_dependence_type_t_values[deps[i].dependence_type]);941  }942  if (ndeps > 0)943    progress[-2] = 0;944  printf("%" PRIu64 ":" _TOOL_PREFIX " ompt_event_dependences: task_id=%" PRIx64945         ", deps=[%s], ndeps=%d\n",946         ompt_get_thread_data()->value, task_data->value, buffer, ndeps);947}948 949static void on_ompt_callback_task_dependence(ompt_data_t *first_task_data,950                                             ompt_data_t *second_task_data) {951  printf("%" PRIu64 ":" _TOOL_PREFIX952         " ompt_event_task_dependence_pair: first_task_id=%" PRIx64953         ", second_task_id=%" PRIx64 "\n",954         ompt_get_thread_data()->value, first_task_data->value,955         second_task_data->value);956}957 958static void on_ompt_callback_thread_begin(ompt_thread_t thread_type,959                                          ompt_data_t *thread_data) {960  if (thread_data->ptr)961    printf("%s\n", "0: thread_data initially not null");962  thread_data->value = ompt_get_unique_id();963  printf("%" PRIu64 ":" _TOOL_PREFIX964         " ompt_event_thread_begin: thread_type=%s=%d, thread_id=%" PRIu64 "\n",965         ompt_get_thread_data()->value, ompt_thread_t_values[thread_type],966         thread_type, thread_data->value);967}968 969static void on_ompt_callback_thread_end(ompt_data_t *thread_data) {970  printf("%" PRIu64 ":" _TOOL_PREFIX971         " ompt_event_thread_end: thread_id=%" PRIu64 "\n",972         ompt_get_thread_data()->value, thread_data->value);973}974 975static int on_ompt_callback_control_tool(uint64_t command, uint64_t modifier,976                                         void *arg, const void *codeptr_ra) {977  ompt_frame_t *omptTaskFrame;978  ompt_get_task_info(0, NULL, (ompt_data_t **)NULL, &omptTaskFrame, NULL, NULL);979  printf("%" PRIu64 ":" _TOOL_PREFIX980         " ompt_event_control_tool: command=%" PRIu64 ", modifier=%" PRIu64981         ", arg=%p, codeptr_ra=%p, current_task_frame.exit=%p, "982         "current_task_frame.reenter=%p \n",983         ompt_get_thread_data()->value, command, modifier, arg, codeptr_ra,984         omptTaskFrame->exit_frame.ptr, omptTaskFrame->enter_frame.ptr);985 986  // the following would interfere with expected output for OMPT tests, so skip987#ifndef _OMPT_TESTS988  // print task data989  int task_level = 0;990  ompt_data_t *task_data;991  while (ompt_get_task_info(task_level, NULL, (ompt_data_t **)&task_data, NULL,992                            NULL, NULL)) {993    printf("%" PRIu64 ":" _TOOL_PREFIX " task level %d: task_id=%" PRIx64 "\n",994           ompt_get_thread_data()->value, task_level, task_data->value);995    task_level++;996  }997 998  // print parallel data999  int parallel_level = 0;1000  ompt_data_t *parallel_data;1001  while (ompt_get_parallel_info(parallel_level, (ompt_data_t **)&parallel_data,1002                                NULL)) {1003    printf("%" PRIu64 ":" _TOOL_PREFIX1004           " parallel level %d: parallel_id=%" PRIx64 "\n",1005           ompt_get_thread_data()->value, parallel_level, parallel_data->value);1006    parallel_level++;1007  }1008#endif1009  return 0; // success1010}1011 1012static void on_ompt_callback_error(ompt_severity_t severity,1013                                   const char *message, size_t length,1014                                   const void *codeptr_ra) {1015  printf("%" PRIu64 ": ompt_event_runtime_error: severity=%" PRIu321016         ", message=%s, length=%" PRIu64 ", codeptr_ra=%p\n",1017         ompt_get_thread_data()->value, severity, message, (uint64_t)length,1018         codeptr_ra);1019}1020 1021int ompt_initialize(ompt_function_lookup_t lookup, int initial_device_num,1022                    ompt_data_t *tool_data) {1023  ompt_set_callback = (ompt_set_callback_t)lookup("ompt_set_callback");1024  ompt_get_callback = (ompt_get_callback_t)lookup("ompt_get_callback");1025  ompt_get_state = (ompt_get_state_t)lookup("ompt_get_state");1026  ompt_get_task_info = (ompt_get_task_info_t)lookup("ompt_get_task_info");1027  ompt_get_task_memory = (ompt_get_task_memory_t)lookup("ompt_get_task_memory");1028  ompt_get_thread_data = (ompt_get_thread_data_t)lookup("ompt_get_thread_data");1029  ompt_get_parallel_info =1030      (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info");1031  ompt_get_unique_id = (ompt_get_unique_id_t)lookup("ompt_get_unique_id");1032  ompt_finalize_tool = (ompt_finalize_tool_t)lookup("ompt_finalize_tool");1033 1034  ompt_get_unique_id();1035 1036  ompt_get_num_procs = (ompt_get_num_procs_t)lookup("ompt_get_num_procs");1037  ompt_get_num_places = (ompt_get_num_places_t)lookup("ompt_get_num_places");1038  ompt_get_place_proc_ids =1039      (ompt_get_place_proc_ids_t)lookup("ompt_get_place_proc_ids");1040  ompt_get_place_num = (ompt_get_place_num_t)lookup("ompt_get_place_num");1041  ompt_get_partition_place_nums =1042      (ompt_get_partition_place_nums_t)lookup("ompt_get_partition_place_nums");1043  ompt_get_proc_id = (ompt_get_proc_id_t)lookup("ompt_get_proc_id");1044  ompt_enumerate_states =1045      (ompt_enumerate_states_t)lookup("ompt_enumerate_states");1046  ompt_enumerate_mutex_impls =1047      (ompt_enumerate_mutex_impls_t)lookup("ompt_enumerate_mutex_impls");1048 1049  register_ompt_callback(ompt_callback_mutex_acquire);1050  register_ompt_callback_t(ompt_callback_mutex_acquired, ompt_callback_mutex_t);1051  register_ompt_callback_t(ompt_callback_mutex_released, ompt_callback_mutex_t);1052  register_ompt_callback(ompt_callback_nest_lock);1053  register_ompt_callback(ompt_callback_sync_region);1054  register_ompt_callback_t(ompt_callback_sync_region_wait,1055                           ompt_callback_sync_region_t);1056  register_ompt_callback_t(ompt_callback_reduction,1057                           ompt_callback_sync_region_t);1058  register_ompt_callback(ompt_callback_control_tool);1059  register_ompt_callback(ompt_callback_flush);1060  register_ompt_callback(ompt_callback_cancel);1061  register_ompt_callback(ompt_callback_implicit_task);1062  register_ompt_callback_t(ompt_callback_lock_init,1063                           ompt_callback_mutex_acquire_t);1064  register_ompt_callback_t(ompt_callback_lock_destroy, ompt_callback_mutex_t);1065  register_ompt_callback(ompt_callback_work);1066  register_ompt_callback(ompt_callback_dispatch);1067  register_ompt_callback(ompt_callback_masked);1068  register_ompt_callback(ompt_callback_parallel_begin);1069  register_ompt_callback(ompt_callback_parallel_end);1070  register_ompt_callback(ompt_callback_task_create);1071  register_ompt_callback(ompt_callback_task_schedule);1072  register_ompt_callback(ompt_callback_dependences);1073  register_ompt_callback(ompt_callback_task_dependence);1074  register_ompt_callback(ompt_callback_thread_begin);1075  register_ompt_callback(ompt_callback_thread_end);1076  register_ompt_callback(ompt_callback_error);1077  printf("0: NULL_POINTER=%p\n", (void *)NULL);1078  return 1; // success1079}1080 1081void ompt_finalize(ompt_data_t *tool_data) {1082  printf("0: ompt_event_runtime_shutdown\n");1083}1084 1085#ifdef __cplusplus1086extern "C" {1087#endif1088ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,1089                                          const char *runtime_version) {1090  static ompt_start_tool_result_t ompt_start_tool_result = {&ompt_initialize,1091                                                            &ompt_finalize, 0};1092  return &ompt_start_tool_result;1093}1094#ifdef __cplusplus1095}1096#endif1097#endif // ifndef USE_PRIVATE_TOOL1098#ifdef _OMPT_TESTS1099#undef _OMPT_TESTS1100#endif1101