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 /*****************************************************************************
14 * system include files
15 ****************************************************************************/
27 /*****************************************************************************
29 ****************************************************************************/
31 #include "ompt-specific.cpp"
33 /*****************************************************************************
35 ****************************************************************************/
37 #define ompt_get_callback_success 1
38 #define ompt_get_callback_failure 0
40 #define no_tool_present 0
42 #define OMPT_API_ROUTINE static
44 #ifndef OMPT_STR_MATCH
45 #define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))
48 // prints for an enabled OMP_TOOL_VERBOSE_INIT.
49 // In the future a prefix could be added in the first define, the second define
50 // omits the prefix to allow for continued lines. Example: "PREFIX: Start
51 // tool... Success." instead of "PREFIX: Start tool... PREFIX: Success."
52 #define OMPT_VERBOSE_INIT_PRINT(...) \
54 fprintf(verbose_file, __VA_ARGS__)
55 #define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...) \
57 fprintf(verbose_file, __VA_ARGS__)
59 static FILE *verbose_file
;
60 static int verbose_init
;
62 /*****************************************************************************
64 ****************************************************************************/
67 const char *state_name
;
68 ompt_state_t state_id
;
74 } kmp_mutex_impl_info_t
;
83 /*****************************************************************************
85 ****************************************************************************/
87 ompt_callbacks_active_t ompt_enabled
;
89 ompt_state_info_t ompt_state_info
[] = {
90 #define ompt_state_macro(state, code) {#state, state},
91 FOREACH_OMPT_STATE(ompt_state_macro
)
92 #undef ompt_state_macro
95 kmp_mutex_impl_info_t kmp_mutex_impl_info
[] = {
96 #define kmp_mutex_impl_macro(name, id) {#name, name},
97 FOREACH_KMP_MUTEX_IMPL(kmp_mutex_impl_macro
)
98 #undef kmp_mutex_impl_macro
101 ompt_callbacks_internal_t ompt_callbacks
;
103 static ompt_start_tool_result_t
*ompt_start_tool_result
= NULL
;
106 static HMODULE ompt_tool_module
= NULL
;
107 #define OMPT_DLCLOSE(Lib) FreeLibrary(Lib)
109 static void *ompt_tool_module
= NULL
;
110 #define OMPT_DLCLOSE(Lib) dlclose(Lib)
113 /// Used to track the initializer and the finalizer provided by libomptarget
114 static ompt_start_tool_result_t
*libomptarget_ompt_result
= NULL
;
116 /*****************************************************************************
117 * forward declarations
118 ****************************************************************************/
120 static ompt_interface_fn_t
ompt_fn_lookup(const char *s
);
122 OMPT_API_ROUTINE ompt_data_t
*ompt_get_thread_data(void);
124 /*****************************************************************************
125 * initialization and finalization (private operations)
126 ****************************************************************************/
128 typedef ompt_start_tool_result_t
*(*ompt_start_tool_t
)(unsigned int,
133 // While Darwin supports weak symbols, the library that wishes to provide a new
134 // implementation has to link against this runtime which defeats the purpose
135 // of having tools that are agnostic of the underlying runtime implementation.
137 // Fortunately, the linker includes all symbols of an executable in the global
138 // symbol table by default so dlsym() even finds static implementations of
139 // ompt_start_tool. For this to work on Linux, -Wl,--export-dynamic needs to be
140 // passed when building the application which we don't want to rely on.
142 static ompt_start_tool_result_t
*ompt_tool_darwin(unsigned int omp_version
,
143 const char *runtime_version
) {
144 ompt_start_tool_result_t
*ret
= NULL
;
145 // Search symbol in the current address space.
146 ompt_start_tool_t start_tool
=
147 (ompt_start_tool_t
)dlsym(RTLD_DEFAULT
, "ompt_start_tool");
149 ret
= start_tool(omp_version
, runtime_version
);
154 #elif OMPT_HAVE_WEAK_ATTRIBUTE
156 // On Unix-like systems that support weak symbols the following implementation
157 // of ompt_start_tool() will be used in case no tool-supplied implementation of
158 // this function is present in the address space of a process.
160 _OMP_EXTERN OMPT_WEAK_ATTRIBUTE ompt_start_tool_result_t
*
161 ompt_start_tool(unsigned int omp_version
, const char *runtime_version
) {
162 ompt_start_tool_result_t
*ret
= NULL
;
163 // Search next symbol in the current address space. This can happen if the
164 // runtime library is linked before the tool. Since glibc 2.2 strong symbols
165 // don't override weak symbols that have been found before unless the user
166 // sets the environment variable LD_DYNAMIC_WEAK.
167 ompt_start_tool_t next_tool
=
168 (ompt_start_tool_t
)dlsym(RTLD_NEXT
, "ompt_start_tool");
170 ret
= next_tool(omp_version
, runtime_version
);
175 #elif OMPT_HAVE_PSAPI
177 // On Windows, the ompt_tool_windows function is used to find the
178 // ompt_start_tool symbol across all modules loaded by a process. If
179 // ompt_start_tool is found, ompt_start_tool's return value is used to
180 // initialize the tool. Otherwise, NULL is returned and OMPT won't be enabled.
183 #pragma comment(lib, "psapi.lib")
185 // The number of loaded modules to start enumeration with EnumProcessModules()
186 #define NUM_MODULES 128
188 static ompt_start_tool_result_t
*
189 ompt_tool_windows(unsigned int omp_version
, const char *runtime_version
) {
191 DWORD needed
, new_size
;
193 HANDLE process
= GetCurrentProcess();
194 modules
= (HMODULE
*)malloc(NUM_MODULES
* sizeof(HMODULE
));
195 ompt_start_tool_t ompt_tool_p
= NULL
;
198 printf("ompt_tool_windows(): looking for ompt_start_tool\n");
200 if (!EnumProcessModules(process
, modules
, NUM_MODULES
* sizeof(HMODULE
),
202 // Regardless of the error reason use the stub initialization function
206 // Check if NUM_MODULES is enough to list all modules
207 new_size
= needed
/ sizeof(HMODULE
);
208 if (new_size
> NUM_MODULES
) {
210 printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed
);
212 modules
= (HMODULE
*)realloc(modules
, needed
);
213 // If resizing failed use the stub function.
214 if (!EnumProcessModules(process
, modules
, needed
, &needed
)) {
219 for (i
= 0; i
< new_size
; ++i
) {
220 (FARPROC
&)ompt_tool_p
= GetProcAddress(modules
[i
], "ompt_start_tool");
223 TCHAR modName
[MAX_PATH
];
224 if (GetModuleFileName(modules
[i
], modName
, MAX_PATH
))
225 printf("ompt_tool_windows(): ompt_start_tool found in module %s\n",
229 return (*ompt_tool_p
)(omp_version
, runtime_version
);
233 TCHAR modName
[MAX_PATH
];
234 if (GetModuleFileName(modules
[i
], modName
, MAX_PATH
))
235 printf("ompt_tool_windows(): ompt_start_tool not found in module %s\n",
244 #error Activation of OMPT is not supported on this platform.
247 static ompt_start_tool_result_t
*
248 ompt_try_start_tool(unsigned int omp_version
, const char *runtime_version
) {
249 ompt_start_tool_result_t
*ret
= NULL
;
250 ompt_start_tool_t start_tool
= NULL
;
252 // Cannot use colon to describe a list of absolute paths on Windows
253 const char *sep
= ";";
255 const char *sep
= ":";
258 OMPT_VERBOSE_INIT_PRINT("----- START LOGGING OF TOOL REGISTRATION -----\n");
259 OMPT_VERBOSE_INIT_PRINT("Search for OMP tool in current address space... ");
262 // Try in the current address space
263 ret
= ompt_tool_darwin(omp_version
, runtime_version
);
264 #elif OMPT_HAVE_WEAK_ATTRIBUTE
265 ret
= ompt_start_tool(omp_version
, runtime_version
);
266 #elif OMPT_HAVE_PSAPI
267 ret
= ompt_tool_windows(omp_version
, runtime_version
);
269 #error Activation of OMPT is not supported on this platform.
272 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
273 OMPT_VERBOSE_INIT_PRINT(
274 "Tool was started and is using the OMPT interface.\n");
275 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
279 // Try tool-libraries-var ICV
280 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed.\n");
281 const char *tool_libs
= getenv("OMP_TOOL_LIBRARIES");
283 OMPT_VERBOSE_INIT_PRINT("Searching tool libraries...\n");
284 OMPT_VERBOSE_INIT_PRINT("OMP_TOOL_LIBRARIES = %s\n", tool_libs
);
285 char *libs
= __kmp_str_format("%s", tool_libs
);
287 char *fname
= __kmp_str_token(libs
, sep
, &buf
);
293 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
294 void *h
= dlopen(fname
, RTLD_LAZY
);
296 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
298 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success. \n");
299 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
301 dlerror(); // Clear any existing error
302 start_tool
= (ompt_start_tool_t
)dlsym(h
, "ompt_start_tool");
304 char *error
= dlerror();
306 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", error
);
308 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n",
309 "ompt_start_tool = NULL");
313 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
314 HMODULE h
= LoadLibrary(fname
);
316 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
317 (unsigned)GetLastError());
319 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success. \n");
320 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
322 start_tool
= (ompt_start_tool_t
)GetProcAddress(h
, "ompt_start_tool");
324 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
325 (unsigned)GetLastError());
328 #error Activation of OMPT is not supported on this platform.
331 ret
= (*start_tool
)(omp_version
, runtime_version
);
333 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
334 OMPT_VERBOSE_INIT_PRINT(
335 "Tool was started and is using the OMPT interface.\n");
336 ompt_tool_module
= h
;
339 OMPT_VERBOSE_INIT_CONTINUED_PRINT(
340 "Found but not using the OMPT interface.\n");
341 OMPT_VERBOSE_INIT_PRINT("Continuing search...\n");
345 fname
= __kmp_str_token(NULL
, sep
, &buf
);
347 __kmp_str_free(&libs
);
349 OMPT_VERBOSE_INIT_PRINT("No OMP_TOOL_LIBRARIES defined.\n");
352 // usable tool found in tool-libraries
354 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
359 { // Non-standard: load archer tool if application is built with TSan
360 const char *fname
= "libarcher.so";
361 OMPT_VERBOSE_INIT_PRINT(
362 "...searching tool libraries failed. Using archer tool.\n");
363 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname
);
364 void *h
= dlopen(fname
, RTLD_LAZY
);
366 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
367 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ", fname
);
368 start_tool
= (ompt_start_tool_t
)dlsym(h
, "ompt_start_tool");
370 ret
= (*start_tool
)(omp_version
, runtime_version
);
372 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Success.\n");
373 OMPT_VERBOSE_INIT_PRINT(
374 "Tool was started and is using the OMPT interface.\n");
375 OMPT_VERBOSE_INIT_PRINT(
376 "----- END LOGGING OF TOOL REGISTRATION -----\n");
379 OMPT_VERBOSE_INIT_CONTINUED_PRINT(
380 "Found but not using the OMPT interface.\n");
382 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
387 OMPT_VERBOSE_INIT_PRINT("No OMP tool loaded.\n");
388 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
392 void ompt_pre_init() {
393 //--------------------------------------------------
394 // Execute the pre-initialization logic only once.
395 //--------------------------------------------------
396 static int ompt_pre_initialized
= 0;
398 if (ompt_pre_initialized
)
401 ompt_pre_initialized
= 1;
403 //--------------------------------------------------
404 // Use a tool iff a tool is enabled and available.
405 //--------------------------------------------------
406 const char *ompt_env_var
= getenv("OMP_TOOL");
407 tool_setting_e tool_setting
= omp_tool_error
;
409 if (!ompt_env_var
|| !strcmp(ompt_env_var
, ""))
410 tool_setting
= omp_tool_unset
;
411 else if (OMPT_STR_MATCH(ompt_env_var
, "disabled"))
412 tool_setting
= omp_tool_disabled
;
413 else if (OMPT_STR_MATCH(ompt_env_var
, "enabled"))
414 tool_setting
= omp_tool_enabled
;
416 const char *ompt_env_verbose_init
= getenv("OMP_TOOL_VERBOSE_INIT");
417 // possible options: disabled | stdout | stderr | <filename>
418 // if set, not empty and not disabled -> prepare for logging
419 if (ompt_env_verbose_init
&& strcmp(ompt_env_verbose_init
, "") &&
420 !OMPT_STR_MATCH(ompt_env_verbose_init
, "disabled")) {
422 if (OMPT_STR_MATCH(ompt_env_verbose_init
, "STDERR"))
423 verbose_file
= stderr
;
424 else if (OMPT_STR_MATCH(ompt_env_verbose_init
, "STDOUT"))
425 verbose_file
= stdout
;
427 verbose_file
= fopen(ompt_env_verbose_init
, "w");
432 printf("ompt_pre_init(): tool_setting = %d\n", tool_setting
);
434 switch (tool_setting
) {
435 case omp_tool_disabled
:
436 OMPT_VERBOSE_INIT_PRINT("OMP tool disabled. \n");
440 case omp_tool_enabled
:
442 //--------------------------------------------------
443 // Load tool iff specified in environment variable
444 //--------------------------------------------------
445 ompt_start_tool_result
=
446 ompt_try_start_tool(__kmp_openmp_version
, ompt_get_runtime_version());
448 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
453 "Warning: OMP_TOOL has invalid value \"%s\".\n"
454 " legal values are (NULL,\"\",\"disabled\","
459 if (verbose_init
&& verbose_file
!= stderr
&& verbose_file
!= stdout
)
460 fclose(verbose_file
);
462 printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled
.enabled
);
466 extern "C" int omp_get_initial_device(void);
468 void ompt_post_init() {
469 //--------------------------------------------------
470 // Execute the post-initialization logic only once.
471 //--------------------------------------------------
472 static int ompt_post_initialized
= 0;
474 if (ompt_post_initialized
)
477 ompt_post_initialized
= 1;
479 //--------------------------------------------------
480 // Initialize the tool if so indicated.
481 //--------------------------------------------------
482 if (ompt_start_tool_result
) {
483 ompt_enabled
.enabled
= !!ompt_start_tool_result
->initialize(
484 ompt_fn_lookup
, omp_get_initial_device(),
485 &(ompt_start_tool_result
->tool_data
));
487 if (!ompt_enabled
.enabled
) {
488 // tool not enabled, zero out the bitmap, and done
489 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
493 kmp_info_t
*root_thread
= ompt_get_thread();
495 ompt_set_thread_state(root_thread
, ompt_state_overhead
);
497 if (ompt_enabled
.ompt_callback_thread_begin
) {
498 ompt_callbacks
.ompt_callback(ompt_callback_thread_begin
)(
499 ompt_thread_initial
, __ompt_get_thread_data_internal());
501 ompt_data_t
*task_data
= nullptr;
502 ompt_data_t
*parallel_data
= nullptr;
503 __ompt_get_task_info_internal(0, NULL
, &task_data
, NULL
, ¶llel_data
,
505 if (ompt_enabled
.ompt_callback_implicit_task
) {
506 ompt_callbacks
.ompt_callback(ompt_callback_implicit_task
)(
507 ompt_scope_begin
, parallel_data
, task_data
, 1, 1, ompt_task_initial
);
510 ompt_set_thread_state(root_thread
, ompt_state_work_serial
);
515 if (ompt_enabled
.enabled
) {
516 if (ompt_start_tool_result
&& ompt_start_tool_result
->finalize
) {
517 ompt_start_tool_result
->finalize(&(ompt_start_tool_result
->tool_data
));
519 if (libomptarget_ompt_result
&& libomptarget_ompt_result
->finalize
) {
520 libomptarget_ompt_result
->finalize(NULL
);
524 if (ompt_tool_module
)
525 OMPT_DLCLOSE(ompt_tool_module
);
526 memset(&ompt_enabled
, 0, sizeof(ompt_enabled
));
529 /*****************************************************************************
530 * interface operations
531 ****************************************************************************/
533 /*****************************************************************************
535 ****************************************************************************/
537 OMPT_API_ROUTINE
int ompt_enumerate_states(int current_state
, int *next_state
,
538 const char **next_state_name
) {
539 const static int len
= sizeof(ompt_state_info
) / sizeof(ompt_state_info_t
);
542 for (i
= 0; i
< len
- 1; i
++) {
543 if (ompt_state_info
[i
].state_id
== current_state
) {
544 *next_state
= ompt_state_info
[i
+ 1].state_id
;
545 *next_state_name
= ompt_state_info
[i
+ 1].state_name
;
553 OMPT_API_ROUTINE
int ompt_enumerate_mutex_impls(int current_impl
,
555 const char **next_impl_name
) {
556 const static int len
=
557 sizeof(kmp_mutex_impl_info
) / sizeof(kmp_mutex_impl_info_t
);
559 for (i
= 0; i
< len
- 1; i
++) {
560 if (kmp_mutex_impl_info
[i
].id
!= current_impl
)
562 *next_impl
= kmp_mutex_impl_info
[i
+ 1].id
;
563 *next_impl_name
= kmp_mutex_impl_info
[i
+ 1].name
;
569 /*****************************************************************************
571 ****************************************************************************/
573 OMPT_API_ROUTINE ompt_set_result_t
ompt_set_callback(ompt_callbacks_t which
,
574 ompt_callback_t callback
) {
577 #define ompt_event_macro(event_name, callback_type, event_id) \
579 ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \
580 ompt_enabled.event_name = (callback != 0); \
582 return ompt_event_implementation_status(event_name); \
584 return ompt_set_always;
586 FOREACH_OMPT_EVENT(ompt_event_macro
)
588 #undef ompt_event_macro
591 return ompt_set_error
;
595 OMPT_API_ROUTINE
int ompt_get_callback(ompt_callbacks_t which
,
596 ompt_callback_t
*callback
) {
597 if (!ompt_enabled
.enabled
)
598 return ompt_get_callback_failure
;
602 #define ompt_event_macro(event_name, callback_type, event_id) \
604 ompt_callback_t mycb = \
605 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \
606 if (ompt_enabled.event_name && mycb) { \
608 return ompt_get_callback_success; \
610 return ompt_get_callback_failure; \
613 FOREACH_OMPT_EVENT(ompt_event_macro
)
615 #undef ompt_event_macro
618 return ompt_get_callback_failure
;
622 /*****************************************************************************
624 ****************************************************************************/
626 OMPT_API_ROUTINE
int ompt_get_parallel_info(int ancestor_level
,
627 ompt_data_t
**parallel_data
,
629 if (!ompt_enabled
.enabled
)
631 return __ompt_get_parallel_info_internal(ancestor_level
, parallel_data
,
635 OMPT_API_ROUTINE
int ompt_get_state(ompt_wait_id_t
*wait_id
) {
636 if (!ompt_enabled
.enabled
)
637 return ompt_state_work_serial
;
638 int thread_state
= __ompt_get_state_internal(wait_id
);
640 if (thread_state
== ompt_state_undefined
) {
641 thread_state
= ompt_state_work_serial
;
647 /*****************************************************************************
649 ****************************************************************************/
651 OMPT_API_ROUTINE ompt_data_t
*ompt_get_thread_data(void) {
652 if (!ompt_enabled
.enabled
)
654 return __ompt_get_thread_data_internal();
657 OMPT_API_ROUTINE
int ompt_get_task_info(int ancestor_level
, int *type
,
658 ompt_data_t
**task_data
,
659 ompt_frame_t
**task_frame
,
660 ompt_data_t
**parallel_data
,
662 if (!ompt_enabled
.enabled
)
664 return __ompt_get_task_info_internal(ancestor_level
, type
, task_data
,
665 task_frame
, parallel_data
, thread_num
);
668 OMPT_API_ROUTINE
int ompt_get_task_memory(void **addr
, size_t *size
,
670 return __ompt_get_task_memory_internal(addr
, size
, block
);
673 /*****************************************************************************
675 ****************************************************************************/
677 OMPT_API_ROUTINE
int ompt_get_num_procs(void) {
678 // copied from kmp_ftn_entry.h (but modified: OMPT can only be called when
679 // runtime is initialized)
680 return __kmp_avail_proc
;
683 /*****************************************************************************
685 ****************************************************************************/
687 OMPT_API_ROUTINE
int ompt_get_num_places(void) {
688 // copied from kmp_ftn_entry.h (but modified)
689 #if !KMP_AFFINITY_SUPPORTED
692 if (!KMP_AFFINITY_CAPABLE())
694 return __kmp_affinity
.num_masks
;
698 OMPT_API_ROUTINE
int ompt_get_place_proc_ids(int place_num
, int ids_size
,
700 // copied from kmp_ftn_entry.h (but modified)
701 #if !KMP_AFFINITY_SUPPORTED
705 int tmp_ids
[ids_size
];
706 for (int j
= 0; j
< ids_size
; j
++)
708 if (!KMP_AFFINITY_CAPABLE())
710 if (place_num
< 0 || place_num
>= (int)__kmp_affinity
.num_masks
)
712 /* TODO: Is this safe for asynchronous call from signal handler during runtime
714 kmp_affin_mask_t
*mask
= KMP_CPU_INDEX(__kmp_affinity
.masks
, place_num
);
716 KMP_CPU_SET_ITERATE(i
, mask
) {
717 if ((!KMP_CPU_ISSET(i
, __kmp_affin_fullMask
)) ||
718 (!KMP_CPU_ISSET(i
, mask
))) {
721 if (count
< ids_size
)
725 if (ids_size
>= count
) {
726 for (i
= 0; i
< count
; i
++) {
734 OMPT_API_ROUTINE
int ompt_get_place_num(void) {
735 // copied from kmp_ftn_entry.h (but modified)
736 #if !KMP_AFFINITY_SUPPORTED
739 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
744 if (!KMP_AFFINITY_CAPABLE())
746 gtid
= __kmp_entry_gtid();
747 thread
= __kmp_thread_from_gtid(gtid
);
748 if (thread
== NULL
|| thread
->th
.th_current_place
< 0)
750 return thread
->th
.th_current_place
;
754 OMPT_API_ROUTINE
int ompt_get_partition_place_nums(int place_nums_size
,
756 // copied from kmp_ftn_entry.h (but modified)
757 #if !KMP_AFFINITY_SUPPORTED
760 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
763 int i
, gtid
, place_num
, first_place
, last_place
, start
, end
;
765 if (!KMP_AFFINITY_CAPABLE())
767 gtid
= __kmp_entry_gtid();
768 thread
= __kmp_thread_from_gtid(gtid
);
771 first_place
= thread
->th
.th_first_place
;
772 last_place
= thread
->th
.th_last_place
;
773 if (first_place
< 0 || last_place
< 0)
775 if (first_place
<= last_place
) {
782 if (end
- start
<= place_nums_size
)
783 for (i
= 0, place_num
= start
; place_num
<= end
; ++place_num
, ++i
) {
784 place_nums
[i
] = place_num
;
786 return end
- start
+ 1;
790 /*****************************************************************************
792 ****************************************************************************/
794 OMPT_API_ROUTINE
int ompt_get_proc_id(void) {
795 if (!ompt_enabled
.enabled
|| __kmp_get_gtid() < 0)
797 #if KMP_HAVE_SCHED_GETCPU
798 return sched_getcpu();
801 GetCurrentProcessorNumberEx(&pn
);
802 return 64 * pn
.Group
+ pn
.Number
;
808 /*****************************************************************************
810 ****************************************************************************/
813 * Currently unused function
814 OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; }
817 /*****************************************************************************
818 * application-facing API
819 ****************************************************************************/
821 /*----------------------------------------------------------------------------
823 ---------------------------------------------------------------------------*/
825 int __kmp_control_tool(uint64_t command
, uint64_t modifier
, void *arg
) {
827 if (ompt_enabled
.enabled
) {
828 if (ompt_enabled
.ompt_callback_control_tool
) {
829 return ompt_callbacks
.ompt_callback(ompt_callback_control_tool
)(
830 command
, modifier
, arg
, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid()));
839 /*****************************************************************************
841 ****************************************************************************/
843 OMPT_API_ROUTINE
uint64_t ompt_get_unique_id(void) {
844 return __ompt_get_unique_id_internal();
847 OMPT_API_ROUTINE
void ompt_finalize_tool(void) { __kmp_internal_end_atexit(); }
849 /*****************************************************************************
851 ****************************************************************************/
853 OMPT_API_ROUTINE
int ompt_get_target_info(uint64_t *device_num
,
854 ompt_id_t
*target_id
,
855 ompt_id_t
*host_op_id
) {
856 return 0; // thread is not in a target region
859 OMPT_API_ROUTINE
int ompt_get_num_devices(void) {
860 return 1; // only one device (the current device) is available
863 /*****************************************************************************
864 * API inquiry for tool
865 ****************************************************************************/
867 static ompt_interface_fn_t
ompt_fn_lookup(const char *s
) {
869 #define ompt_interface_fn(fn) \
870 fn##_t fn##_f = fn; \
871 if (strcmp(s, #fn) == 0) \
872 return (ompt_interface_fn_t)fn##_f;
874 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn
)
876 #undef ompt_interface_fn
881 static ompt_data_t
*ompt_get_task_data() { return __ompt_get_task_data(); }
883 static ompt_data_t
*ompt_get_target_task_data() {
884 return __ompt_get_target_task_data();
887 /// Lookup function to query libomp callbacks registered by the tool
888 static ompt_interface_fn_t
ompt_libomp_target_fn_lookup(const char *s
) {
889 #define provide_fn(fn) \
890 if (strcmp(s, #fn) == 0) \
891 return (ompt_interface_fn_t)fn;
893 provide_fn(ompt_get_callback
);
894 provide_fn(ompt_get_task_data
);
895 provide_fn(ompt_get_target_task_data
);
898 #define ompt_interface_fn(fn, type, code) \
899 if (strcmp(s, #fn) == 0) \
900 return (ompt_interface_fn_t)ompt_callbacks.ompt_callback(fn);
902 FOREACH_OMPT_DEVICE_EVENT(ompt_interface_fn
)
903 FOREACH_OMPT_EMI_EVENT(ompt_interface_fn
)
904 FOREACH_OMPT_NOEMI_EVENT(ompt_interface_fn
)
905 #undef ompt_interface_fn
907 return (ompt_interface_fn_t
)0;
910 /// This function is called by the libomptarget connector to assign
911 /// callbacks already registered with libomp.
912 _OMP_EXTERN
void ompt_libomp_connect(ompt_start_tool_result_t
*result
) {
913 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Enter ompt_libomp_connect\n");
915 // Ensure libomp callbacks have been added if not already
916 __ompt_force_initialization();
918 if (ompt_enabled
.enabled
&&
919 // Callbacks are initiated only if the device initialize callback
920 // has been registered by the tool
921 ompt_callbacks
.ompt_callback(ompt_callback_device_initialize
)) {
923 OMPT_VERBOSE_INIT_PRINT(
924 "libomp --> OMPT: Connecting with libomptarget\n");
925 // Pass in the libomp lookup function so that the already registered
926 // functions can be extracted and assigned to the callbacks in
928 result
->initialize(ompt_libomp_target_fn_lookup
,
929 /* initial_device_num */ 0, /* tool_data */ nullptr);
930 // Track the object provided by libomptarget so that the finalizer can be
931 // called during OMPT finalization
932 libomptarget_ompt_result
= result
;
935 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Exit ompt_libomp_connect\n");