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 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("%s\n", "0: thread_data initially not null"); 67 thread_data->value = ompt_get_unique_id(); 68 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); 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("%" 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("%" 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("ompt_scope_beginend should never be passed to %s\n", __func__); 92 exit(-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("%" 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("%" 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("ompt_scope_beginend should never be passed to %s\n", __func__); 120 exit(-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("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("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 = {&ompt_initialize,&ompt_finalize, 0}; 157 return &ompt_start_tool_result; 158 } 159