Skip to content

Commit 820be30

Browse files
committed
[OpenMP][OMPT] Introduce VERBOSE_INIT in ompt-multiplex.h
OpenMP 5.1 added OMP_TOOL_VERBOSE_INIT. This env variable is extremely helpful to understand the issue when loading a tool fails unexpectedly (e.g., errors from dlopen, when the libc available at runtime is older than libc used at compile time of the tool -> missed to load the right gcc module). This patch replicates the verbose init code from libomp watching out for a different env variable. Similar to CLIENT_TOOL_LIBRARIES_VAR, a tool can define the name of the env var by defining CLIENT_TOOL_VERBOSE_INIT_VAR before including ompt-multiplex.h. Alternatively, a tool can define OMPT_MULTIPLEX_TOOL_NAME to specify the tool name which will be the prefix for both _TOOL_LIBRARIES and _VERBOSE_INIT var. Finally, if none of the two macros is defined, the header will print a compiler warning and look at OMP_TOOL_VERBOSE_INIT. Patch prepared by Semih Burak Differential Revision: https://reviews.llvm.org/D112809
1 parent cec33fc commit 820be30

File tree

2 files changed

+116
-9
lines changed

2 files changed

+116
-9
lines changed

openmp/tools/multiplex/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,16 @@ Either build llvm and find lit+FileCheck in build directory of llvm or install u
2929
Code of first tool must include the following with the convention, that the environment variable containing the path to the client tool is the tool name with the suffix "_TOOL_LIBRARIES":
3030
```
3131
#define CLIENT_TOOL_LIBRARIES_VAR "EXAMPLE_TOOL_LIBRARIES"
32+
#define CLIENT_TOOL_VERBOSE_INIT_VAR "EXAMPLE_TOOL_VERBOSE_INIT"
3233
#include <ompt-multiplex.h>
3334
```
35+
Alternatively, the name of the tool can be set as a prefix for both variables:
36+
```
37+
#define OMPT_MULTIPLEX_TOOL_NAME "EXAMPLE"
38+
#include <ompt-multiplex.h>
39+
```
40+
This define will have the same effect as to two defines above.
41+
3442
Note that functions and variables with prefix "ompt_multiplex" are reserved by the tool
3543

3644

@@ -50,7 +58,7 @@ To reduce the amount of memory allocations, the user can define macros before in
5058
#define OMPT_MULTIPLEX_CUSTOM_GET_CLIENT_TASK_DATA get_client_task_data
5159
```
5260

53-
This will reverse the calling order of the current tool and its client. In order to avoid this, one can specify a custom delete handler as well:
61+
This will reverse the calling order of the current tool and its client for clean-up events. In order to avoid this, one can specify a custom delete handler as well:
5462

5563
```
5664
#define OMPT_MULTIPLEX_CUSTOM_DELETE_THREAD_DATA delete_thread_data

openmp/tools/multiplex/ompt-multiplex.h

Lines changed: 107 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ static ompt_get_task_info_t ompt_multiplex_get_task_info;
3333
static ompt_get_thread_data_t ompt_multiplex_get_thread_data;
3434
static ompt_get_parallel_info_t ompt_multiplex_get_parallel_info;
3535

36+
// If OMPT_MULTIPLEX_TOOL_NAME is defined, use the tool name as prefix
37+
// contains name of the environment var in which the tool path is specified
38+
// for TOOL_LIBRARIES and VERBOSE_INIT variables. Only overwrite, if
39+
// they are not explicitly defined.
40+
#ifdef OMPT_MULTIPLEX_TOOL_NAME
41+
#ifndef CLIENT_TOOL_LIBRARIES_VAR
42+
#define CLIENT_TOOL_LIBRARIES_VAR OMPT_MULTIPLEX_TOOL_NAME "_TOOL_LIBRARIES"
43+
#endif
44+
#ifndef CLIENT_TOOL_VERBOSE_INIT_VAR
45+
#define CLIENT_TOOL_VERBOSE_INIT_VAR \
46+
OMPT_MULTIPLEX_TOOL_NAME "_TOOL_VERBOSE_INIT"
47+
#endif
48+
#endif
49+
50+
// If CLIENT_TOOL_VERBOSE_INIT_VAR is still not defined, use the OMPT
51+
// env var.
52+
#ifndef CLIENT_TOOL_VERBOSE_INIT_VAR
53+
#warning CLIENT_TOOL_VERBOSE_INIT_VAR redefined to OMP_TOOL_VERBOSE_INIT
54+
#define CLIENT_TOOL_VERBOSE_INIT_VAR "OMP_TOOL_VERBOSE_INIT"
55+
#endif
56+
3657
// contains name of the environment var in which the tool path is specified
3758
#ifndef CLIENT_TOOL_LIBRARIES_VAR
3859
#error CLIENT_TOOL_LIBRARIES_VAR should be defined before including of ompt-multiplex.h
@@ -55,6 +76,47 @@ static ompt_get_parallel_info_t ompt_multiplex_get_parallel_info;
5576

5677
#define OMPT_API_ROUTINE static
5778

79+
#ifndef OMPT_STR_MATCH
80+
#define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))
81+
#endif
82+
83+
// prints for an enabled OMP_TOOL_VERBOSE_INIT.
84+
// In the future a prefix could be added in the first define, the second define
85+
// omits the prefix to allow for continued lines. Example: "PREFIX: Start
86+
// tool... Success." instead of "PREFIX: Start tool... PREFIX: Success."
87+
#define OMPT_VERBOSE_INIT_PRINT(...) \
88+
if (verbose_init) \
89+
fprintf(verbose_file, __VA_ARGS__)
90+
#define OMPT_VERBOSE_INIT_CONTINUED_PRINT(...) \
91+
if (verbose_init) \
92+
fprintf(verbose_file, __VA_ARGS__)
93+
94+
static FILE *verbose_file;
95+
static int verbose_init;
96+
97+
void setup_verbose_init() {
98+
const char *ompt_env_verbose_init = getenv(CLIENT_TOOL_VERBOSE_INIT_VAR);
99+
// possible options: disabled | stdout | stderr | <filename>
100+
// if set, not empty and not disabled -> prepare for logging
101+
if (ompt_env_verbose_init && strcmp(ompt_env_verbose_init, "") &&
102+
!OMPT_STR_MATCH(ompt_env_verbose_init, "disabled")) {
103+
verbose_init = 1;
104+
if (OMPT_STR_MATCH(ompt_env_verbose_init, "STDERR"))
105+
verbose_file = stderr;
106+
else if (OMPT_STR_MATCH(ompt_env_verbose_init, "STDOUT"))
107+
verbose_file = stdout;
108+
else if (!OMPT_STR_MATCH(ompt_env_verbose_init,
109+
getenv("OMP_TOOL_VERBOSE_INIT")))
110+
verbose_file = fopen(ompt_env_verbose_init, "w");
111+
else {
112+
verbose_init = 0;
113+
printf("Multiplex: Can not open file defined in OMP_TOOL_VERBOSE_INIT "
114+
"twice.");
115+
}
116+
} else
117+
verbose_init = 0;
118+
}
119+
58120
#define OMPT_LOAD_CLIENT_FOREACH_OMPT_EVENT(macro) \
59121
macro(callback_thread_begin, ompt_callback_thread_begin_t, 1); \
60122
macro(callback_thread_end, ompt_callback_thread_end_t, 2); \
@@ -105,8 +167,8 @@ typedef struct ompt_multiplex_callback_implementation_status_s {
105167
#undef ompt_event_macro
106168
} ompt_multiplex_callback_implementation_status_t;
107169

108-
ompt_start_tool_result_t *ompt_multiplex_own_fns;
109-
ompt_start_tool_result_t *ompt_multiplex_client_fns;
170+
ompt_start_tool_result_t *ompt_multiplex_own_fns = NULL;
171+
ompt_start_tool_result_t *ompt_multiplex_client_fns = NULL;
110172
ompt_function_lookup_t ompt_multiplex_lookup_function;
111173
ompt_multiplex_callbacks_t ompt_multiplex_own_callbacks,
112174
ompt_multiplex_client_callbacks;
@@ -1042,19 +1104,25 @@ void ompt_multiplex_finalize(ompt_data_t *fns) {
10421104
#ifdef __cplusplus
10431105
extern "C" {
10441106
#endif
1107+
1108+
// forward declaration because of name shifting from ompt_start_tool
1109+
// to ompt_multiplex_own_start_tool below
10451110
ompt_start_tool_result_t *
10461111
ompt_multiplex_own_start_tool(unsigned int omp_version,
10471112
const char *runtime_version);
10481113

10491114
ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
10501115
const char *runtime_version) {
1116+
setup_verbose_init();
1117+
OMPT_VERBOSE_INIT_PRINT(
1118+
"----- START LOGGING OF CLIENT TOOL REGISTRATION -----\n");
10511119
// try loading client tool
1052-
ompt_multiplex_client_fns = NULL;
1053-
ompt_start_tool_result_t *(*client_start_tool)(unsigned int, const char *) =
1054-
NULL;
1055-
1120+
OMPT_VERBOSE_INIT_PRINT("Search for " CLIENT_TOOL_LIBRARIES_VAR
1121+
" env var... ");
10561122
const char *tool_libs = getenv(CLIENT_TOOL_LIBRARIES_VAR);
10571123
if (tool_libs) {
1124+
OMPT_VERBOSE_INIT_CONTINUED_PRINT("Sucess.\n");
1125+
OMPT_VERBOSE_INIT_PRINT(CLIENT_TOOL_LIBRARIES_VAR " = %s\n", tool_libs);
10581126
// copy environement variable
10591127
char *tool_libs_buffer = strdup(tool_libs);
10601128
if (!tool_libs_buffer) {
@@ -1063,39 +1131,70 @@ ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
10631131
}
10641132

10651133
int progress = 0;
1134+
// Reset dl-error
1135+
dlerror();
10661136
while (progress < strlen(tool_libs)) {
1137+
ompt_multiplex_client_fns = NULL;
1138+
ompt_start_tool_result_t *(*client_start_tool)(unsigned int,
1139+
const char *) = NULL;
1140+
OMPT_VERBOSE_INIT_PRINT(
1141+
"Look for candidates within " CLIENT_TOOL_LIBRARIES_VAR "...\n");
10671142
int tmp_progress = progress;
10681143
while (tmp_progress < strlen(tool_libs) &&
10691144
tool_libs_buffer[tmp_progress] != ':')
10701145
tmp_progress++;
10711146
if (tmp_progress < strlen(tool_libs))
10721147
tool_libs_buffer[tmp_progress] = 0;
1073-
void *h = dlopen(tool_libs_buffer + progress, RTLD_LAZY);
1148+
OMPT_VERBOSE_INIT_PRINT("Try out one candidate...\n");
1149+
char *fname = tool_libs_buffer + progress;
1150+
OMPT_VERBOSE_INIT_PRINT("Opening %s... ", fname);
1151+
void *h = dlopen(fname, RTLD_LAZY);
10741152
if (h) {
10751153
client_start_tool =
10761154
(ompt_start_tool_result_t * (*)(unsigned int, const char *))
10771155
dlsym(h, "ompt_start_tool");
10781156
if (client_start_tool &&
10791157
(ompt_multiplex_client_fns =
10801158
(*client_start_tool)(omp_version, runtime_version))) {
1159+
OMPT_VERBOSE_INIT_CONTINUED_PRINT("Sucess.\n");
1160+
OMPT_VERBOSE_INIT_PRINT(
1161+
"Tool was started and is using the OMPT interface.\n");
10811162
break;
1163+
} else {
1164+
OMPT_VERBOSE_INIT_CONTINUED_PRINT(
1165+
"Failed: client_start_tool = %p, ompt_multiplex_client_fns = %p, "
1166+
"%s\n",
1167+
client_start_tool, ompt_multiplex_client_fns, dlerror());
10821168
}
10831169
} else {
1170+
OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed: %s\n", dlerror());
10841171
printf("Loading %s from %s failed with: %s\n",
10851172
tool_libs_buffer + progress, CLIENT_TOOL_LIBRARIES_VAR,
10861173
dlerror());
10871174
}
10881175
progress = tmp_progress + 1;
10891176
}
10901177
free(tool_libs_buffer);
1178+
OMPT_VERBOSE_INIT_PRINT(
1179+
"----- END LOGGING OF CLIENT TOOL REGISTRATION -----\n");
10911180
}
10921181
// load own tool
1182+
OMPT_VERBOSE_INIT_PRINT(
1183+
"----- START LOGGING OF OWN TOOL REGISTRATION -----\n");
10931184
ompt_multiplex_own_fns =
10941185
ompt_multiplex_own_start_tool(omp_version, runtime_version);
1095-
1186+
OMPT_VERBOSE_INIT_PRINT("ompt_multiplex_own_fns = %p\n",
1187+
ompt_multiplex_own_fns);
1188+
OMPT_VERBOSE_INIT_PRINT("----- END LOGGING OF OWN TOOL REGISTRATION -----\n");
10961189
// return multiplexed versions
10971190
static ompt_start_tool_result_t ompt_start_tool_result = {
10981191
&ompt_multiplex_initialize, &ompt_multiplex_finalize, {0}};
1192+
if (verbose_init && verbose_file != stderr && verbose_file != stdout)
1193+
fclose(verbose_file);
1194+
if (!ompt_multiplex_client_fns)
1195+
return ompt_multiplex_own_fns;
1196+
if (!ompt_multiplex_own_fns)
1197+
return ompt_multiplex_client_fns;
10991198
return &ompt_start_tool_result;
11001199
}
11011200
#ifdef __cplusplus

0 commit comments

Comments
 (0)