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 | |
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_begin: parallel_id=0, task_id=[[TASK_ID:[0-9]+]], codeptr_ra={{0x[0-f]*}} |
46 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_wait_barrier_begin: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra={{0x[0-f]*}} |
47 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_wait_barrier_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra={{0x[0-f]*}} |
48 | // CHECK: {{^}}[[MASTER_ID]]: ompt_event_barrier_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_begin: parallel_id=0, task_id=[[TASK_ID:[0-9]+]], codeptr_ra=[[NULL]] |
53 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_wait_barrier_begin: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
54 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_wait_barrier_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
55 | // CHECK: {{^}}[[THREAD_ID]]: ompt_event_barrier_end: parallel_id=0, task_id=[[TASK_ID]], codeptr_ra=[[NULL]] |
56 | |
57 | return 0; |
58 | } |
59 | |
60 | static void |
61 | on_ompt_callback_thread_begin( |
62 | ompt_thread_t thread_type, |
63 | ompt_data_t *thread_data) |
64 | { |
65 | if(thread_data->ptr) |
66 | printf(format: "%s\n" , "0: thread_data initially not null" ); |
67 | thread_data->value = ompt_get_unique_id(); |
68 | 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); |
69 | } |
70 | |
71 | static void |
72 | on_ompt_callback_sync_region( |
73 | ompt_sync_region_t kind, |
74 | ompt_scope_endpoint_t endpoint, |
75 | ompt_data_t *parallel_data, |
76 | ompt_data_t *task_data, |
77 | const void *codeptr_ra) |
78 | { |
79 | switch(endpoint) |
80 | { |
81 | case ompt_scope_begin: |
82 | task_data->value = ompt_get_unique_id(); |
83 | if (kind == ompt_sync_region_barrier_implicit) |
84 | printf(format: "%" PRIu64 ": ompt_event_barrier_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n" , ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); |
85 | break; |
86 | case ompt_scope_end: |
87 | if (kind == ompt_sync_region_barrier_implicit) |
88 | printf(format: "%" PRIu64 ": ompt_event_barrier_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n" , ompt_get_thread_data()->value, (parallel_data)?parallel_data->value:0, task_data->value, codeptr_ra); |
89 | break; |
90 | case ompt_scope_beginend: |
91 | printf(format: "ompt_scope_beginend should never be passed to %s\n" , __func__); |
92 | exit(status: -1); |
93 | } |
94 | } |
95 | |
96 | static void |
97 | on_ompt_callback_sync_region_wait( |
98 | ompt_sync_region_t kind, |
99 | ompt_scope_endpoint_t endpoint, |
100 | ompt_data_t *parallel_data, |
101 | ompt_data_t *task_data, |
102 | const void *codeptr_ra) |
103 | { |
104 | switch(endpoint) |
105 | { |
106 | case ompt_scope_begin: |
107 | if (kind == ompt_sync_region_barrier_implicit) |
108 | printf(format: "%" PRIu64 |
109 | ": ompt_event_wait_barrier_begin: parallel_id=%" PRIu64 |
110 | ", task_id=%" PRIu64 ", codeptr_ra=%p\n" , |
111 | ompt_get_thread_data()->value, parallel_data->value, |
112 | task_data->value, codeptr_ra); |
113 | break; |
114 | case ompt_scope_end: |
115 | if (kind == ompt_sync_region_barrier_implicit) |
116 | printf(format: "%" PRIu64 ": ompt_event_wait_barrier_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n" , ompt_get_thread_data()->value, (parallel_data)?parallel_data->value:0, task_data->value, codeptr_ra); |
117 | break; |
118 | case ompt_scope_beginend: |
119 | printf(format: "ompt_scope_beginend should never be passed to %s\n" , __func__); |
120 | exit(status: -1); |
121 | } |
122 | } |
123 | |
124 | #define register_ompt_callback_t(name, type) \ |
125 | do{ \ |
126 | type f_##name = &on_##name; \ |
127 | if (ompt_set_callback(name, (ompt_callback_t)f_##name) == \ |
128 | ompt_set_never) \ |
129 | printf("0: Could not register callback '" #name "'\n"); \ |
130 | }while(0) |
131 | |
132 | #define register_ompt_callback(name) register_ompt_callback_t(name, name##_t) |
133 | |
134 | int ompt_initialize(ompt_function_lookup_t lookup, int initial_device_num, |
135 | ompt_data_t *tool_data) { |
136 | ompt_set_callback_t ompt_set_callback; |
137 | ompt_set_callback = (ompt_set_callback_t) lookup("ompt_set_callback" ); |
138 | ompt_get_unique_id = (ompt_get_unique_id_t) lookup("ompt_get_unique_id" ); |
139 | ompt_get_thread_data = (ompt_get_thread_data_t) lookup("ompt_get_thread_data" ); |
140 | register_ompt_callback(ompt_callback_sync_region); |
141 | register_ompt_callback_t(ompt_callback_sync_region_wait, ompt_callback_sync_region_t); |
142 | register_ompt_callback(ompt_callback_thread_begin); |
143 | printf(format: "0: NULL_POINTER=%p\n" , (void*)NULL); |
144 | return 1; //success |
145 | } |
146 | |
147 | void ompt_finalize(ompt_data_t *tool_data) |
148 | { |
149 | printf(format: "0: ompt_event_runtime_shutdown\n" ); |
150 | } |
151 | |
152 | ompt_start_tool_result_t* ompt_start_tool( |
153 | unsigned int omp_version, |
154 | const char *runtime_version) |
155 | { |
156 | static ompt_start_tool_result_t ompt_start_tool_result = {.initialize: &ompt_initialize,.finalize: &ompt_finalize, .tool_data.value: 0}; |
157 | return &ompt_start_tool_result; |
158 | } |
159 | |