2 * ompt-general.cpp -- OMPT implementation of interface functions
5 //===----------------------------------------------------------------------===//
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //===----------------------------------------------------------------------===//
13 #include "kmp_utils.h"
15 /*****************************************************************************
16 * system include files
17 ****************************************************************************/
28 /*****************************************************************************
30 ****************************************************************************/
32 #include "ompt-specific.cpp"
34 /*****************************************************************************
36 ****************************************************************************/
38 #define ompt_get_callback_success 1
39 #define ompt_get_callback_failure 0
41 #define no_tool_present 0
43 #define OMPT_API_ROUTINE static
45 #ifndef OMPT_STR_MATCH
46 #define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))
49 // prints for an enabled OMP_TOOL_VERBOSE_INIT.
50 // In the future a prefix could be added in the first define, the second define
51 // omits the prefix to allow for continued lines. Example: "PREFIX: Start
52 // tool... Success." instead of "PREFIX: Start tool... PREFIX: Success."
53 #define OMPT_VERBOSE_INIT_PRINT(...) \
55 fprintf(verbose_file, __VA_ARGS__)
56 #define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...) \
58 fprintf(verbose_file, __VA_ARGS__)
60 static FILE *verbose_file
;
61 static int verbose_init
;
63 /*****************************************************************************
65 ****************************************************************************/
68 const char *state_name
;
69 ompt_state_t state_id
;
75 } kmp_mutex_impl_info_t
;
84 /*****************************************************************************
86 ****************************************************************************/
88 ompt_callbacks_active_t ompt_enabled
;
90 ompt_state_info_t ompt_state_info
[] = {
91 #define ompt_state_macro(state, code) {#state, state},
92 FOREACH_OMPT_STATE(ompt_state_macro
)
93 #undef ompt_state_macro
96 kmp_mutex_impl_info_t kmp_mutex_impl_info
[] = {
97 #define kmp_mutex_impl_macro(name, id) {#name, name},
98 FOREACH_KMP_MUTEX_IMPL(kmp_mutex_impl_macro
)
99 #undef kmp_mutex_impl_macro
102 ompt_callbacks_internal_t ompt_callbacks
;
104 static ompt_start_tool_result_t
*ompt_start_tool_result
= NULL
;
107 static HMODULE ompt_tool_module
= NULL
;
108 static HMODULE ompt_archer_module
= NULL
;
109 #define OMPT_DLCLOSE(Lib) FreeLibrary(Lib)
111 static void *ompt_tool_module
= NULL
;
112 static void *ompt_archer_module
= NULL
;
113 #define OMPT_DLCLOSE(Lib) dlclose(Lib)
116 /// Used to track the initializer and the finalizer provided by libomptarget
117 static ompt_start_tool_result_t
*libomptarget_ompt_result
= NULL
;
119 /*****************************************************************************
120 * forward declarations
121 ****************************************************************************/
123 static ompt_interface_fn_t
ompt_fn_lookup(const char *s
);
125 OMPT_API_ROUTINE ompt_data_t
*ompt_get_thread_data(void);
127 /*****************************************************************************
128 * initialization and finalization (private operations)
129 ****************************************************************************/
131 typedef ompt_start_tool_result_t
*(*ompt_start_tool_t
)(unsigned int,
136 // While Darwin supports weak symbols, the library that wishes to provide a new
137 // implementation has to link against this runtime which defeats the purpose
138 // of having tools that are agnostic of the underlying runtime implementation.
140 // Fortunately, the linker includes all symbols of an executable in the global
141 // symbol table by default so dlsym() even finds static implementations of
142 // ompt_start_tool. For this to work on Linux, -Wl,--export-dynamic needs to be
143 // passed when building the application which we don't want to rely on.
145 static ompt_start_tool_result_t
*ompt_tool_darwin(unsigned int omp_version
,
146 const char *runtime_version
) {
147 ompt_start_tool_result_t
*ret
= NULL
;
148 // Search symbol in the current address space.
149 ompt_start_tool_t start_tool
=
150 (ompt_start_tool_t
)dlsym(RTLD_DEFAULT
, "ompt_start_tool");
152 ret
= start_tool(omp_version
, runtime_version
);
157 #elif OMPT_HAVE_WEAK_ATTRIBUTE
159 // On Unix-like systems that support weak symbols the following implementation
160 // of ompt_start_tool() will be used in case no tool-supplied implementation of
161 // this function is present in the address space of a process.
163 _OMP_EXTERN OMPT_WEAK_ATTRIBUTE ompt_start_tool_result_t
*
164 ompt_start_tool(unsigned int omp_version
, const char *runtime_version
) {
165 ompt_start_tool_result_t
*ret
= NULL
;
166 // Search next symbol in the current address space. This can happen if the
167 // runtime library is linked before the tool. Since glibc 2.2 strong symbols
168 // don't override weak symbols that have been found before unless the user
169 // sets the environment variable LD_DYNAMIC_WEAK.
170 ompt_start_tool_t next_tool
=
171 (ompt_start_tool_t
)dlsym(RTLD_NEXT
, "ompt_start_tool");
173 ret
= next_tool(omp_version
, runtime_version
);
178 #elif OMPT_HAVE_PSAPI
180 // On Windows, the ompt_tool_windows function is used to find the
181 // ompt_start_tool symbol across all modules loaded by a process. If
182 // ompt_start_tool is found, ompt_start_tool's return value is used to
183 // initialize the tool. Otherwise, NULL is returned and OMPT won't be enabled.
186 #pragma comment(lib, "psapi.lib")
188 // The number of loaded modules to start enumeration with EnumProcessModules()
189 #define NUM_MODULES 128
191 static ompt_start_tool_result_t
*
192 ompt_tool_windows(unsigned int omp_version
, const char *runtime_version
) {
194 DWORD needed
, new_size
;
196 HANDLE process
= GetCurrentProcess();
197 modules
= (HMODULE
*)malloc(NUM_MODULES
* sizeof(HMODULE
));
198 ompt_start_tool_t ompt_tool_p
= NULL
;
201 printf("ompt_tool_windows(): looking for ompt_start_tool\n");
203 if (!EnumProcessModules(process
, modules
, NUM_MODULES
* sizeof(HMODULE
),
205 // Regardless of the error reason use the stub initialization function
209 // Check if NUM_MODULES is enough to list all modules
210 new_size
= needed
/ sizeof(HMODULE
);
211 if (new_size
> NUM_MODULES
) {
213 printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed
);
215 modules
= (HMODULE
*)realloc(modules
, needed
);
216 // If resizing failed use the stub function.
217 if (!EnumProcessModules(process
, modules
, needed
, &needed
)) {
222 for (i
= 0; i
< new_size
; ++i
) {
223 (FARPROC
&)ompt_tool_p
= GetProcAddress(modules
[i
], "ompt_start_tool");
226 TCHAR modName
[MAX_PATH
];
227 if (GetModuleFileName(modules
[i
], modName
, MAX_PATH
))
228 printf("ompt_tool_windows(): ompt_start_tool found in module %s\n",
232 return (*ompt_tool_p
)(omp_version
, runtime_version
);
236 TCHAR modName
[MAX_PATH
];
237 if (GetModuleFileName(modules
[i
], modName
, MAX_PATH
))
238 printf("ompt_tool_windows(): ompt_start_tool not found in module %s\n",
247 #error Activation of OMPT is not supported on this platform.
250 static ompt_start_tool_result_t
*
251 ompt_try_start_tool(unsigned int omp_version
, const char *runtime_version
) {
252 ompt_start_tool_result_t
*ret
= NULL
;
253 ompt_start_tool_t start_tool
= NULL
;
255 // Cannot use colon to describe a list of absolute paths on Windows
256 const char *sep
= ";";
258 const char *sep
= ":";
261 OMPT_VERBOSE_INIT_PRINT("----- START LOGGING OF TOOL REGISTRATION -----\n");
262 OMPT_VERBOSE_INIT_PRINT("Search for OMP tool in current address space... ");
265 // Try in the current address space
266 ret
= ompt_tool_darwin(omp_version
, runtime_version
);
267 #elif OMPT_HAVE_WEAK_ATTRIBUTE
268 ret
= ompt_start_tool(omp_version
, runtime_version
);
269 #elif OMPT_HAVE_PSAPI
270 ret
= ompt_tool_windows(omp_version
, runtime_version
);
272 #error Activation of OMPT is not supported on this platform.
275 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
276 OMPT_VERBOSE_INIT_PRINT(
277 "Tool was started and is using the OMPT interface.\n");
278 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
282 // Try tool-libraries-var ICV
283 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed.\n");
284 const char *tool_libs
= getenv("OMP_TOOL_LIBRARIES");
286 OMPT_VERBOSE_INIT_PRINT("Searching tool libraries...\n");
287 OMPT_VERBOSE_INIT_PRINT("OMP_TOOL_LIBRARIES = %s\n", tool_libs
);
288 char *libs
= __kmp_str_format("%s", tool_libs
);
290 char *fname
= __kmp_str_token(libs
, sep
, &buf
);
296 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
297 void *h
= dlopen(fname
, RTLD_LAZY
);
299 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
301 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success. \n");
302 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
304 dlerror(); // Clear any existing error
305 start_tool
= (ompt_start_tool_t
)dlsym(h
, "ompt_start_tool");
307 char *error
= dlerror();
309 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", error
);
311 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n",
312 "ompt_start_tool = NULL");
316 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
317 HMODULE h
= LoadLibrary(fname
);
319 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
320 (unsigned)GetLastError());
322 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success. \n");
323 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
325 start_tool
= (ompt_start_tool_t
)GetProcAddress(h
, "ompt_start_tool");
327 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
328 (unsigned)GetLastError());
331 #error Activation of OMPT is not supported on this platform.
334 ret
= (*start_tool
)(omp_version
, runtime_version
);
336 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
337 OMPT_VERBOSE_INIT_PRINT(
338 "Tool was started and is using the OMPT interface.\n");
339 ompt_tool_module
= h
;
342 OMPT_VERBOSE_INIT_CONTINUED_PRINT(
343 "Found but not using the OMPT interface.\n");
344 OMPT_VERBOSE_INIT_PRINT("Continuing search...\n");
348 fname
= __kmp_str_token(NULL
, sep
, &buf
);
350 __kmp_str_free(&libs
);
352 OMPT_VERBOSE_INIT_PRINT("No OMP_TOOL_LIBRARIES defined.\n");
355 // usable tool found in tool-libraries
357 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
362 { // Non-standard: load archer tool if application is built with TSan
363 const char *fname
= "libarcher.so";
364 OMPT_VERBOSE_INIT_PRINT(
365 "...searching tool libraries failed. Using archer tool.\n");
366 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
367 void *h
= dlopen(fname
, RTLD_LAZY
);
369 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
370 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ", fname
);
371 start_tool
= (ompt_start_tool_t
)dlsym(h
, "ompt_start_tool");
373 ret
= (*start_tool
)(omp_version
, runtime_version
);
375 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
376 OMPT_VERBOSE_INIT_PRINT(
377 "Tool was started and is using the OMPT interface.\n");
378 OMPT_VERBOSE_INIT_PRINT(
379 "----- END LOGGING OF TOOL REGISTRATION -----\n");
380 ompt_archer_module
= h
;
383 OMPT_VERBOSE_INIT_CONTINUED_PRINT(
384 "Found but not using the OMPT interface.\n");
386 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
392 OMPT_VERBOSE_INIT_PRINT("No OMP tool loaded.\n");
393 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
397 void ompt_pre_init() {
398 //--------------------------------------------------
399 // Execute the pre-initialization logic only once.
400 //--------------------------------------------------
401 static int ompt_pre_initialized
= 0;
403 if (ompt_pre_initialized
)
406 ompt_pre_initialized
= 1;
408 //--------------------------------------------------
409 // Use a tool iff a tool is enabled and available.
410 //--------------------------------------------------
411 const char *ompt_env_var
= getenv("OMP_TOOL");
412 tool_setting_e tool_setting
= omp_tool_error
;
414 if (!ompt_env_var
|| !strcmp(ompt_env_var
, ""))
415 tool_setting
= omp_tool_unset
;
416 else if (OMPT_STR_MATCH(ompt_env_var
, "disabled"))
417 tool_setting
= omp_tool_disabled
;
418 else if (OMPT_STR_MATCH(ompt_env_var
, "enabled"))
419 tool_setting
= omp_tool_enabled
;
421 const char *ompt_env_verbose_init
= getenv("OMP_TOOL_VERBOSE_INIT");
422 // possible options: disabled | stdout | stderr | <filename>
423 // if set, not empty and not disabled -> prepare for logging
424 if (ompt_env_verbose_init
&& strcmp(ompt_env_verbose_init
, "") &&
425 !OMPT_STR_MATCH(ompt_env_verbose_init
, "disabled")) {
427 if (OMPT_STR_MATCH(ompt_env_verbose_init
, "STDERR"))
428 verbose_file
= stderr
;
429 else if (OMPT_STR_MATCH(ompt_env_verbose_init
, "STDOUT"))
430 verbose_file
= stdout
;
432 verbose_file
= fopen(ompt_env_verbose_init
, "w");
437 printf("ompt_pre_init(): tool_setting = %d\n", tool_setting
);
439 switch (tool_setting
) {
440 case omp_tool_disabled
:
441 OMPT_VERBOSE_INIT_PRINT("OMP tool disabled. \n");
445 case omp_tool_enabled
:
447 //--------------------------------------------------
448 // Load tool iff specified in environment variable
449 //--------------------------------------------------
450 ompt_start_tool_result
=
451 ompt_try_start_tool(__kmp_openmp_version
, ompt_get_runtime_version());
453 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
458 "Warning: OMP_TOOL has invalid value \"%s\".\n"
459 " legal values are (NULL,\"\",\"disabled\","
464 if (verbose_init
&& verbose_file
!= stderr
&& verbose_file
!= stdout
)
465 fclose(verbose_file
);
467 printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled
.enabled
);
471 extern "C" int omp_get_initial_device(void);
473 void ompt_post_init() {
474 //--------------------------------------------------
475 // Execute the post-initialization logic only once.
476 //--------------------------------------------------
477 static int ompt_post_initialized
= 0;
479 if (ompt_post_initialized
)
482 ompt_post_initialized
= 1;
484 //--------------------------------------------------
485 // Initialize the tool if so indicated.
486 //--------------------------------------------------
487 if (ompt_start_tool_result
) {
488 ompt_enabled
.enabled
= !!ompt_start_tool_result
->initialize(
489 ompt_fn_lookup
, omp_get_initial_device(),
490 &(ompt_start_tool_result
->tool_data
));
492 if (!ompt_enabled
.enabled
) {
493 // tool not enabled, zero out the bitmap, and done
494 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
498 kmp_info_t
*root_thread
= ompt_get_thread();
500 ompt_set_thread_state(root_thread
, ompt_state_overhead
);
502 if (ompt_enabled
.ompt_callback_thread_begin
) {
503 ompt_callbacks
.ompt_callback(ompt_callback_thread_begin
)(
504 ompt_thread_initial
, __ompt_get_thread_data_internal());
506 ompt_data_t
*task_data
= nullptr;
507 ompt_data_t
*parallel_data
= nullptr;
508 __ompt_get_task_info_internal(0, NULL
, &task_data
, NULL
, ¶llel_data
,
510 if (ompt_enabled
.ompt_callback_implicit_task
) {
511 ompt_callbacks
.ompt_callback(ompt_callback_implicit_task
)(
512 ompt_scope_begin
, parallel_data
, task_data
, 1, 1, ompt_task_initial
);
515 ompt_set_thread_state(root_thread
, ompt_state_work_serial
);
520 if (ompt_enabled
.enabled
) {
521 if (ompt_start_tool_result
&& ompt_start_tool_result
->finalize
) {
522 ompt_start_tool_result
->finalize(&(ompt_start_tool_result
->tool_data
));
524 if (libomptarget_ompt_result
&& libomptarget_ompt_result
->finalize
) {
525 libomptarget_ompt_result
->finalize(NULL
);
529 if (ompt_archer_module
)
530 OMPT_DLCLOSE(ompt_archer_module
);
531 if (ompt_tool_module
)
532 OMPT_DLCLOSE(ompt_tool_module
);
533 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
536 /*****************************************************************************
537 * interface operations
538 ****************************************************************************/
540 /*****************************************************************************
542 ****************************************************************************/
544 OMPT_API_ROUTINE
int ompt_enumerate_states(int current_state
, int *next_state
,
545 const char **next_state_name
) {
546 const static int len
= sizeof(ompt_state_info
) / sizeof(ompt_state_info_t
);
549 for (i
= 0; i
< len
- 1; i
++) {
550 if (ompt_state_info
[i
].state_id
== current_state
) {
551 *next_state
= ompt_state_info
[i
+ 1].state_id
;
552 *next_state_name
= ompt_state_info
[i
+ 1].state_name
;
560 OMPT_API_ROUTINE
int ompt_enumerate_mutex_impls(int current_impl
,
562 const char **next_impl_name
) {
563 const static int len
=
564 sizeof(kmp_mutex_impl_info
) / sizeof(kmp_mutex_impl_info_t
);
566 for (i
= 0; i
< len
- 1; i
++) {
567 if (kmp_mutex_impl_info
[i
].id
!= current_impl
)
569 *next_impl
= kmp_mutex_impl_info
[i
+ 1].id
;
570 *next_impl_name
= kmp_mutex_impl_info
[i
+ 1].name
;
576 /*****************************************************************************
578 ****************************************************************************/
580 OMPT_API_ROUTINE ompt_set_result_t
ompt_set_callback(ompt_callbacks_t which
,
581 ompt_callback_t callback
) {
584 #define ompt_event_macro(event_name, callback_type, event_id) \
586 ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \
587 ompt_enabled.event_name = (callback != 0); \
589 return ompt_event_implementation_status(event_name); \
591 return ompt_set_always;
593 FOREACH_OMPT_EVENT(ompt_event_macro
)
595 #undef ompt_event_macro
598 return ompt_set_error
;
602 OMPT_API_ROUTINE
int ompt_get_callback(ompt_callbacks_t which
,
603 ompt_callback_t
*callback
) {
604 if (!ompt_enabled
.enabled
)
605 return ompt_get_callback_failure
;
609 #define ompt_event_macro(event_name, callback_type, event_id) \
611 ompt_callback_t mycb = \
612 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \
613 if (ompt_enabled.event_name && mycb) { \
615 return ompt_get_callback_success; \
617 return ompt_get_callback_failure; \
620 FOREACH_OMPT_EVENT(ompt_event_macro
)
622 #undef ompt_event_macro
625 return ompt_get_callback_failure
;
629 /*****************************************************************************
631 ****************************************************************************/
633 OMPT_API_ROUTINE
int ompt_get_parallel_info(int ancestor_level
,
634 ompt_data_t
**parallel_data
,
636 if (!ompt_enabled
.enabled
)
638 return __ompt_get_parallel_info_internal(ancestor_level
, parallel_data
,
642 OMPT_API_ROUTINE
int ompt_get_state(ompt_wait_id_t
*wait_id
) {
643 if (!ompt_enabled
.enabled
)
644 return ompt_state_work_serial
;
645 int thread_state
= __ompt_get_state_internal(wait_id
);
647 if (thread_state
== ompt_state_undefined
) {
648 thread_state
= ompt_state_work_serial
;
654 /*****************************************************************************
656 ****************************************************************************/
658 OMPT_API_ROUTINE ompt_data_t
*ompt_get_thread_data(void) {
659 if (!ompt_enabled
.enabled
)
661 return __ompt_get_thread_data_internal();
664 OMPT_API_ROUTINE
int ompt_get_task_info(int ancestor_level
, int *type
,
665 ompt_data_t
**task_data
,
666 ompt_frame_t
**task_frame
,
667 ompt_data_t
**parallel_data
,
669 if (!ompt_enabled
.enabled
)
671 return __ompt_get_task_info_internal(ancestor_level
, type
, task_data
,
672 task_frame
, parallel_data
, thread_num
);
675 OMPT_API_ROUTINE
int ompt_get_task_memory(void **addr
, size_t *size
,
677 return __ompt_get_task_memory_internal(addr
, size
, block
);
680 /*****************************************************************************
682 ****************************************************************************/
684 OMPT_API_ROUTINE
int ompt_get_num_procs(void) {
685 // copied from kmp_ftn_entry.h (but modified: OMPT can only be called when
686 // runtime is initialized)
687 return __kmp_avail_proc
;
690 /*****************************************************************************
692 ****************************************************************************/
694 OMPT_API_ROUTINE
int ompt_get_num_places(void) {
695 // copied from kmp_ftn_entry.h (but modified)
696 #if !KMP_AFFINITY_SUPPORTED
699 if (!KMP_AFFINITY_CAPABLE())
701 return __kmp_affinity
.num_masks
;
705 OMPT_API_ROUTINE
int ompt_get_place_proc_ids(int place_num
, int ids_size
,
707 // copied from kmp_ftn_entry.h (but modified)
708 #if !KMP_AFFINITY_SUPPORTED
712 SimpleVLA
<int> tmp_ids(ids_size
);
713 for (int j
= 0; j
< ids_size
; j
++)
715 if (!KMP_AFFINITY_CAPABLE())
717 if (place_num
< 0 || place_num
>= (int)__kmp_affinity
.num_masks
)
719 /* TODO: Is this safe for asynchronous call from signal handler during runtime
721 kmp_affin_mask_t
*mask
= KMP_CPU_INDEX(__kmp_affinity
.masks
, place_num
);
723 KMP_CPU_SET_ITERATE(i
, mask
) {
724 if ((!KMP_CPU_ISSET(i
, __kmp_affin_fullMask
)) ||
725 (!KMP_CPU_ISSET(i
, mask
))) {
728 if (count
< ids_size
)
732 if (ids_size
>= count
) {
733 for (i
= 0; i
< count
; i
++) {
741 OMPT_API_ROUTINE
int ompt_get_place_num(void) {
742 // copied from kmp_ftn_entry.h (but modified)
743 #if !KMP_AFFINITY_SUPPORTED
746 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
751 if (!KMP_AFFINITY_CAPABLE())
753 gtid
= __kmp_entry_gtid();
754 thread
= __kmp_thread_from_gtid(gtid
);
755 if (thread
== NULL
|| thread
->th
.th_current_place
< 0)
757 return thread
->th
.th_current_place
;
761 OMPT_API_ROUTINE
int ompt_get_partition_place_nums(int place_nums_size
,
763 // copied from kmp_ftn_entry.h (but modified)
764 #if !KMP_AFFINITY_SUPPORTED
767 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
770 int i
, gtid
, place_num
, first_place
, last_place
, start
, end
;
772 if (!KMP_AFFINITY_CAPABLE())
774 gtid
= __kmp_entry_gtid();
775 thread
= __kmp_thread_from_gtid(gtid
);
778 first_place
= thread
->th
.th_first_place
;
779 last_place
= thread
->th
.th_last_place
;
780 if (first_place
< 0 || last_place
< 0)
782 if (first_place
<= last_place
) {
789 if (end
- start
<= place_nums_size
)
790 for (i
= 0, place_num
= start
; place_num
<= end
; ++place_num
, ++i
) {
791 place_nums
[i
] = place_num
;
793 return end
- start
+ 1;
797 /*****************************************************************************
799 ****************************************************************************/
801 OMPT_API_ROUTINE
int ompt_get_proc_id(void) {
802 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
804 #if KMP_HAVE_SCHED_GETCPU
805 return sched_getcpu();
808 GetCurrentProcessorNumberEx(&pn
);
809 return 64 * pn
.Group
+ pn
.Number
;
815 /*****************************************************************************
817 ****************************************************************************/
820 * Currently unused function
821 OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; }
824 /*****************************************************************************
825 * application-facing API
826 ****************************************************************************/
828 /*----------------------------------------------------------------------------
830 ---------------------------------------------------------------------------*/
832 int __kmp_control_tool(uint64_t command
, uint64_t modifier
, void *arg
) {
834 if (ompt_enabled
.enabled
) {
835 if (ompt_enabled
.ompt_callback_control_tool
) {
836 return ompt_callbacks
.ompt_callback(ompt_callback_control_tool
)(
837 command
, modifier
, arg
, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid()));
846 /*****************************************************************************
848 ****************************************************************************/
850 OMPT_API_ROUTINE
uint64_t ompt_get_unique_id(void) {
851 return __ompt_get_unique_id_internal();
854 OMPT_API_ROUTINE
void ompt_finalize_tool(void) { __kmp_internal_end_atexit(); }
856 /*****************************************************************************
858 ****************************************************************************/
860 OMPT_API_ROUTINE
int ompt_get_target_info(uint64_t *device_num
,
861 ompt_id_t
*target_id
,
862 ompt_id_t
*host_op_id
) {
863 return 0; // thread is not in a target region
866 OMPT_API_ROUTINE
int ompt_get_num_devices(void) {
867 return 1; // only one device (the current device) is available
870 /*****************************************************************************
871 * API inquiry for tool
872 ****************************************************************************/
874 static ompt_interface_fn_t
ompt_fn_lookup(const char *s
) {
876 #define ompt_interface_fn(fn) \
877 fn##_t fn##_f = fn; \
878 if (strcmp(s, #fn) == 0) \
879 return (ompt_interface_fn_t)fn##_f;
881 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn
)
883 #undef ompt_interface_fn
888 static ompt_data_t
*ompt_get_task_data() { return __ompt_get_task_data(); }
890 static ompt_data_t
*ompt_get_target_task_data() {
891 return __ompt_get_target_task_data();
894 /// Lookup function to query libomp callbacks registered by the tool
895 static ompt_interface_fn_t
ompt_libomp_target_fn_lookup(const char *s
) {
896 #define provide_fn(fn) \
897 if (strcmp(s, #fn) == 0) \
898 return (ompt_interface_fn_t)fn;
900 provide_fn(ompt_get_callback
);
901 provide_fn(ompt_get_task_data
);
902 provide_fn(ompt_get_target_task_data
);
905 #define ompt_interface_fn(fn, type, code) \
906 if (strcmp(s, #fn) == 0) \
907 return (ompt_interface_fn_t)ompt_callbacks.ompt_callback(fn);
909 FOREACH_OMPT_DEVICE_EVENT(ompt_interface_fn
)
910 FOREACH_OMPT_EMI_EVENT(ompt_interface_fn
)
911 FOREACH_OMPT_NOEMI_EVENT(ompt_interface_fn
)
912 #undef ompt_interface_fn
914 return (ompt_interface_fn_t
)0;
917 /// This function is called by the libomptarget connector to assign
918 /// callbacks already registered with libomp.
919 _OMP_EXTERN
void ompt_libomp_connect(ompt_start_tool_result_t
*result
) {
920 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Enter ompt_libomp_connect\n");
922 // Ensure libomp callbacks have been added if not already
923 __ompt_force_initialization();
925 if (ompt_enabled
.enabled
&& result
) {
926 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Connecting with libomptarget\n");
927 // Pass in the libomp lookup function so that the already registered
928 // functions can be extracted and assigned to the callbacks in
930 result
->initialize(ompt_libomp_target_fn_lookup
,
931 /* initial_device_num */ 0, /* tool_data */ nullptr);
932 // Track the object provided by libomptarget so that the finalizer can be
933 // called during OMPT finalization
934 libomptarget_ompt_result
= result
;
936 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Exit ompt_libomp_connect\n");