1 | // RUN: %libomp-compile-and-run | %sort-threads | FileCheck %s |
2 | // REQUIRES: ompt |
3 | |
4 | // This test checks that values stored in task_data in a barrier_begin event |
5 | // are still present in the corresponding barrier_end event. |
6 | // Therefore, callback implementations different from the ones in callback.h are necessary. |
7 | // This is a test for an issue reported in |
8 | // https://github.com/OpenMPToolsInterface/LLVM-openmp/issues/39 |
9 | |
10 | #define _BSD_SOURCE |
11 | #include <stdio.h> |
12 | #include <unistd.h> |
13 | #include <inttypes.h> |
14 | #include <omp.h> |
15 | #include <omp-tools.h> |
16 | |
17 | static const char* ompt_thread_t_values[] = { |
18 | NULL, |
19 | "ompt_thread_initial" , |
20 | "ompt_thread_worker" , |
21 | "ompt_thread_other" |
22 | }; |
23 | |
24 | static ompt_get_unique_id_t ompt_get_unique_id; |
25 | static ompt_get_thread_data_t ompt_get_thread_data; |
26 | |
27 | int main() |
28 | { |
29 | #pragma omp parallel num_threads(4) |
30 | { |
31 | #pragma omp master |
32 | { |
33 | sleep(seconds: 1); |
34 | } |
35 | } |
36 | |
37 | // clang-format off |
38 | // Check if libomp supports the callbacks for this test. |
39 | // CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_sync_region' |
40 | // CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_sync_region_wait' |
41 | |
42 | // CHECK: 0: NULL_POINTER=[[NULL:.*$]] |
43 | |
44 | // master thread implicit barrier at parallel end |
45 | // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_barrier_implicit_parallel_begin: parallel_id=0, task_id=[[TASK_ID:[0-9]+]], codeptr_ra={{(0x)?[0-f]*}} |
46 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_wait_barrier_implicit_parallel_begin: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra={{(0x)?[0-f]*}} |
47 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_wait_barrier_implicit_parallel_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra={{(0x)?[0-f]*}} |
48 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_barrier_implicit_parallel_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra={{(0x)?[0-f]*}} |
49 | |
50 | |
51 | // worker thread implicit barrier at parallel end |
52 | // CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_barrier_implicit_parallel_begin: parallel_id=0, task_id=[[TASK_ID:[0-9]+]], codeptr_ra=[[NULL]] |
53 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_wait_barrier_implicit_parallel_begin: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
54 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_wait_barrier_implicit_parallel_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
55 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_barrier_implicit_parallel_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
56 | // clang-format on |
57 | |
58 | return 0; |
59 | } |
60 | |
61 | static void |
62 | on_ompt_callback_thread_begin( |
63 | ompt_thread_t thread_type, |
64 | ompt_data_t *thread_data) |
65 | { |
66 | if(thread_data->ptr) |
67 | printf(format: "%s\n" , "0: thread_data initially not null" ); |
68 | thread_data->value = ompt_get_unique_id(); |
69 | printf(format: "%" PRIu64 ": ompt_event_thread_begin: thread_type=%s=%d, thread_id=%" PRIu64 "\n" , ompt_get_thread_data()->value, ompt_thread_t_values[thread_type], thread_type, thread_data->value); |
70 | } |
71 | |
72 | static void |
73 | on_ompt_callback_sync_region( |
74 | ompt_sync_region_t kind, |
75 | ompt_scope_endpoint_t endpoint, |
76 | ompt_data_t *parallel_data, |
77 | ompt_data_t *task_data, |
78 | const void *codeptr_ra) |
79 | { |
80 | // We only expect implicit parallel barrier in this code. |
81 | if (kind != ompt_sync_region_barrier_implicit_parallel) { |
82 | printf(format: "unexpected ompt_sync_region_t passed to %s\n" , __func__); |
83 | exit(status: -1); |
84 | } |
85 | const char *event_name = NULL; |
86 | if (endpoint == ompt_scope_begin) { |
87 | event_name = "ompt_event_barrier_implicit_parallel_begin" ; |
88 | task_data->value = ompt_get_unique_id(); |
89 | } else if (endpoint == ompt_scope_end) { |
90 | event_name = "ompt_event_barrier_implicit_parallel_end" ; |
91 | } else { |
92 | printf(format: "ompt_scope_beginend should never be passed to %s\n" , __func__); |
93 | exit(status: -1); |
94 | } |
95 | printf(format: "%" PRIu64 ": %s: parallel_id=%" PRIu64 ", task_id=%" PRIu64 |
96 | ", codeptr_ra=%p\n" , |
97 | ompt_get_thread_data()->value, event_name, |
98 | parallel_data ? parallel_data->value : 0, task_data->value, |
99 | codeptr_ra); |
100 | } |
101 | |
102 | static void |
103 | on_ompt_callback_sync_region_wait( |
104 | ompt_sync_region_t kind, |
105 | ompt_scope_endpoint_t endpoint, |
106 | ompt_data_t *parallel_data, |
107 | ompt_data_t *task_data, |
108 | const void *codeptr_ra) |
109 | { |
110 | if (kind != ompt_sync_region_barrier_implicit_parallel) { |
111 | printf(format: "unexpected ompt_sync_region_t passed to %s\n" , __func__); |
112 | exit(status: -1); |
113 | } |
114 | const char *event_name = NULL; |
115 | if (endpoint == ompt_scope_begin) { |
116 | event_name = "ompt_event_wait_barrier_implicit_parallel_begin" ; |
117 | } else if (endpoint == ompt_scope_end) { |
118 | event_name = "ompt_event_wait_barrier_implicit_parallel_end" ; |
119 | } else { |
120 | printf(format: "ompt_scope_beginend should never be passed to %s\n" , __func__); |
121 | exit(status: -1); |
122 | } |
123 | printf(format: "%" PRIu64 ": %s: parallel_id=%" PRIu64 ", task_id=%" PRIu64 |
124 | ", codeptr_ra=%p\n" , |
125 | ompt_get_thread_data()->value, event_name, |
126 | parallel_data ? parallel_data->value : 0, task_data->value, |
127 | codeptr_ra); |
128 | } |
129 | |
130 | #define register_ompt_callback_t(name, type) \ |
131 | do{ \ |
132 | type f_##name = &on_##name; \ |
133 | if (ompt_set_callback(name, (ompt_callback_t)f_##name) == \ |
134 | ompt_set_never) \ |
135 | printf("0: Could not register callback '" #name "'\n"); \ |
136 | }while(0) |
137 | |
138 | #define register_ompt_callback(name) register_ompt_callback_t(name, name##_t) |
139 | |
140 | int ompt_initialize(ompt_function_lookup_t lookup, int initial_device_num, |
141 | ompt_data_t *tool_data) { |
142 | ompt_set_callback_t ompt_set_callback; |
143 | ompt_set_callback = (ompt_set_callback_t) lookup("ompt_set_callback" ); |
144 | ompt_get_unique_id = (ompt_get_unique_id_t) lookup("ompt_get_unique_id" ); |
145 | ompt_get_thread_data = (ompt_get_thread_data_t) lookup("ompt_get_thread_data" ); |
146 | register_ompt_callback(ompt_callback_sync_region); |
147 | register_ompt_callback_t(ompt_callback_sync_region_wait, ompt_callback_sync_region_t); |
148 | register_ompt_callback(ompt_callback_thread_begin); |
149 | printf(format: "0: NULL_POINTER=%p\n" , (void*)NULL); |
150 | return 1; //success |
151 | } |
152 | |
153 | void ompt_finalize(ompt_data_t *tool_data) |
154 | { |
155 | printf(format: "0: ompt_event_runtime_shutdown\n" ); |
156 | } |
157 | |
158 | ompt_start_tool_result_t* ompt_start_tool( |
159 | unsigned int omp_version, |
160 | const char *runtime_version) |
161 | { |
162 | static ompt_start_tool_result_t ompt_start_tool_result = {.initialize: &ompt_initialize,.finalize: &ompt_finalize, .tool_data.value: 0}; |
163 | return &ompt_start_tool_result; |
164 | } |
165 | |