LLVM OpenMP 22.0.0git
ompt-general.cpp
Go to the documentation of this file.
1/*
2 * ompt-general.cpp -- OMPT implementation of interface functions
3 */
4
5//===----------------------------------------------------------------------===//
6//
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
10//
11//===----------------------------------------------------------------------===//
12
13#include "kmp_utils.h"
14
15/*****************************************************************************
16 * system include files
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// 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(...) \
54 if (verbose_init) \
55 fprintf(verbose_file, __VA_ARGS__)
56#define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...) \
57 if (verbose_init) \
58 fprintf(verbose_file, __VA_ARGS__)
59
60static FILE *verbose_file;
61static int verbose_init;
62
63/*****************************************************************************
64 * types
65 ****************************************************************************/
66
67typedef struct {
68 const char *state_name;
69 ompt_state_t state_id;
71
72typedef struct {
73 const char *name;
74 kmp_mutex_impl_t id;
76
82};
83
84/*****************************************************************************
85 * global variables
86 ****************************************************************************/
87
89
91#define ompt_state_macro(state, code) {#state, state},
92 FOREACH_OMPT_STATE(ompt_state_macro)
93#undef ompt_state_macro
94};
95
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
100};
101
103
105
106#if KMP_OS_WINDOWS
107static HMODULE ompt_tool_module = NULL;
108static HMODULE ompt_archer_module = NULL;
109#define OMPT_DLCLOSE(Lib) FreeLibrary(Lib)
110#else
111static void *ompt_tool_module = NULL;
112static void *ompt_archer_module = NULL;
113#define OMPT_DLCLOSE(Lib) dlclose(Lib)
114#endif
115
116/// Used to track the initializer and the finalizer provided by libomptarget
118
119/*****************************************************************************
120 * forward declarations
121 ****************************************************************************/
122
123static ompt_interface_fn_t ompt_fn_lookup(const char *s);
124
125OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void);
126
127/*****************************************************************************
128 * initialization and finalization (private operations)
129 ****************************************************************************/
130
131typedef ompt_start_tool_result_t *(*ompt_start_tool_t)(unsigned int,
132 const char *);
133
134#if KMP_OS_DARWIN
135
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.
139//
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.
144
145static ompt_start_tool_result_t *ompt_tool_darwin(unsigned int omp_version,
146 const char *runtime_version) {
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");
151 if (start_tool) {
152 ret = start_tool(omp_version, runtime_version);
153 }
154 return ret;
155}
156
157#elif OMPT_HAVE_WEAK_ATTRIBUTE
158
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.
162
164ompt_start_tool(unsigned int omp_version, const char *runtime_version) {
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");
172 if (next_tool) {
173 ret = next_tool(omp_version, runtime_version);
174 }
175 return ret;
176}
177
178#elif OMPT_HAVE_PSAPI
179
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.
184
185#include <psapi.h>
186#pragma comment(lib, "psapi.lib")
187
188// The number of loaded modules to start enumeration with EnumProcessModules()
189#define NUM_MODULES 128
190
192ompt_tool_windows(unsigned int omp_version, const char *runtime_version) {
193 int i;
194 DWORD needed, new_size;
195 HMODULE *modules;
196 HANDLE process = GetCurrentProcess();
197 modules = (HMODULE *)malloc(NUM_MODULES * sizeof(HMODULE));
198 ompt_start_tool_t ompt_tool_p = NULL;
199
200#if OMPT_DEBUG
201 printf("ompt_tool_windows(): looking for ompt_start_tool\n");
202#endif
203 if (!EnumProcessModules(process, modules, NUM_MODULES * sizeof(HMODULE),
204 &needed)) {
205 // Regardless of the error reason use the stub initialization function
206 free(modules);
207 return NULL;
208 }
209 // Check if NUM_MODULES is enough to list all modules
210 new_size = needed / sizeof(HMODULE);
211 if (new_size > NUM_MODULES) {
212#if OMPT_DEBUG
213 printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed);
214#endif
215 modules = (HMODULE *)realloc(modules, needed);
216 // If resizing failed use the stub function.
217 if (!EnumProcessModules(process, modules, needed, &needed)) {
218 free(modules);
219 return NULL;
220 }
221 }
222 for (i = 0; i < new_size; ++i) {
223 (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_start_tool");
224 if (ompt_tool_p) {
225#if OMPT_DEBUG
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",
229 modName);
230#endif
231 free(modules);
232 return (*ompt_tool_p)(omp_version, runtime_version);
233 }
234#if OMPT_DEBUG
235 else {
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",
239 modName);
240 }
241#endif
242 }
243 free(modules);
244 return NULL;
245}
246#else
247#error Activation of OMPT is not supported on this platform.
248#endif
249
251ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) {
253 ompt_start_tool_t start_tool = NULL;
254#if KMP_OS_WINDOWS
255 // Cannot use colon to describe a list of absolute paths on Windows
256 const char *sep = ";";
257#else
258 const char *sep = ":";
259#endif
260
261 OMPT_VERBOSE_INIT_PRINT("----- START LOGGING OF TOOL REGISTRATION -----\n");
262 OMPT_VERBOSE_INIT_PRINT("Search for OMP tool in current address space... ");
263
264#if KMP_OS_DARWIN
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);
271#else
272#error Activation of OMPT is not supported on this platform.
273#endif
274 if (ret) {
277 "Tool was started and is using the OMPT interface.\n");
278 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
279 return ret;
280 }
281
282 // Try tool-libraries-var ICV
284 const char *tool_libs = getenv("OMP_TOOL_LIBRARIES");
285 if (tool_libs) {
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);
289 char *buf;
290 char *fname = __kmp_str_token(libs, sep, &buf);
291 // Reset dl-error
292 dlerror();
293
294 while (fname) {
295#if KMP_OS_UNIX
296 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname);
297 void *h = dlopen(fname, RTLD_LAZY);
298 if (!h) {
299 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
300 } else {
302 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
303 fname);
304 dlerror(); // Clear any existing error
305 start_tool = (ompt_start_tool_t)dlsym(h, "ompt_start_tool");
306 if (!start_tool) {
307 char *error = dlerror();
308 if (error != NULL) {
309 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", error);
310 } else {
312 "ompt_start_tool = NULL");
313 }
314 } else
315#elif KMP_OS_WINDOWS
316 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname);
317 HMODULE h = LoadLibrary(fname);
318 if (!h) {
319 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
320 (unsigned)GetLastError());
321 } else {
323 OMPT_VERBOSE_INIT_PRINT("Searching for ompt_start_tool in %s... ",
324 fname);
325 start_tool = (ompt_start_tool_t)GetProcAddress(h, "ompt_start_tool");
326 if (!start_tool) {
327 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: Error %u\n",
328 (unsigned)GetLastError());
329 } else
330#else
331#error Activation of OMPT is not supported on this platform.
332#endif
333 { // if (start_tool)
334 ret = (*start_tool)(omp_version, runtime_version);
335 if (ret) {
338 "Tool was started and is using the OMPT interface.\n");
340 break;
341 }
343 "Found but not using the OMPT interface.\n");
344 OMPT_VERBOSE_INIT_PRINT("Continuing search...\n");
345 }
347 }
348 fname = __kmp_str_token(NULL, sep, &buf);
349 }
350 __kmp_str_free(&libs);
351 } else {
352 OMPT_VERBOSE_INIT_PRINT("No OMP_TOOL_LIBRARIES defined.\n");
353 }
354
355 // usable tool found in tool-libraries
356 if (ret) {
357 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
358 return ret;
359 }
360
361#if KMP_OS_UNIX
362 { // Non-standard: load archer tool if application is built with TSan
363 const char *fname = "libarcher.so";
365 "...searching tool libraries failed. Using archer tool.\n");
366 OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname);
367 void *h = dlopen(fname, RTLD_LAZY);
368 if (h) {
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");
372 if (start_tool) {
373 ret = (*start_tool)(omp_version, runtime_version);
374 if (ret) {
377 "Tool was started and is using the OMPT interface.\n");
379 "----- END LOGGING OF TOOL REGISTRATION -----\n");
381 return ret;
382 }
384 "Found but not using the OMPT interface.\n");
385 } else {
386 OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
387 }
389 }
390 }
391#endif
392 OMPT_VERBOSE_INIT_PRINT("No OMP tool loaded.\n");
393 OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF TOOL REGISTRATION -----\n");
394 return ret;
395}
396
398 //--------------------------------------------------
399 // Execute the pre-initialization logic only once.
400 //--------------------------------------------------
401 static int ompt_pre_initialized = 0;
402
403 if (ompt_pre_initialized)
404 return;
405
406 ompt_pre_initialized = 1;
407
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;
413
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;
420
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")) {
426 verbose_init = 1;
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;
431 else
432 verbose_file = fopen(ompt_env_verbose_init, "w");
433 } else
434 verbose_init = 0;
435
436#if OMPT_DEBUG
437 printf("ompt_pre_init(): tool_setting = %d\n", tool_setting);
438#endif
439 switch (tool_setting) {
441 OMPT_VERBOSE_INIT_PRINT("OMP tool disabled. \n");
442 break;
443
444 case omp_tool_unset:
445 case omp_tool_enabled:
446
447 //--------------------------------------------------
448 // Load tool iff specified in environment variable
449 //--------------------------------------------------
451 ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version());
452
453 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
454 break;
455
456 case omp_tool_error:
457 fprintf(stderr,
458 "Warning: OMP_TOOL has invalid value \"%s\".\n"
459 " legal values are (NULL,\"\",\"disabled\","
460 "\"enabled\").\n",
461 ompt_env_var);
462 break;
463 }
464 if (verbose_init && verbose_file != stderr && verbose_file != stdout)
465 fclose(verbose_file);
466#if OMPT_DEBUG
467 printf("ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled.enabled);
468#endif
469}
470
471extern "C" int omp_get_initial_device(void);
472
474 //--------------------------------------------------
475 // Execute the post-initialization logic only once.
476 //--------------------------------------------------
477 static int ompt_post_initialized = 0;
478
479 if (ompt_post_initialized)
480 return;
481
482 ompt_post_initialized = 1;
483
484 //--------------------------------------------------
485 // Initialize the tool if so indicated.
486 //--------------------------------------------------
490 &(ompt_start_tool_result->tool_data));
491
492 if (!ompt_enabled.enabled) {
493 // tool not enabled, zero out the bitmap, and done
494 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
495 return;
496 }
497
498 kmp_info_t *root_thread = ompt_get_thread();
499
500 ompt_set_thread_state(root_thread, ompt_state_overhead);
501 __ompt_task_init(root_thread->th.th_current_task, 0);
502
503 if (ompt_enabled.ompt_callback_thread_begin) {
504 ompt_callbacks.ompt_callback(ompt_callback_thread_begin)(
505 ompt_thread_initial, __ompt_get_thread_data_internal());
506 }
507 ompt_data_t *task_data = nullptr;
508 ompt_data_t *parallel_data = nullptr;
509 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, &parallel_data,
510 NULL);
511 if (ompt_enabled.ompt_callback_implicit_task) {
512 ompt_callbacks.ompt_callback(ompt_callback_implicit_task)(
513 ompt_scope_begin, parallel_data, task_data, 1, 1, ompt_task_initial);
514 }
515
516 ompt_set_thread_state(root_thread, ompt_state_work_serial);
517 }
518}
519
520void ompt_fini() {
521 if (ompt_enabled.enabled) {
523 ompt_start_tool_result->finalize(&(ompt_start_tool_result->tool_data));
524 }
526 libomptarget_ompt_result->finalize(NULL);
527 }
528 }
529
534 memset(&ompt_enabled, 0, sizeof(ompt_enabled));
535}
536
537/*****************************************************************************
538 * interface operations
539 ****************************************************************************/
540
541/*****************************************************************************
542 * state
543 ****************************************************************************/
544
545OMPT_API_ROUTINE int ompt_enumerate_states(int current_state, int *next_state,
546 const char **next_state_name) {
547 const static int len = sizeof(ompt_state_info) / sizeof(ompt_state_info_t);
548 int i = 0;
549
550 for (i = 0; i < len - 1; i++) {
551 if (ompt_state_info[i].state_id == current_state) {
552 *next_state = ompt_state_info[i + 1].state_id;
553 *next_state_name = ompt_state_info[i + 1].state_name;
554 return 1;
555 }
556 }
557
558 return 0;
559}
560
562 int *next_impl,
563 const char **next_impl_name) {
564 const static int len =
566 int i = 0;
567 for (i = 0; i < len - 1; i++) {
568 if (kmp_mutex_impl_info[i].id != current_impl)
569 continue;
570 *next_impl = kmp_mutex_impl_info[i + 1].id;
571 *next_impl_name = kmp_mutex_impl_info[i + 1].name;
572 return 1;
573 }
574 return 0;
575}
576
577/*****************************************************************************
578 * callbacks
579 ****************************************************************************/
580
581OMPT_API_ROUTINE ompt_set_result_t ompt_set_callback(ompt_callbacks_t which,
582 ompt_callback_t callback) {
583 switch (which) {
584
585#define ompt_event_macro(event_name, callback_type, event_id) \
586 case event_name: \
587 ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \
588 ompt_enabled.event_name = (callback != 0); \
589 if (callback) \
590 return ompt_event_implementation_status(event_name); \
591 else \
592 return ompt_set_always;
593
594 FOREACH_OMPT_EVENT(ompt_event_macro)
595
596#undef ompt_event_macro
597
598 default:
599 return ompt_set_error;
600 }
601}
602
603OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which,
604 ompt_callback_t *callback) {
607
608 switch (which) {
609
610#define ompt_event_macro(event_name, callback_type, event_id) \
611 case event_name: { \
612 ompt_callback_t mycb = \
613 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \
614 if (ompt_enabled.event_name && mycb) { \
615 *callback = mycb; \
616 return ompt_get_callback_success; \
617 } \
618 return ompt_get_callback_failure; \
619 }
620
621 FOREACH_OMPT_EVENT(ompt_event_macro)
622
623#undef ompt_event_macro
624
625 default:
627 }
628}
629
630/*****************************************************************************
631 * parallel regions
632 ****************************************************************************/
633
635 ompt_data_t **parallel_data,
636 int *team_size) {
638 return 0;
639 return __ompt_get_parallel_info_internal(ancestor_level, parallel_data,
640 team_size);
641}
642
643OMPT_API_ROUTINE int ompt_get_state(ompt_wait_id_t *wait_id) {
645 return ompt_state_work_serial;
646 int thread_state = __ompt_get_state_internal(wait_id);
647
648 if (thread_state == ompt_state_undefined) {
649 thread_state = ompt_state_work_serial;
650 }
651
652 return thread_state;
653}
654
655/*****************************************************************************
656 * tasks
657 ****************************************************************************/
658
661 return NULL;
663}
664
665OMPT_API_ROUTINE int ompt_get_task_info(int ancestor_level, int *type,
666 ompt_data_t **task_data,
667 ompt_frame_t **task_frame,
668 ompt_data_t **parallel_data,
669 int *thread_num) {
671 return 0;
672 return __ompt_get_task_info_internal(ancestor_level, type, task_data,
673 task_frame, parallel_data, thread_num);
674}
675
677 int block) {
679}
680
681/*****************************************************************************
682 * num_procs
683 ****************************************************************************/
684
686 // copied from kmp_ftn_entry.h (but modified: OMPT can only be called when
687 // runtime is initialized)
688 return __kmp_avail_proc;
689}
690
691/*****************************************************************************
692 * places
693 ****************************************************************************/
694
696// copied from kmp_ftn_entry.h (but modified)
697#if !KMP_AFFINITY_SUPPORTED
698 return 0;
699#else
700 if (!KMP_AFFINITY_CAPABLE())
701 return 0;
702 return __kmp_affinity.num_masks;
703#endif
704}
705
706OMPT_API_ROUTINE int ompt_get_place_proc_ids(int place_num, int ids_size,
707 int *ids) {
708// copied from kmp_ftn_entry.h (but modified)
709#if !KMP_AFFINITY_SUPPORTED
710 return 0;
711#else
712 int i, count;
713 SimpleVLA<int> tmp_ids(ids_size);
714 for (int j = 0; j < ids_size; j++)
715 tmp_ids[j] = 0;
716 if (!KMP_AFFINITY_CAPABLE())
717 return 0;
718 if (place_num < 0 || place_num >= (int)__kmp_affinity.num_masks)
719 return 0;
720 /* TODO: Is this safe for asynchronous call from signal handler during runtime
721 * shutdown? */
722 kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity.masks, place_num);
723 count = 0;
724 KMP_CPU_SET_ITERATE(i, mask) {
725 if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
726 (!KMP_CPU_ISSET(i, mask))) {
727 continue;
728 }
729 if (count < ids_size)
730 tmp_ids[count] = i;
731 count++;
732 }
733 if (ids_size >= count) {
734 for (i = 0; i < count; i++) {
735 ids[i] = tmp_ids[i];
736 }
737 }
738 return count;
739#endif
740}
741
743// copied from kmp_ftn_entry.h (but modified)
744#if !KMP_AFFINITY_SUPPORTED
745 return -1;
746#else
747 if (!ompt_enabled.enabled || __kmp_get_gtid() < 0)
748 return -1;
749
750 int gtid;
751 kmp_info_t *thread;
752 if (!KMP_AFFINITY_CAPABLE())
753 return -1;
754 gtid = __kmp_entry_gtid();
755 thread = __kmp_thread_from_gtid(gtid);
756 if (thread == NULL || thread->th.th_current_place < 0)
757 return -1;
758 return thread->th.th_current_place;
759#endif
760}
761
763 int *place_nums) {
764// copied from kmp_ftn_entry.h (but modified)
765#if !KMP_AFFINITY_SUPPORTED
766 return 0;
767#else
768 if (!ompt_enabled.enabled || __kmp_get_gtid() < 0)
769 return 0;
770
771 int i, gtid, place_num, first_place, last_place, start, end;
772 kmp_info_t *thread;
773 if (!KMP_AFFINITY_CAPABLE())
774 return 0;
775 gtid = __kmp_entry_gtid();
776 thread = __kmp_thread_from_gtid(gtid);
777 if (thread == NULL)
778 return 0;
779 first_place = thread->th.th_first_place;
780 last_place = thread->th.th_last_place;
781 if (first_place < 0 || last_place < 0)
782 return 0;
783 if (first_place <= last_place) {
784 start = first_place;
785 end = last_place;
786 } else {
787 start = last_place;
788 end = first_place;
789 }
790 if (end - start <= place_nums_size)
791 for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
792 place_nums[i] = place_num;
793 }
794 return end - start + 1;
795#endif
796}
797
798/*****************************************************************************
799 * places
800 ****************************************************************************/
801
803 if (!ompt_enabled.enabled || __kmp_get_gtid() < 0)
804 return -1;
805#if KMP_HAVE_SCHED_GETCPU
806 return sched_getcpu();
807#elif KMP_OS_WINDOWS
808 PROCESSOR_NUMBER pn;
809 GetCurrentProcessorNumberEx(&pn);
810 return 64 * pn.Group + pn.Number;
811#else
812 return -1;
813#endif
814}
815
816/*****************************************************************************
817 * compatability
818 ****************************************************************************/
819
820/*
821 * Currently unused function
822OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; }
823*/
824
825/*****************************************************************************
826 * application-facing API
827 ****************************************************************************/
828
829/*----------------------------------------------------------------------------
830 | control
831 ---------------------------------------------------------------------------*/
832
833int __kmp_control_tool(uint64_t command, uint64_t modifier, void *arg) {
834
835 if (ompt_enabled.enabled) {
836 if (ompt_enabled.ompt_callback_control_tool) {
837 return ompt_callbacks.ompt_callback(ompt_callback_control_tool)(
838 command, modifier, arg, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid()));
839 } else {
840 return -1;
841 }
842 } else {
843 return -2;
844 }
845}
846
847/*****************************************************************************
848 * misc
849 ****************************************************************************/
850
853}
854
856
857/*****************************************************************************
858 * Target
859 ****************************************************************************/
860
861OMPT_API_ROUTINE int ompt_get_target_info(uint64_t *device_num,
862 ompt_id_t *target_id,
863 ompt_id_t *host_op_id) {
864 return 0; // thread is not in a target region
865}
866
868 return 1; // only one device (the current device) is available
869}
870
871/*****************************************************************************
872 * API inquiry for tool
873 ****************************************************************************/
874
875static ompt_interface_fn_t ompt_fn_lookup(const char *s) {
876
877#define ompt_interface_fn(fn) \
878 fn##_t fn##_f = fn; \
879 if (strcmp(s, #fn) == 0) \
880 return (ompt_interface_fn_t)fn##_f;
881
882 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn)
883
884#undef ompt_interface_fn
885
886 return NULL;
887}
888
889static ompt_data_t *ompt_get_task_data() { return __ompt_get_task_data(); }
890
891static ompt_data_t *ompt_get_target_task_data() {
893}
894
895/// Lookup function to query libomp callbacks registered by the tool
896static ompt_interface_fn_t ompt_libomp_target_fn_lookup(const char *s) {
897#define provide_fn(fn) \
898 if (strcmp(s, #fn) == 0) \
899 return (ompt_interface_fn_t)fn;
900
904#undef provide_fn
905
906#define ompt_interface_fn(fn, type, code) \
907 if (strcmp(s, #fn) == 0) \
908 return (ompt_interface_fn_t)ompt_callbacks.ompt_callback(fn);
909
910 FOREACH_OMPT_DEVICE_EVENT(ompt_interface_fn)
911 FOREACH_OMPT_EMI_EVENT(ompt_interface_fn)
912 FOREACH_OMPT_NOEMI_EVENT(ompt_interface_fn)
913#undef ompt_interface_fn
914
915 return (ompt_interface_fn_t)0;
916}
917
918/// This function is called by the libomptarget connector to assign
919/// callbacks already registered with libomp.
921 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Enter ompt_libomp_connect\n");
922
923 // Ensure libomp callbacks have been added if not already
925
926 if (ompt_enabled.enabled && result) {
927 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Connecting with libomptarget\n");
928 // Pass in the libomp lookup function so that the already registered
929 // functions can be extracted and assigned to the callbacks in
930 // libomptarget
932 /* initial_device_num */ 0, /* tool_data */ nullptr);
933 // Track the object provided by libomptarget so that the finalizer can be
934 // called during OMPT finalization
936 }
937 OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Exit ompt_libomp_connect\n");
938}
char buf[BUFFER_SIZE]
static ompt_get_task_info_t ompt_get_task_info
Definition: callback.h:156
static ompt_enumerate_states_t ompt_enumerate_states
Definition: callback.h:168
static ompt_get_callback_t ompt_get_callback
Definition: callback.h:154
static ompt_get_place_proc_ids_t ompt_get_place_proc_ids
Definition: callback.h:164
static ompt_set_callback_t ompt_set_callback
Definition: callback.h:153
static ompt_get_partition_place_nums_t ompt_get_partition_place_nums
Definition: callback.h:166
static ompt_get_task_memory_t ompt_get_task_memory
Definition: callback.h:157
static ompt_get_state_t ompt_get_state
Definition: callback.h:155
static ompt_get_parallel_info_t ompt_get_parallel_info
Definition: callback.h:159
static ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls
Definition: callback.h:169
int result[2]
A simple pure header implementation of VLA that aims to replace uses of actual VLA,...
Definition: kmp_utils.h:26
void const char const char int ITT_FORMAT __itt_group_sync s
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t new_size
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int mask
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp end
void * addr
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
void __kmp_internal_end_atexit(void)
#define __kmp_entry_gtid()
Definition: kmp.h:3601
#define __kmp_get_gtid()
Definition: kmp.h:3600
int __kmp_avail_proc
Definition: kmp_global.cpp:123
static kmp_info_t * __kmp_thread_from_gtid(int gtid)
Definition: kmp.h:3634
union KMP_ALIGN_CACHE kmp_info kmp_info_t
char * __kmp_str_format(char const *format,...)
Definition: kmp_str.cpp:448
char * __kmp_str_token(char *str, char const *delim, char **buf)
Definition: kmp_str.cpp:595
void __kmp_str_free(char **str)
Definition: kmp_str.cpp:494
#define i
Definition: kmp_stub.cpp:87
struct ompt_start_tool_result_t ompt_start_tool_result_t
int const __kmp_openmp_version
Definition: kmp_version.cpp:97
static int verbose_init
static FILE * verbose_file
void ompt_fini()
_OMP_EXTERN void ompt_libomp_connect(ompt_start_tool_result_t *result)
This function is called by the libomptarget connector to assign callbacks already registered with lib...
kmp_mutex_impl_info_t kmp_mutex_impl_info[]
ompt_callbacks_active_t ompt_enabled
#define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...)
#define ompt_interface_fn(fn)
#define kmp_mutex_impl_macro(name, id)
#define provide_fn(fn)
#define ompt_state_macro(state, code)
static ompt_start_tool_result_t * ompt_try_start_tool(unsigned int omp_version, const char *runtime_version)
return ret
#define OMPT_STR_MATCH(haystack, needle)
static ompt_data_t * ompt_get_target_task_data()
OMPT_API_ROUTINE int ompt_get_num_devices(void)
static void * ompt_tool_module
#define OMPT_VERBOSE_INIT_PRINT(...)
static void * ompt_archer_module
ompt_state_info_t ompt_state_info[]
OMPT_API_ROUTINE int ompt_get_proc_id(void)
int omp_get_initial_device(void)
int __kmp_control_tool(uint64_t command, uint64_t modifier, void *arg)
static ompt_interface_fn_t ompt_fn_lookup(const char *s)
#define OMPT_API_ROUTINE
#define OMPT_DLCLOSE(Lib)
static ompt_start_tool_result_t * libomptarget_ompt_result
Used to track the initializer and the finalizer provided by libomptarget.
void ompt_pre_init()
OMPT_API_ROUTINE int ompt_get_num_places(void)
static ompt_interface_fn_t ompt_libomp_target_fn_lookup(const char *s)
Lookup function to query libomp callbacks registered by the tool.
#define ompt_get_callback_failure
static ompt_data_t * ompt_get_task_data()
tool_setting_e
@ omp_tool_error
@ omp_tool_enabled
@ omp_tool_unset
@ omp_tool_disabled
OMPT_API_ROUTINE void ompt_finalize_tool(void)
OMPT_API_ROUTINE ompt_data_t * ompt_get_thread_data(void)
static ompt_start_tool_result_t * ompt_start_tool_result
#define ompt_event_macro(event_name, callback_type, event_id)
ompt_start_tool_result_t *(* ompt_start_tool_t)(unsigned int, const char *)
OMPT_API_ROUTINE uint64_t ompt_get_unique_id(void)
OMPT_API_ROUTINE int ompt_get_target_info(uint64_t *device_num, ompt_id_t *target_id, ompt_id_t *host_op_id)
void ompt_post_init()
ompt_callbacks_internal_t ompt_callbacks
OMPT_API_ROUTINE int ompt_get_num_procs(void)
OMPT_API_ROUTINE int ompt_get_place_num(void)
#define _OMP_EXTERN
Definition: ompt-internal.h:21
#define ompt_start_tool
#define OMPT_WEAK_ATTRIBUTE
int __ompt_get_task_memory_internal(void **addr, size_t *size, int blocknum)
int __ompt_get_state_internal(ompt_wait_id_t *omp_wait_id)
ompt_data_t * __ompt_get_target_task_data()
int __ompt_get_task_info_internal(int ancestor_level, int *type, ompt_data_t **task_data, ompt_frame_t **task_frame, ompt_data_t **parallel_data, int *thread_num)
ompt_data_t * __ompt_get_task_data()
static uint64_t __ompt_get_unique_id_internal()
void __ompt_force_initialization()
ompt_data_t * __ompt_get_thread_data_internal()
int __ompt_get_parallel_info_internal(int ancestor_level, ompt_data_t **parallel_data, int *team_size)
kmp_mutex_impl_t id
ompt_state_t state_id
const char * state_name