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(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("%s\n", "0: thread_data initially not null"); 68 thread_data->value = ompt_get_unique_id(); 69 printf("%" 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("unexpected ompt_sync_region_t passed to %s\n", __func__); 83 exit(-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("ompt_scope_beginend should never be passed to %s\n", __func__); 93 exit(-1); 94 } 95 printf("%" 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("unexpected ompt_sync_region_t passed to %s\n", __func__); 112 exit(-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("ompt_scope_beginend should never be passed to %s\n", __func__); 121 exit(-1); 122 } 123 printf("%" 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("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("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 = {&ompt_initialize,&ompt_finalize, 0}; 163 return &ompt_start_tool_result; 164 } 165