30#if (defined(__clang__) || defined(__INTEL_COMPILER))
33typedef struct ompt_frame_t ompt_frame_t;
34typedef void *ompt_initialize_t;
35typedef void *ompt_finalize_t;
36typedef void *ompt_callback_t;
37typedef union ompt_data_t {
41typedef struct ompt_start_tool_result_t {
42 ompt_initialize_t initialize;
43 ompt_finalize_t finalize;
44 ompt_data_t tool_data;
45} ompt_start_tool_result_t;
46typedef enum ompt_scope_endpoint_t {
50} ompt_scope_endpoint_t;
51typedef enum ompt_set_result_t {
54typedef enum ompt_callbacks_t {
55 ompt_callback_parallel_begin = 3,
56 ompt_callback_parallel_end = 4,
57 ompt_callback_work = 20,
58 ompt_callback_master = 21,
59 ompt_callback_sync_region = 23,
61typedef enum ompt_parallel_flag_t {
62 ompt_parallel_team = 0x80000000
63} ompt_parallel_flag_t;
64typedef enum ompt_sync_region_t {
65 ompt_sync_region_barrier = 1,
66 ompt_sync_region_barrier_implicit,
67 ompt_sync_region_barrier_explicit,
68 ompt_sync_region_barrier_implementation
70typedef enum ompt_work_t {
73 ompt_work_single_executor,
74 ompt_work_single_other,
78typedef void (*ompt_interface_fn_t)(void);
79typedef int (*ompt_get_parallel_info_t)(int, ompt_data_t **,
int *);
80typedef ompt_interface_fn_t (*ompt_function_lookup_t)(
const char *);
81typedef ompt_set_result_t (*ompt_set_callback_t)(ompt_callbacks_t,
85#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(OPENMP_TRACE_SYMBOL)
86#define OPENMP_TRACE_SYMBOL
91#define OPENMP_TRACE_PTR_KIND(PTR) (int)(((uintptr_t)(PTR)) >> 56)
92#define OPENMP_TRACE_PTR_SYMBOL(PTR) \
93 (const void *)(0x0FFFFFFFFFFFFFFF & ((uintptr_t)(PTR)))
94#define OPENMP_TRACE_PTR(PTR, KIND) \
95 (const void *)((((uintptr_t)(0xF & (KIND))) << 56) | \
96 (uintptr_t)OPENMP_TRACE_PTR_SYMBOL(PTR))
97#define OPENMP_TRACE_SET_CALLBACK(PREFIX, NAME) \
98 if (ompt_set_never == \
99 set_callback(ompt_callback_##NAME, (ompt_callback_t)PREFIX##_##NAME)) { \
100 ++openmp_trace_issues_n; \
102#define OPENMP_TRACE_PRINT(KIND, FORMAT, ...) \
103 fprintf(stderr, "OMP/TRACE %s: " FORMAT, KIND, __VA_ARGS__)
104#define OPENMP_TRACE_UNUSED(VAR) (void)VAR
106#define OPENMP_TRACE_ENABLE(FEATURE) (FEATURE)
108#define OPENMP_TRACE_ENABLE(FEATURE) 0
112 openmp_trace_level_deflt = 2,
113 openmp_trace_level_high = 4,
114 openmp_trace_level_warn,
115 openmp_trace_level_info
118static int openmp_trace_parallel_n;
119static int openmp_trace_sync_n;
121static const void *openmp_trace_parallel;
122static ompt_data_t *openmp_trace_sync;
124static ompt_get_parallel_info_t openmp_trace_get_parallel_info;
127static void openmp_trace_symbol(
const void *symbol,
char *str,
size_t size,
129 if (NULL != str && 0 < size) {
130#if !defined(OPENMP_TRACE_SYMBOL)
131 OPENMP_TRACE_UNUSED(symbol);
134 if (NULL != symbol && 0 == pipe(pipefd)) {
135 void *
const backtrace[] = {(
void *)(uintptr_t)symbol};
136 backtrace_symbols_fd(backtrace, 1, pipefd[1]);
138 if (0 < read(pipefd[0], str, size)) {
139 char *s = (
char *)(0 != cleanup ? memchr(str,
'(', size) : NULL);
141 (
char *)(NULL != s ? memchr(s + 1,
'+', size - (s - str)) : NULL);
144 memmove(str, s + 1, t - s);
146 s = (
char *)memchr(str,
'\n', size);
150 for (s = str; s < (str + size) &&
'\0' != *s; ++s) {
151 if (0 == isprint(*s)) {
167static const char *openmp_trace_sync_name(
int kind) {
168 static const char *
kinds[] = {
169 "master",
"barrier",
"implicit barrier",
"explicit barrier",
170 "sections",
"single",
"single",
"workshare"};
176static void openmp_trace_parallel_begin(
177 ompt_data_t *encountering_task_data,
178 const ompt_frame_t *encountering_task_frame, ompt_data_t *parallel_data,
179 unsigned int requested_parallelism,
int flags,
const void *codeptr_ra) {
180 OPENMP_TRACE_UNUSED(encountering_task_data);
181 OPENMP_TRACE_UNUSED(encountering_task_frame);
182 OPENMP_TRACE_UNUSED(parallel_data);
183 OPENMP_TRACE_UNUSED(requested_parallelism);
184 if (ompt_parallel_team & flags) {
185 const ompt_data_t *sync;
186#pragma omp atomic read
187 sync = openmp_trace_sync;
189 const int kind = OPENMP_TRACE_PTR_KIND(sync->ptr);
190 if (ompt_sync_region_barrier_implementation > kind) {
194 const char *
const type =
195 (ompt_sync_region_barrier_implementation > kind ?
"ERROR" :
"WARN");
197 const char *
const name = openmp_trace_sync_name(kind);
198 char symbol[1024], symbol2[1024];
199 openmp_trace_symbol(codeptr_ra, symbol,
sizeof(symbol),
201 openmp_trace_symbol(OPENMP_TRACE_PTR_SYMBOL(sync->ptr), symbol2,
202 sizeof(symbol2), 1 );
203 if (
'\0' != *symbol) {
204 if (
'\0' != *symbol2) {
205 OPENMP_TRACE_PRINT(type,
206 "parallel region \"%s\" opened in %s \"%s\"\n",
207 symbol, name, symbol2);
209 OPENMP_TRACE_PRINT(type,
"parallel region \"%s\" opened in %s\n",
213 if (
'\0' != *symbol2) {
214 OPENMP_TRACE_PRINT(type,
"parallel region opened in %s \"%s\"\n",
217 OPENMP_TRACE_PRINT(type,
"parallel region opened in %s\n", name);
229static void openmp_trace_parallel_end(ompt_data_t *parallel_data,
230 ompt_data_t *encountering_task_data,
231 int flags,
const void *codeptr_ra) {
232 OPENMP_TRACE_UNUSED(parallel_data);
233 OPENMP_TRACE_UNUSED(encountering_task_data);
234 if (0 != (ompt_parallel_team & flags) &&
235 0 != openmp_trace_get_parallel_info(openmp_trace_parallel_n + 1, NULL,
237 openmp_trace_parallel = codeptr_ra;
238 ++openmp_trace_parallel_n;
243static void openmp_trace_master(ompt_scope_endpoint_t endpoint,
244 ompt_data_t *parallel_data,
245 ompt_data_t *task_data,
246 const void *codeptr_ra) {
247 OPENMP_TRACE_UNUSED(task_data);
248 if (NULL != parallel_data) {
250 switch ((
int)endpoint) {
251 case OPENMP_TRACE_ENABLE(ompt_scope_beginend):
252 case ompt_scope_begin: {
253 if (OPENMP_TRACE_ENABLE(ompt_scope_beginend) != endpoint) {
254#pragma omp atomic capture
255 sync_n = openmp_trace_sync_n++;
257#pragma omp atomic read
258 sync_n = openmp_trace_sync_n;
261 assert(OPENMP_TRACE_PTR(codeptr_ra, 0) == codeptr_ra);
262 parallel_data->ptr = (
void *)(uintptr_t)codeptr_ra;
263 openmp_trace_sync = parallel_data;
266 case ompt_scope_end: {
267#pragma omp atomic capture
268 sync_n = --openmp_trace_sync_n;
270 openmp_trace_sync = NULL;
278void openmp_trace_sync_region(ompt_sync_region_t kind,
279 ompt_scope_endpoint_t endpoint,
280 ompt_data_t *parallel_data,
281 ompt_data_t *task_data,
const void *codeptr_ra) {
282 OPENMP_TRACE_UNUSED(task_data);
284 if (NULL != parallel_data && ompt_sync_region_barrier_implementation > kind) {
286 switch ((
int)endpoint) {
287 case OPENMP_TRACE_ENABLE(ompt_scope_beginend):
288 case ompt_scope_begin: {
289 if (OPENMP_TRACE_ENABLE(ompt_scope_beginend) != endpoint) {
290#pragma omp atomic capture
291 sync_n = openmp_trace_sync_n++;
293#pragma omp atomic read
294 sync_n = openmp_trace_sync_n;
297 assert(OPENMP_TRACE_PTR(codeptr_ra, 0) == codeptr_ra);
299 (
void *)(uintptr_t)OPENMP_TRACE_PTR(codeptr_ra, kind);
300 openmp_trace_sync = parallel_data;
303 const ompt_data_t *sync;
304#pragma omp atomic read
305 sync = openmp_trace_sync;
306 if (NULL != sync && parallel_data != sync) {
307 const char *
const name = openmp_trace_sync_name(kind);
308 char symbol[1024], symbol2[1024];
309 openmp_trace_symbol(codeptr_ra, symbol,
sizeof(symbol),
311 openmp_trace_symbol(OPENMP_TRACE_PTR_SYMBOL(sync->ptr), symbol2,
312 sizeof(symbol2), 1 );
313 if (
'\0' != *symbol) {
314 if (
'\0' != *symbol2) {
315 OPENMP_TRACE_PRINT(
"WARN",
316 "potential deadlock at \"%s\" in %s \"%s\"\n",
317 symbol2, name, symbol);
319 OPENMP_TRACE_PRINT(
"WARN",
"potential deadlock in %s \"%s\"\n",
323 if (
'\0' != *symbol2) {
324 OPENMP_TRACE_PRINT(
"WARN",
"potential deadlock at \"%s\" in %s\n",
327 OPENMP_TRACE_PRINT(
"WARN",
"potential deadlock in %s\n", name);
333 case ompt_scope_end: {
334#pragma omp atomic capture
335 sync_n = --openmp_trace_sync_n;
337 openmp_trace_sync = NULL;
345static void openmp_trace_work(ompt_work_t wstype,
346 ompt_scope_endpoint_t endpoint,
347 ompt_data_t *parallel_data,
348 ompt_data_t *task_data, uint64_t count,
349 const void *codeptr_ra) {
350 OPENMP_TRACE_UNUSED(task_data);
351 OPENMP_TRACE_UNUSED(count);
353 if (NULL != parallel_data && ompt_work_sections <= wstype &&
354 wstype <= ompt_work_workshare) {
356 switch ((
int)endpoint) {
357 case OPENMP_TRACE_ENABLE(ompt_scope_beginend):
358 case ompt_scope_begin: {
359 if (OPENMP_TRACE_ENABLE(ompt_scope_beginend) != endpoint) {
360#pragma omp atomic capture
361 sync_n = openmp_trace_sync_n++;
363#pragma omp atomic read
364 sync_n = openmp_trace_sync_n;
367 const int kind = wstype - ompt_work_sections +
368 ompt_sync_region_barrier_implementation;
369 assert(OPENMP_TRACE_PTR(codeptr_ra, 0) == codeptr_ra);
371 (
void *)(uintptr_t)OPENMP_TRACE_PTR(codeptr_ra, kind);
372 openmp_trace_sync = parallel_data;
375 case ompt_scope_end: {
376#pragma omp atomic capture
377 sync_n = --openmp_trace_sync_n;
379 openmp_trace_sync = NULL;
387static int openmp_trace_initialize(ompt_function_lookup_t lookup,
388 int initial_device_num,
389 ompt_data_t *tool_data) {
390 const ompt_set_callback_t set_callback =
391 (ompt_set_callback_t)lookup(
"ompt_set_callback");
392 openmp_trace_get_parallel_info =
393 (ompt_get_parallel_info_t)lookup(
"ompt_get_parallel_info");
394 OPENMP_TRACE_UNUSED(initial_device_num);
395 OPENMP_TRACE_UNUSED(tool_data);
396 OPENMP_TRACE_SET_CALLBACK(openmp_trace, parallel_begin);
397 OPENMP_TRACE_SET_CALLBACK(openmp_trace, parallel_end);
398 OPENMP_TRACE_SET_CALLBACK(openmp_trace, master);
400 OPENMP_TRACE_SET_CALLBACK(openmp_trace, sync_region);
403 OPENMP_TRACE_SET_CALLBACK(openmp_trace, work);
405 assert(NULL != openmp_trace_get_parallel_info);
410static void openmp_trace_finalize(ompt_data_t *tool_data) {
411 OPENMP_TRACE_UNUSED(tool_data);
413 if (1 < openmp_trace_parallel_n) {
415 openmp_trace_symbol(openmp_trace_parallel, symbol,
sizeof(symbol),
417 if (
'\0' != *symbol) {
418 OPENMP_TRACE_PRINT(
"INFO",
"parallelism in \"%s\" is nested (%i)\n",
419 symbol, openmp_trace_parallel_n);
421 OPENMP_TRACE_PRINT(
"INFO",
"parallelism is nested (%i)\n",
422 openmp_trace_parallel_n);
429ompt_start_tool_result_t *ompt_start_tool(
unsigned int omp_version,
430 const char *runtime_version) {
431 static ompt_start_tool_result_t openmp_start_tool;
432 const char *
const enabled_env = getenv(
"CP2K_OMP_TRACE");
433 ompt_start_tool_result_t *result = NULL;
435 OPENMP_TRACE_UNUSED(omp_version);
436 OPENMP_TRACE_UNUSED(runtime_version);
438 openmp_start_tool.initialize = (ompt_initialize_t)openmp_trace_initialize;
439 openmp_start_tool.finalize = (ompt_finalize_t)openmp_trace_finalize;
440 openmp_start_tool.tool_data.ptr = NULL;
441 result = &openmp_start_tool;
Defines the basic variable types.
int openmp_trace_issues(void)
static int openmp_trace_level
static int openmp_trace_issues_n