1 /* 2 * ompt-general.cpp -- OMPT implementation of interface functions 3 */ 4 5 //===----------------------------------------------------------------------===// 6 // 7 // The LLVM Compiler Infrastructure 8 // 9 // This file is dual licensed under the MIT and the University of Illinois Open 10 // Source Licenses. See LICENSE.txt for details. 11 // 12 //===----------------------------------------------------------------------===// 13 14 /***************************************************************************** 15 * system include files 16 ****************************************************************************/ 17 18 #include <assert.h> 19 20 #include <stdint.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #if KMP_OS_UNIX 25 #include <dlfcn.h> 26 #endif 27 28 /***************************************************************************** 29 * ompt include files 30 ****************************************************************************/ 31 32 #include "ompt-specific.cpp" 33 34 /***************************************************************************** 35 * macros 36 ****************************************************************************/ 37 38 #define ompt_get_callback_success 1 39 #define ompt_get_callback_failure 0 40 41 #define no_tool_present 0 42 43 #define OMPT_API_ROUTINE static 44 45 #ifndef OMPT_STR_MATCH 46 #define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle)) 47 #endif 48 49 /***************************************************************************** 50 * types 51 ****************************************************************************/ 52 53 typedef struct { 54 const char *state_name; 55 ompt_state_t state_id; 56 } ompt_state_info_t; 57 58 typedef struct { 59 const char *name; 60 kmp_mutex_impl_t id; 61 } kmp_mutex_impl_info_t; 62 63 enum tool_setting_e { 64 omp_tool_error, 65 omp_tool_unset, 66 omp_tool_disabled, 67 omp_tool_enabled 68 }; 69 70 /***************************************************************************** 71 * global variables 72 ****************************************************************************/ 73 74 ompt_callbacks_active_t ompt_enabled; 75 76 ompt_state_info_t ompt_state_info[] = { 77 #define ompt_state_macro(state, code) {#state, state}, 78 FOREACH_OMPT_STATE(ompt_state_macro) 79 #undef ompt_state_macro 80 }; 81 82 kmp_mutex_impl_info_t kmp_mutex_impl_info[] = { 83 #define kmp_mutex_impl_macro(name, id) {#name, name}, 84 FOREACH_KMP_MUTEX_IMPL(kmp_mutex_impl_macro) 85 #undef kmp_mutex_impl_macro 86 }; 87 88 ompt_callbacks_internal_t ompt_callbacks; 89 90 static ompt_start_tool_result_t *ompt_start_tool_result = NULL; 91 92 /***************************************************************************** 93 * forward declarations 94 ****************************************************************************/ 95 96 static ompt_interface_fn_t ompt_fn_lookup(const char *s); 97 98 OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void); 99 100 /***************************************************************************** 101 * initialization and finalization (private operations) 102 ****************************************************************************/ 103 104 typedef ompt_start_tool_result_t *(*ompt_start_tool_t)(unsigned int, 105 const char *); 106 107 #if KMP_OS_DARWIN 108 109 // While Darwin supports weak symbols, the library that wishes to provide a new 110 // implementation has to link against this runtime which defeats the purpose 111 // of having tools that are agnostic of the underlying runtime implementation. 112 // 113 // Fortunately, the linker includes all symbols of an executable in the global 114 // symbol table by default so dlsym() even finds static implementations of 115 // ompt_start_tool. For this to work on Linux, -Wl,--export-dynamic needs to be 116 // passed when building the application which we don't want to rely on. 117 118 static ompt_start_tool_result_t *ompt_tool_darwin(unsigned int omp_version, 119 const char *runtime_version) { 120 ompt_start_tool_result_t *ret = NULL; 121 // Search symbol in the current address space. 122 ompt_start_tool_t start_tool = 123 (ompt_start_tool_t)dlsym(RTLD_DEFAULT, "ompt_start_tool"); 124 if (start_tool) { 125 ret = start_tool(omp_version, runtime_version); 126 } 127 return ret; 128 } 129 130 #elif OMPT_HAVE_WEAK_ATTRIBUTE 131 132 // On Unix-like systems that support weak symbols the following implementation 133 // of ompt_start_tool() will be used in case no tool-supplied implementation of 134 // this function is present in the address space of a process. 135 136 _OMP_EXTERN OMPT_WEAK_ATTRIBUTE ompt_start_tool_result_t * 137 ompt_start_tool(unsigned int omp_version, const char *runtime_version) { 138 ompt_start_tool_result_t *ret = NULL; 139 // Search next symbol in the current address space. This can happen if the 140 // runtime library is linked before the tool. Since glibc 2.2 strong symbols 141 // don't override weak symbols that have been found before unless the user 142 // sets the environment variable LD_DYNAMIC_WEAK. 143 ompt_start_tool_t next_tool = 144 (ompt_start_tool_t)dlsym(RTLD_NEXT, "ompt_start_tool"); 145 if (next_tool) { 146 ret = next_tool(omp_version, runtime_version); 147 } 148 return ret; 149 } 150 151 #elif OMPT_HAVE_PSAPI 152 153 // On Windows, the ompt_tool_windows function is used to find the 154 // ompt_start_tool symbol across all modules loaded by a process. If 155 // ompt_start_tool is found, ompt_start_tool's return value is used to 156 // initialize the tool. Otherwise, NULL is returned and OMPT won't be enabled. 157 158 #include <psapi.h> 159 #pragma comment(lib, "psapi.lib") 160 161 // The number of loaded modules to start enumeration with EnumProcessModules() 162 #define NUM_MODULES 128 163 164 static ompt_start_tool_result_t * 165 ompt_tool_windows(unsigned int omp_version, const char *runtime_version) { 166 int i; 167 DWORD needed, new_size; 168 HMODULE *modules; 169 HANDLE process = GetCurrentProcess(); 170 modules = (HMODULE *)malloc(NUM_MODULES * sizeof(HMODULE)); 171 ompt_start_tool_t ompt_tool_p = NULL; 172 173 #if OMPT_DEBUG 174 printf("ompt_tool_windows(): looking for ompt_start_tool\n"); 175 #endif 176 if (!EnumProcessModules(process, modules, NUM_MODULES * sizeof(HMODULE), 177 &needed)) { 178 // Regardless of the error reason use the stub initialization function 179 free(modules); 180 return NULL; 181 } 182 // Check if NUM_MODULES is enough to list all modules 183 new_size = needed / sizeof(HMODULE); 184 if (new_size > NUM_MODULES) { 185 #if OMPT_DEBUG 186 printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed); 187 #endif 188 modules = (HMODULE *)realloc(modules, needed); 189 // If resizing failed use the stub function. 190 if (!EnumProcessModules(process, modules, needed, &needed)) { 191 free(modules); 192 return NULL; 193 } 194 } 195 for (i = 0; i < new_size; ++i) { 196 (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_start_tool"); 197 if (ompt_tool_p) { 198 #if OMPT_DEBUG 199 TCHAR modName[MAX_PATH]; 200 if (GetModuleFileName(modules[i], modName, MAX_PATH)) 201 printf("ompt_tool_windows(): ompt_start_tool found in module %s\n", 202 modName); 203 #endif 204 free(modules); 205 return (*ompt_tool_p)(omp_version, runtime_version); 206 } 207 #if OMPT_DEBUG 208 else { 209 TCHAR modName[MAX_PATH]; 210 if (GetModuleFileName(modules[i], modName, MAX_PATH)) 211 printf("ompt_tool_windows(): ompt_start_tool not found in module %s\n", 212 modName); 213 } 214 #endif 215 } 216 free(modules); 217 return NULL; 218 } 219 #else 220 #error Activation of OMPT is not supported on this platform. 221 #endif 222 223 static ompt_start_tool_result_t * 224 ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) { 225 ompt_start_tool_result_t *ret = NULL; 226 ompt_start_tool_t start_tool = NULL; 227 #if KMP_OS_WINDOWS 228 // Cannot use colon to describe a list of absolute paths on Windows 229 const char *sep = ";"; 230 #else 231 const char *sep = ":"; 232 #endif 233 234 #if KMP_OS_DARWIN 235 // Try in the current address space 236 ret = ompt_tool_darwin(omp_version, runtime_version); 237 #elif OMPT_HAVE_WEAK_ATTRIBUTE 238 ret = ompt_start_tool(omp_version, runtime_version); 239 #elif OMPT_HAVE_PSAPI 240 ret = ompt_tool_windows(omp_version, runtime_version); 241 #else 242 #error Activation of OMPT is not supported on this platform. 243 #endif 244 if (ret) 245 return ret; 246 247 // Try tool-libraries-var ICV 248 const char *tool_libs = getenv("OMP_TOOL_LIBRARIES"); 249 if (tool_libs) { 250 char *libs = __kmp_str_format("%s", tool_libs); 251 char *buf; 252 char *fname = __kmp_str_token(libs, sep, &buf); 253 while (fname) { 254 #if KMP_OS_UNIX 255 void *h = dlopen(fname, RTLD_LAZY); 256 if (h) { 257 start_tool = (ompt_start_tool_t)dlsym(h, "ompt_start_tool"); 258 #elif KMP_OS_WINDOWS 259 HMODULE h = LoadLibrary(fname); 260 if (h) { 261 start_tool = (ompt_start_tool_t)GetProcAddress(h, "ompt_start_tool"); 262 #else 263 #error Activation of OMPT is not supported on this platform. 264 #endif 265 if (start_tool && (ret = (*start_tool)(omp_version, runtime_version))) 266 break; 267 } 268 fname = __kmp_str_token(NULL, sep, &buf); 269 } 270 __kmp_str_free(&libs); 271 } 272 return ret; 273 } 274 275 void ompt_pre_init() { 276 //-------------------------------------------------- 277 // Execute the pre-initialization logic only once. 278 //-------------------------------------------------- 279 static int ompt_pre_initialized = 0; 280 281 if (ompt_pre_initialized) 282 return; 283 284 ompt_pre_initialized = 1; 285 286 //-------------------------------------------------- 287 // Use a tool iff a tool is enabled and available. 288 //-------------------------------------------------- 289 const char *ompt_env_var = getenv("OMP_TOOL"); 290 tool_setting_e tool_setting = omp_tool_error; 291 292 if (!ompt_env_var || !strcmp(ompt_env_var, "")) 293 tool_setting = omp_tool_unset; 294 else if (OMPT_STR_MATCH(ompt_env_var, "disabled")) 295 tool_setting = omp_tool_disabled; 296 else if (OMPT_STR_MATCH(ompt_env_var, "enabled")) 297 tool_setting = omp_tool_enabled; 298 299 #if OMPT_DEBUG 300 printf("ompt_pre_init(): tool_setting = %d\n", tool_setting); 301 #endif 302 switch (tool_setting) { 303 case omp_tool_disabled: 304 break; 305 306 case omp_tool_unset: 307 case omp_tool_enabled: 308 309 //-------------------------------------------------- 310 // Load tool iff specified in environment variable 311 //-------------------------------------------------- 312 ompt_start_tool_result = 313 ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version()); 314 315 memset(&ompt_enabled, 0, sizeof(ompt_enabled)); 316 break; 317 318 case omp_tool_error: 319 fprintf(stderr, "Warning: OMP_TOOL has invalid value \"%s\".\n" 320 " legal values are (NULL,\"\",\"disabled\"," 321 "\"enabled\").\n", 322 ompt_env_var); 323 break; 324 } 325 #if OMPT_DEBUG 326 printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled); 327 #endif 328 } 329 330 extern "C" int omp_get_initial_device(void); 331 332 void ompt_post_init() { 333 //-------------------------------------------------- 334 // Execute the post-initialization logic only once. 335 //-------------------------------------------------- 336 static int ompt_post_initialized = 0; 337 338 if (ompt_post_initialized) 339 return; 340 341 ompt_post_initialized = 1; 342 343 //-------------------------------------------------- 344 // Initialize the tool if so indicated. 345 //-------------------------------------------------- 346 if (ompt_start_tool_result) { 347 ompt_enabled.enabled = !!ompt_start_tool_result->initialize( 348 ompt_fn_lookup, omp_get_initial_device(), &(ompt_start_tool_result->tool_data)); 349 350 if (!ompt_enabled.enabled) { 351 // tool not enabled, zero out the bitmap, and done 352 memset(&ompt_enabled, 0, sizeof(ompt_enabled)); 353 return; 354 } 355 356 kmp_info_t *root_thread = ompt_get_thread(); 357 358 ompt_set_thread_state(root_thread, ompt_state_overhead); 359 360 if (ompt_enabled.ompt_callback_thread_begin) { 361 ompt_callbacks.ompt_callback(ompt_callback_thread_begin)( 362 ompt_thread_initial, __ompt_get_thread_data_internal()); 363 } 364 ompt_data_t *task_data; 365 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL); 366 if (ompt_enabled.ompt_callback_task_create) { 367 ompt_callbacks.ompt_callback(ompt_callback_task_create)( 368 NULL, NULL, task_data, ompt_task_initial, 0, NULL); 369 } 370 371 ompt_set_thread_state(root_thread, ompt_state_work_serial); 372 } 373 } 374 375 void ompt_fini() { 376 if (ompt_enabled.enabled) { 377 ompt_start_tool_result->finalize(&(ompt_start_tool_result->tool_data)); 378 } 379 380 memset(&ompt_enabled, 0, sizeof(ompt_enabled)); 381 } 382 383 /***************************************************************************** 384 * interface operations 385 ****************************************************************************/ 386 387 /***************************************************************************** 388 * state 389 ****************************************************************************/ 390 391 OMPT_API_ROUTINE int ompt_enumerate_states(int current_state, int *next_state, 392 const char **next_state_name) { 393 const static int len = sizeof(ompt_state_info) / sizeof(ompt_state_info_t); 394 int i = 0; 395 396 for (i = 0; i < len - 1; i++) { 397 if (ompt_state_info[i].state_id == current_state) { 398 *next_state = ompt_state_info[i + 1].state_id; 399 *next_state_name = ompt_state_info[i + 1].state_name; 400 return 1; 401 } 402 } 403 404 return 0; 405 } 406 407 OMPT_API_ROUTINE int ompt_enumerate_mutex_impls(int current_impl, 408 int *next_impl, 409 const char **next_impl_name) { 410 const static int len = 411 sizeof(kmp_mutex_impl_info) / sizeof(kmp_mutex_impl_info_t); 412 int i = 0; 413 for (i = 0; i < len - 1; i++) { 414 if (kmp_mutex_impl_info[i].id != current_impl) 415 continue; 416 *next_impl = kmp_mutex_impl_info[i + 1].id; 417 *next_impl_name = kmp_mutex_impl_info[i + 1].name; 418 return 1; 419 } 420 return 0; 421 } 422 423 /***************************************************************************** 424 * callbacks 425 ****************************************************************************/ 426 427 OMPT_API_ROUTINE ompt_set_result_t ompt_set_callback(ompt_callbacks_t which, 428 ompt_callback_t callback) { 429 switch (which) { 430 431 #define ompt_event_macro(event_name, callback_type, event_id) \ 432 case event_name: \ 433 if (ompt_event_implementation_status(event_name)) { \ 434 ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \ 435 ompt_enabled.event_name = (callback != 0); \ 436 } \ 437 if (callback) \ 438 return ompt_event_implementation_status(event_name); \ 439 else \ 440 return ompt_set_always; 441 442 FOREACH_OMPT_EVENT(ompt_event_macro) 443 444 #undef ompt_event_macro 445 446 default: 447 return ompt_set_error; 448 } 449 } 450 451 OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which, 452 ompt_callback_t *callback) { 453 switch (which) { 454 455 #define ompt_event_macro(event_name, callback_type, event_id) \ 456 case event_name: \ 457 if (ompt_event_implementation_status(event_name)) { \ 458 ompt_callback_t mycb = \ 459 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \ 460 if (mycb) { \ 461 *callback = mycb; \ 462 return ompt_get_callback_success; \ 463 } \ 464 } \ 465 return ompt_get_callback_failure; 466 467 FOREACH_OMPT_EVENT(ompt_event_macro) 468 469 #undef ompt_event_macro 470 471 default: 472 return ompt_get_callback_failure; 473 } 474 } 475 476 /***************************************************************************** 477 * parallel regions 478 ****************************************************************************/ 479 480 OMPT_API_ROUTINE int ompt_get_parallel_info(int ancestor_level, 481 ompt_data_t **parallel_data, 482 int *team_size) { 483 return __ompt_get_parallel_info_internal(ancestor_level, parallel_data, 484 team_size); 485 } 486 487 OMPT_API_ROUTINE int ompt_get_state(ompt_wait_id_t *wait_id) { 488 int thread_state = __ompt_get_state_internal(wait_id); 489 490 if (thread_state == ompt_state_undefined) { 491 thread_state = ompt_state_work_serial; 492 } 493 494 return thread_state; 495 } 496 497 /***************************************************************************** 498 * tasks 499 ****************************************************************************/ 500 501 OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void) { 502 return __ompt_get_thread_data_internal(); 503 } 504 505 OMPT_API_ROUTINE int ompt_get_task_info(int ancestor_level, int *type, 506 ompt_data_t **task_data, 507 ompt_frame_t **task_frame, 508 ompt_data_t **parallel_data, 509 int *thread_num) { 510 return __ompt_get_task_info_internal(ancestor_level, type, task_data, 511 task_frame, parallel_data, thread_num); 512 } 513 514 OMPT_API_ROUTINE int ompt_get_task_memory(void **addr, size_t *size, 515 int block) { 516 // stub 517 return 0; 518 } 519 520 /***************************************************************************** 521 * num_procs 522 ****************************************************************************/ 523 524 OMPT_API_ROUTINE int ompt_get_num_procs(void) { 525 // copied from kmp_ftn_entry.h (but modified: OMPT can only be called when 526 // runtime is initialized) 527 return __kmp_avail_proc; 528 } 529 530 /***************************************************************************** 531 * places 532 ****************************************************************************/ 533 534 OMPT_API_ROUTINE int ompt_get_num_places(void) { 535 // copied from kmp_ftn_entry.h (but modified) 536 #if !KMP_AFFINITY_SUPPORTED 537 return 0; 538 #else 539 if (!KMP_AFFINITY_CAPABLE()) 540 return 0; 541 return __kmp_affinity_num_masks; 542 #endif 543 } 544 545 OMPT_API_ROUTINE int ompt_get_place_proc_ids(int place_num, int ids_size, 546 int *ids) { 547 // copied from kmp_ftn_entry.h (but modified) 548 #if !KMP_AFFINITY_SUPPORTED 549 return 0; 550 #else 551 int i, count; 552 int tmp_ids[ids_size]; 553 if (!KMP_AFFINITY_CAPABLE()) 554 return 0; 555 if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks) 556 return 0; 557 /* TODO: Is this safe for asynchronous call from signal handler during runtime 558 * shutdown? */ 559 kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num); 560 count = 0; 561 KMP_CPU_SET_ITERATE(i, mask) { 562 if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) || 563 (!KMP_CPU_ISSET(i, mask))) { 564 continue; 565 } 566 if (count < ids_size) 567 tmp_ids[count] = i; 568 count++; 569 } 570 if (ids_size >= count) { 571 for (i = 0; i < count; i++) { 572 ids[i] = tmp_ids[i]; 573 } 574 } 575 return count; 576 #endif 577 } 578 579 OMPT_API_ROUTINE int ompt_get_place_num(void) { 580 // copied from kmp_ftn_entry.h (but modified) 581 #if !KMP_AFFINITY_SUPPORTED 582 return -1; 583 #else 584 if (__kmp_get_gtid() < 0) 585 return -1; 586 587 int gtid; 588 kmp_info_t *thread; 589 if (!KMP_AFFINITY_CAPABLE()) 590 return -1; 591 gtid = __kmp_entry_gtid(); 592 thread = __kmp_thread_from_gtid(gtid); 593 if (thread == NULL || thread->th.th_current_place < 0) 594 return -1; 595 return thread->th.th_current_place; 596 #endif 597 } 598 599 OMPT_API_ROUTINE int ompt_get_partition_place_nums(int place_nums_size, 600 int *place_nums) { 601 // copied from kmp_ftn_entry.h (but modified) 602 #if !KMP_AFFINITY_SUPPORTED 603 return 0; 604 #else 605 if (__kmp_get_gtid() < 0) 606 return 0; 607 608 int i, gtid, place_num, first_place, last_place, start, end; 609 kmp_info_t *thread; 610 if (!KMP_AFFINITY_CAPABLE()) 611 return 0; 612 gtid = __kmp_entry_gtid(); 613 thread = __kmp_thread_from_gtid(gtid); 614 if (thread == NULL) 615 return 0; 616 first_place = thread->th.th_first_place; 617 last_place = thread->th.th_last_place; 618 if (first_place < 0 || last_place < 0) 619 return 0; 620 if (first_place <= last_place) { 621 start = first_place; 622 end = last_place; 623 } else { 624 start = last_place; 625 end = first_place; 626 } 627 if (end - start <= place_nums_size) 628 for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) { 629 place_nums[i] = place_num; 630 } 631 return end - start + 1; 632 #endif 633 } 634 635 /***************************************************************************** 636 * places 637 ****************************************************************************/ 638 639 OMPT_API_ROUTINE int ompt_get_proc_id(void) { 640 if (__kmp_get_gtid() < 0) 641 return -1; 642 #if KMP_OS_LINUX 643 return sched_getcpu(); 644 #elif KMP_OS_WINDOWS 645 PROCESSOR_NUMBER pn; 646 GetCurrentProcessorNumberEx(&pn); 647 return 64 * pn.Group + pn.Number; 648 #else 649 return -1; 650 #endif 651 } 652 653 /***************************************************************************** 654 * compatability 655 ****************************************************************************/ 656 657 /* 658 * Currently unused function 659 OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; } 660 */ 661 662 /***************************************************************************** 663 * application-facing API 664 ****************************************************************************/ 665 666 /*---------------------------------------------------------------------------- 667 | control 668 ---------------------------------------------------------------------------*/ 669 670 int __kmp_control_tool(uint64_t command, uint64_t modifier, void *arg) { 671 672 if (ompt_enabled.enabled) { 673 if (ompt_enabled.ompt_callback_control_tool) { 674 return ompt_callbacks.ompt_callback(ompt_callback_control_tool)( 675 command, modifier, arg, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid())); 676 } else { 677 return -1; 678 } 679 } else { 680 return -2; 681 } 682 } 683 684 /***************************************************************************** 685 * misc 686 ****************************************************************************/ 687 688 OMPT_API_ROUTINE uint64_t ompt_get_unique_id(void) { 689 return __ompt_get_unique_id_internal(); 690 } 691 692 OMPT_API_ROUTINE void ompt_finalize_tool(void) { 693 // stub 694 } 695 696 /***************************************************************************** 697 * Target 698 ****************************************************************************/ 699 700 OMPT_API_ROUTINE int ompt_get_target_info(uint64_t *device_num, 701 ompt_id_t *target_id, 702 ompt_id_t *host_op_id) { 703 return 0; // thread is not in a target region 704 } 705 706 OMPT_API_ROUTINE int ompt_get_num_devices(void) { 707 return 1; // only one device (the current device) is available 708 } 709 710 /***************************************************************************** 711 * API inquiry for tool 712 ****************************************************************************/ 713 714 static ompt_interface_fn_t ompt_fn_lookup(const char *s) { 715 716 #define ompt_interface_fn(fn) \ 717 fn##_t fn##_f = fn; \ 718 if (strcmp(s, #fn) == 0) \ 719 return (ompt_interface_fn_t)fn##_f; 720 721 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn) 722 723 return (ompt_interface_fn_t)0; 724 } 725