1 #ifndef _BSD_SOURCE 2 #define _BSD_SOURCE 3 #endif 4 #define _DEFAULT_SOURCE 5 #include <stdio.h> 6 #ifndef __STDC_FORMAT_MACROS 7 #define __STDC_FORMAT_MACROS 8 #endif 9 #include <inttypes.h> 10 #include <omp.h> 11 #include <ompt.h> 12 #include "ompt-signal.h" 13 14 // Used to detect architecture 15 #include "../../src/kmp_platform.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 const char* ompt_task_status_t_values[] = { 25 NULL, 26 "ompt_task_complete", 27 "ompt_task_yield", 28 "ompt_task_cancel", 29 "ompt_task_others" 30 }; 31 static const char* ompt_cancel_flag_t_values[] = { 32 "ompt_cancel_parallel", 33 "ompt_cancel_sections", 34 "ompt_cancel_loop", 35 "ompt_cancel_taskgroup", 36 "ompt_cancel_activated", 37 "ompt_cancel_detected", 38 "ompt_cancel_discarded_task" 39 }; 40 41 static void format_task_type(int type, char *buffer) { 42 char *progress = buffer; 43 if (type & ompt_task_initial) 44 progress += sprintf(progress, "ompt_task_initial"); 45 if (type & ompt_task_implicit) 46 progress += sprintf(progress, "ompt_task_implicit"); 47 if (type & ompt_task_explicit) 48 progress += sprintf(progress, "ompt_task_explicit"); 49 if (type & ompt_task_target) 50 progress += sprintf(progress, "ompt_task_target"); 51 if (type & ompt_task_undeferred) 52 progress += sprintf(progress, "|ompt_task_undeferred"); 53 if (type & ompt_task_untied) 54 progress += sprintf(progress, "|ompt_task_untied"); 55 if (type & ompt_task_final) 56 progress += sprintf(progress, "|ompt_task_final"); 57 if (type & ompt_task_mergeable) 58 progress += sprintf(progress, "|ompt_task_mergeable"); 59 if (type & ompt_task_merged) 60 progress += sprintf(progress, "|ompt_task_merged"); 61 } 62 63 static ompt_set_callback_t ompt_set_callback; 64 static ompt_get_callback_t ompt_get_callback; 65 static ompt_get_state_t ompt_get_state; 66 static ompt_get_task_info_t ompt_get_task_info; 67 static ompt_get_thread_data_t ompt_get_thread_data; 68 static ompt_get_parallel_info_t ompt_get_parallel_info; 69 static ompt_get_unique_id_t ompt_get_unique_id; 70 static ompt_get_num_procs_t ompt_get_num_procs; 71 static ompt_get_num_places_t ompt_get_num_places; 72 static ompt_get_place_proc_ids_t ompt_get_place_proc_ids; 73 static ompt_get_place_num_t ompt_get_place_num; 74 static ompt_get_partition_place_nums_t ompt_get_partition_place_nums; 75 static ompt_get_proc_id_t ompt_get_proc_id; 76 static ompt_enumerate_states_t ompt_enumerate_states; 77 static ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls; 78 79 static void print_ids(int level) 80 { 81 int task_type, thread_num; 82 ompt_frame_t *frame; 83 ompt_data_t *task_parallel_data; 84 ompt_data_t *task_data; 85 int exists_task = ompt_get_task_info(level, &task_type, &task_data, &frame, 86 &task_parallel_data, &thread_num); 87 char buffer[2048]; 88 format_task_type(task_type, buffer); 89 if (frame) 90 printf("%" PRIu64 ": task level %d: parallel_id=%" PRIu64 91 ", task_id=%" PRIu64 ", exit_frame=%p, reenter_frame=%p, " 92 "task_type=%s=%d, thread_num=%d\n", 93 ompt_get_thread_data()->value, level, 94 exists_task ? task_parallel_data->value : 0, 95 exists_task ? task_data->value : 0, frame->exit_frame.ptr, 96 frame->enter_frame.ptr, buffer, task_type, thread_num); 97 } 98 99 #define get_frame_address(level) __builtin_frame_address(level) 100 101 #define print_frame(level) \ 102 printf("%" PRIu64 ": __builtin_frame_address(%d)=%p\n", \ 103 ompt_get_thread_data()->value, level, get_frame_address(level)) 104 105 // clang (version 5.0 and above) adds an intermediate function call with debug flag (-g) 106 #if defined(TEST_NEED_PRINT_FRAME_FROM_OUTLINED_FN) 107 #if defined(DEBUG) && defined(__clang__) && __clang_major__ >= 5 108 #define print_frame_from_outlined_fn(level) print_frame(level+1) 109 #else 110 #define print_frame_from_outlined_fn(level) print_frame(level) 111 #endif 112 113 #if defined(__clang__) && __clang_major__ >= 5 114 #warning "Clang 5.0 and later add an additional wrapper for outlined functions when compiling with debug information." 115 #warning "Please define -DDEBUG iff you manually pass in -g to make the tests succeed!" 116 #endif 117 #endif 118 119 // This macro helps to define a label at the current position that can be used 120 // to get the current address in the code. 121 // 122 // For print_current_address(): 123 // To reliably determine the offset between the address of the label and the 124 // actual return address, we insert a NOP instruction as a jump target as the 125 // compiler would otherwise insert an instruction that we can't control. The 126 // instruction length is target dependent and is explained below. 127 // 128 // (The empty block between "#pragma omp ..." and the __asm__ statement is a 129 // workaround for a bug in the Intel Compiler.) 130 #define define_ompt_label(id) \ 131 {} \ 132 __asm__("nop"); \ 133 ompt_label_##id: 134 135 // This macro helps to get the address of a label that is inserted by the above 136 // macro define_ompt_label(). The address is obtained with a GNU extension 137 // (&&label) that has been tested with gcc, clang and icc. 138 #define get_ompt_label_address(id) (&& ompt_label_##id) 139 140 // This macro prints the exact address that a previously called runtime function 141 // returns to. 142 #define print_current_address(id) \ 143 define_ompt_label(id) \ 144 print_possible_return_addresses(get_ompt_label_address(id)) 145 146 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 147 // On X86 the NOP instruction is 1 byte long. In addition, the comiler inserts 148 // a MOV instruction for non-void runtime functions which is 3 bytes long. 149 #define print_possible_return_addresses(addr) \ 150 printf("%" PRIu64 ": current_address=%p or %p for non-void functions\n", \ 151 ompt_get_thread_data()->value, ((char *)addr) - 1, ((char *)addr) - 4) 152 #elif KMP_ARCH_PPC64 153 // On Power the NOP instruction is 4 bytes long. In addition, the compiler 154 // inserts an LD instruction which accounts for another 4 bytes. In contrast to 155 // X86 this instruction is always there, even for void runtime functions. 156 #define print_possible_return_addresses(addr) \ 157 printf("%" PRIu64 ": current_address=%p\n", ompt_get_thread_data()->value, \ 158 ((char *)addr) - 8) 159 #elif KMP_ARCH_AARCH64 160 // On AArch64 the NOP instruction is 4 bytes long, can be followed by inserted 161 // store instruction (another 4 bytes long). 162 #define print_possible_return_addresses(addr) \ 163 printf("%" PRIu64 ": current_address=%p or %p\n", ompt_get_thread_data()->value, \ 164 ((char *)addr) - 4, ((char *)addr) - 8) 165 #else 166 #error Unsupported target architecture, cannot determine address offset! 167 #endif 168 169 170 // This macro performs a somewhat similar job to print_current_address(), except 171 // that it discards a certain number of nibbles from the address and only prints 172 // the most significant bits / nibbles. This can be used for cases where the 173 // return address can only be approximated. 174 // 175 // To account for overflows (ie the most significant bits / nibbles have just 176 // changed as we are a few bytes above the relevant power of two) the addresses 177 // of the "current" and of the "previous block" are printed. 178 #define print_fuzzy_address(id) \ 179 define_ompt_label(id) \ 180 print_fuzzy_address_blocks(get_ompt_label_address(id)) 181 182 // If you change this define you need to adapt all capture patterns in the tests 183 // to include or discard the new number of nibbles! 184 #define FUZZY_ADDRESS_DISCARD_NIBBLES 2 185 #define FUZZY_ADDRESS_DISCARD_BYTES (1 << ((FUZZY_ADDRESS_DISCARD_NIBBLES) * 4)) 186 #define print_fuzzy_address_blocks(addr) \ 187 printf("%" PRIu64 ": fuzzy_address=0x%" PRIx64 " or 0x%" PRIx64 \ 188 " or 0x%" PRIx64 " or 0x%" PRIx64 " (%p)\n", \ 189 ompt_get_thread_data()->value, \ 190 ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES - 1, \ 191 ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES, \ 192 ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES + 1, \ 193 ((uint64_t)addr) / FUZZY_ADDRESS_DISCARD_BYTES + 2, addr) 194 195 static void 196 on_ompt_callback_mutex_acquire( 197 ompt_mutex_t kind, 198 unsigned int hint, 199 unsigned int impl, 200 ompt_wait_id_t wait_id, 201 const void *codeptr_ra) 202 { 203 switch(kind) 204 { 205 case ompt_mutex_lock: 206 printf("%" PRIu64 ": ompt_event_wait_lock: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 207 break; 208 case ompt_mutex_nest_lock: 209 printf("%" PRIu64 ": ompt_event_wait_nest_lock: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 210 break; 211 case ompt_mutex_critical: 212 printf("%" PRIu64 ": ompt_event_wait_critical: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 213 break; 214 case ompt_mutex_atomic: 215 printf("%" PRIu64 ": ompt_event_wait_atomic: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 216 break; 217 case ompt_mutex_ordered: 218 printf("%" PRIu64 ": ompt_event_wait_ordered: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 219 break; 220 default: 221 break; 222 } 223 } 224 225 static void 226 on_ompt_callback_mutex_acquired( 227 ompt_mutex_t kind, 228 ompt_wait_id_t wait_id, 229 const void *codeptr_ra) 230 { 231 switch(kind) 232 { 233 case ompt_mutex_lock: 234 printf("%" PRIu64 ": ompt_event_acquired_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 235 break; 236 case ompt_mutex_nest_lock: 237 printf("%" PRIu64 ": ompt_event_acquired_nest_lock_first: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 238 break; 239 case ompt_mutex_critical: 240 printf("%" PRIu64 ": ompt_event_acquired_critical: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 241 break; 242 case ompt_mutex_atomic: 243 printf("%" PRIu64 ": ompt_event_acquired_atomic: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 244 break; 245 case ompt_mutex_ordered: 246 printf("%" PRIu64 ": ompt_event_acquired_ordered: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 247 break; 248 default: 249 break; 250 } 251 } 252 253 static void 254 on_ompt_callback_mutex_released( 255 ompt_mutex_t kind, 256 ompt_wait_id_t wait_id, 257 const void *codeptr_ra) 258 { 259 switch(kind) 260 { 261 case ompt_mutex_lock: 262 printf("%" PRIu64 ": ompt_event_release_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 263 break; 264 case ompt_mutex_nest_lock: 265 printf("%" PRIu64 ": ompt_event_release_nest_lock_last: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 266 break; 267 case ompt_mutex_critical: 268 printf("%" PRIu64 ": ompt_event_release_critical: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 269 break; 270 case ompt_mutex_atomic: 271 printf("%" PRIu64 ": ompt_event_release_atomic: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 272 break; 273 case ompt_mutex_ordered: 274 printf("%" PRIu64 ": ompt_event_release_ordered: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 275 break; 276 default: 277 break; 278 } 279 } 280 281 static void 282 on_ompt_callback_nest_lock( 283 ompt_scope_endpoint_t endpoint, 284 ompt_wait_id_t wait_id, 285 const void *codeptr_ra) 286 { 287 switch(endpoint) 288 { 289 case ompt_scope_begin: 290 printf("%" PRIu64 ": ompt_event_acquired_nest_lock_next: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 291 break; 292 case ompt_scope_end: 293 printf("%" PRIu64 ": ompt_event_release_nest_lock_prev: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 294 break; 295 } 296 } 297 298 static void 299 on_ompt_callback_sync_region( 300 ompt_sync_region_t kind, 301 ompt_scope_endpoint_t endpoint, 302 ompt_data_t *parallel_data, 303 ompt_data_t *task_data, 304 const void *codeptr_ra) 305 { 306 switch(endpoint) 307 { 308 case ompt_scope_begin: 309 switch(kind) 310 { 311 case ompt_sync_region_barrier: 312 case ompt_sync_region_barrier_implicit: 313 case ompt_sync_region_barrier_explicit: 314 case ompt_sync_region_barrier_implementation: 315 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); 316 print_ids(0); 317 break; 318 case ompt_sync_region_taskwait: 319 printf("%" PRIu64 ": ompt_event_taskwait_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 320 break; 321 case ompt_sync_region_taskgroup: 322 printf("%" PRIu64 ": ompt_event_taskgroup_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 323 break; 324 case ompt_sync_region_reduction: 325 break; 326 } 327 break; 328 case ompt_scope_end: 329 switch(kind) 330 { 331 case ompt_sync_region_barrier: 332 case ompt_sync_region_barrier_implicit: 333 case ompt_sync_region_barrier_explicit: 334 case ompt_sync_region_barrier_implementation: 335 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); 336 break; 337 case ompt_sync_region_taskwait: 338 printf("%" PRIu64 ": ompt_event_taskwait_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); 339 break; 340 case ompt_sync_region_taskgroup: 341 printf("%" PRIu64 ": ompt_event_taskgroup_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); 342 break; 343 case ompt_sync_region_reduction: 344 break; 345 } 346 break; 347 } 348 } 349 350 static void 351 on_ompt_callback_sync_region_wait( 352 ompt_sync_region_t kind, 353 ompt_scope_endpoint_t endpoint, 354 ompt_data_t *parallel_data, 355 ompt_data_t *task_data, 356 const void *codeptr_ra) 357 { 358 switch(endpoint) 359 { 360 case ompt_scope_begin: 361 switch(kind) 362 { 363 case ompt_sync_region_barrier: 364 case ompt_sync_region_barrier_implicit: 365 case ompt_sync_region_barrier_explicit: 366 case ompt_sync_region_barrier_implementation: 367 printf("%" PRIu64 ": ompt_event_wait_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); 368 break; 369 case ompt_sync_region_taskwait: 370 printf("%" PRIu64 ": ompt_event_wait_taskwait_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 371 break; 372 case ompt_sync_region_taskgroup: 373 printf("%" PRIu64 ": ompt_event_wait_taskgroup_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 374 break; 375 case ompt_sync_region_reduction: 376 break; 377 } 378 break; 379 case ompt_scope_end: 380 switch(kind) 381 { 382 case ompt_sync_region_barrier: 383 case ompt_sync_region_barrier_implicit: 384 case ompt_sync_region_barrier_explicit: 385 case ompt_sync_region_barrier_implementation: 386 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); 387 break; 388 case ompt_sync_region_taskwait: 389 printf("%" PRIu64 ": ompt_event_wait_taskwait_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); 390 break; 391 case ompt_sync_region_taskgroup: 392 printf("%" PRIu64 ": ompt_event_wait_taskgroup_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); 393 break; 394 case ompt_sync_region_reduction: 395 break; 396 } 397 break; 398 } 399 } 400 401 static void 402 on_ompt_callback_flush( 403 ompt_data_t *thread_data, 404 const void *codeptr_ra) 405 { 406 printf("%" PRIu64 ": ompt_event_flush: codeptr_ra=%p\n", thread_data->value, codeptr_ra); 407 } 408 409 static void 410 on_ompt_callback_cancel( 411 ompt_data_t *task_data, 412 int flags, 413 const void *codeptr_ra) 414 { 415 const char* first_flag_value; 416 const char* second_flag_value; 417 if(flags & ompt_cancel_parallel) 418 first_flag_value = ompt_cancel_flag_t_values[0]; 419 else if(flags & ompt_cancel_sections) 420 first_flag_value = ompt_cancel_flag_t_values[1]; 421 else if(flags & ompt_cancel_loop) 422 first_flag_value = ompt_cancel_flag_t_values[2]; 423 else if(flags & ompt_cancel_taskgroup) 424 first_flag_value = ompt_cancel_flag_t_values[3]; 425 426 if(flags & ompt_cancel_activated) 427 second_flag_value = ompt_cancel_flag_t_values[4]; 428 else if(flags & ompt_cancel_detected) 429 second_flag_value = ompt_cancel_flag_t_values[5]; 430 else if(flags & ompt_cancel_discarded_task) 431 second_flag_value = ompt_cancel_flag_t_values[6]; 432 433 printf("%" PRIu64 ": ompt_event_cancel: task_data=%" PRIu64 ", flags=%s|%s=%" PRIu32 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, task_data->value, first_flag_value, second_flag_value, flags, codeptr_ra); 434 } 435 436 static void 437 on_ompt_callback_implicit_task( 438 ompt_scope_endpoint_t endpoint, 439 ompt_data_t *parallel_data, 440 ompt_data_t *task_data, 441 unsigned int team_size, 442 unsigned int thread_num) 443 { 444 switch(endpoint) 445 { 446 case ompt_scope_begin: 447 if(task_data->ptr) 448 printf("%s\n", "0: task_data initially not null"); 449 task_data->value = ompt_get_unique_id(); 450 printf("%" PRIu64 ": ompt_event_implicit_task_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", team_size=%" PRIu32 ", thread_num=%" PRIu32 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, team_size, thread_num); 451 break; 452 case ompt_scope_end: 453 printf("%" PRIu64 ": ompt_event_implicit_task_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", team_size=%" PRIu32 ", thread_num=%" PRIu32 "\n", ompt_get_thread_data()->value, (parallel_data)?parallel_data->value:0, task_data->value, team_size, thread_num); 454 break; 455 } 456 } 457 458 static void 459 on_ompt_callback_lock_init( 460 ompt_mutex_t kind, 461 unsigned int hint, 462 unsigned int impl, 463 ompt_wait_id_t wait_id, 464 const void *codeptr_ra) 465 { 466 switch(kind) 467 { 468 case ompt_mutex_lock: 469 printf("%" PRIu64 ": ompt_event_init_lock: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 470 break; 471 case ompt_mutex_nest_lock: 472 printf("%" PRIu64 ": ompt_event_init_nest_lock: wait_id=%" PRIu64 ", hint=%" PRIu32 ", impl=%" PRIu32 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, hint, impl, codeptr_ra); 473 break; 474 default: 475 break; 476 } 477 } 478 479 static void 480 on_ompt_callback_lock_destroy( 481 ompt_mutex_t kind, 482 ompt_wait_id_t wait_id, 483 const void *codeptr_ra) 484 { 485 switch(kind) 486 { 487 case ompt_mutex_lock: 488 printf("%" PRIu64 ": ompt_event_destroy_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 489 break; 490 case ompt_mutex_nest_lock: 491 printf("%" PRIu64 ": ompt_event_destroy_nest_lock: wait_id=%" PRIu64 ", codeptr_ra=%p \n", ompt_get_thread_data()->value, wait_id, codeptr_ra); 492 break; 493 default: 494 break; 495 } 496 } 497 498 static void 499 on_ompt_callback_work( 500 ompt_work_t wstype, 501 ompt_scope_endpoint_t endpoint, 502 ompt_data_t *parallel_data, 503 ompt_data_t *task_data, 504 uint64_t count, 505 const void *codeptr_ra) 506 { 507 switch(endpoint) 508 { 509 case ompt_scope_begin: 510 switch(wstype) 511 { 512 case ompt_work_loop: 513 printf("%" PRIu64 ": ompt_event_loop_begin: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 514 break; 515 case ompt_work_sections: 516 printf("%" PRIu64 ": ompt_event_sections_begin: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 517 break; 518 case ompt_work_single_executor: 519 printf("%" PRIu64 ": ompt_event_single_in_block_begin: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 520 break; 521 case ompt_work_single_other: 522 printf("%" PRIu64 ": ompt_event_single_others_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 523 break; 524 case ompt_work_workshare: 525 //impl 526 break; 527 case ompt_work_distribute: 528 printf("%" PRIu64 ": ompt_event_distribute_begin: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 529 break; 530 case ompt_work_taskloop: 531 //impl 532 printf("%" PRIu64 ": ompt_event_taskloop_begin: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 533 break; 534 } 535 break; 536 case ompt_scope_end: 537 switch(wstype) 538 { 539 case ompt_work_loop: 540 printf("%" PRIu64 ": ompt_event_loop_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 541 break; 542 case ompt_work_sections: 543 printf("%" PRIu64 ": ompt_event_sections_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 544 break; 545 case ompt_work_single_executor: 546 printf("%" PRIu64 ": ompt_event_single_in_block_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 547 break; 548 case ompt_work_single_other: 549 printf("%" PRIu64 ": ompt_event_single_others_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 550 break; 551 case ompt_work_workshare: 552 //impl 553 break; 554 case ompt_work_distribute: 555 printf("%" PRIu64 ": ompt_event_distribute_end: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 556 break; 557 case ompt_work_taskloop: 558 //impl 559 printf("%" PRIu64 ": ompt_event_taskloop_end: parallel_id=%" PRIu64 ", parent_task_id=%" PRIu64 ", codeptr_ra=%p, count=%" PRIu64 "\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra, count); 560 break; 561 } 562 break; 563 } 564 } 565 566 static void 567 on_ompt_callback_master( 568 ompt_scope_endpoint_t endpoint, 569 ompt_data_t *parallel_data, 570 ompt_data_t *task_data, 571 const void *codeptr_ra) 572 { 573 switch(endpoint) 574 { 575 case ompt_scope_begin: 576 printf("%" PRIu64 ": ompt_event_master_begin: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 577 break; 578 case ompt_scope_end: 579 printf("%" PRIu64 ": ompt_event_master_end: parallel_id=%" PRIu64 ", task_id=%" PRIu64 ", codeptr_ra=%p\n", ompt_get_thread_data()->value, parallel_data->value, task_data->value, codeptr_ra); 580 break; 581 } 582 } 583 584 static void on_ompt_callback_parallel_begin( 585 ompt_data_t *encountering_task_data, 586 const ompt_frame_t *encountering_task_frame, ompt_data_t *parallel_data, 587 uint32_t requested_team_size, int flag, const void *codeptr_ra) { 588 if(parallel_data->ptr) 589 printf("0: parallel_data initially not null\n"); 590 parallel_data->value = ompt_get_unique_id(); 591 printf("%" PRIu64 ": ompt_event_parallel_begin: parent_task_id=%" PRIu64 592 ", parent_task_frame.exit=%p, parent_task_frame.reenter=%p, " 593 "parallel_id=%" PRIu64 ", requested_team_size=%" PRIu32 594 ", codeptr_ra=%p, invoker=%d\n", 595 ompt_get_thread_data()->value, encountering_task_data->value, 596 encountering_task_frame->exit_frame.ptr, 597 encountering_task_frame->enter_frame.ptr, parallel_data->value, 598 requested_team_size, codeptr_ra, flag); 599 } 600 601 static void on_ompt_callback_parallel_end(ompt_data_t *parallel_data, 602 ompt_data_t *encountering_task_data, 603 int flag, const void *codeptr_ra) { 604 printf("%" PRIu64 ": ompt_event_parallel_end: parallel_id=%" PRIu64 605 ", task_id=%" PRIu64 ", invoker=%d, codeptr_ra=%p\n", 606 ompt_get_thread_data()->value, parallel_data->value, 607 encountering_task_data->value, flag, codeptr_ra); 608 } 609 610 static void 611 on_ompt_callback_task_create( 612 ompt_data_t *encountering_task_data, 613 const ompt_frame_t *encountering_task_frame, 614 ompt_data_t* new_task_data, 615 int type, 616 int has_dependences, 617 const void *codeptr_ra) 618 { 619 if(new_task_data->ptr) 620 printf("0: new_task_data initially not null\n"); 621 new_task_data->value = ompt_get_unique_id(); 622 char buffer[2048]; 623 624 format_task_type(type, buffer); 625 626 //there is no parallel_begin callback for implicit parallel region 627 //thus it is initialized in initial task 628 if(type & ompt_task_initial) 629 { 630 ompt_data_t *parallel_data; 631 ompt_get_parallel_info(0, ¶llel_data, NULL); 632 if(parallel_data->ptr) 633 printf("%s\n", "0: parallel_data initially not null"); 634 parallel_data->value = ompt_get_unique_id(); 635 } 636 637 printf("%" PRIu64 ": ompt_event_task_create: parent_task_id=%" PRIu64 ", parent_task_frame.exit=%p, parent_task_frame.reenter=%p, new_task_id=%" PRIu64 ", codeptr_ra=%p, task_type=%s=%d, has_dependences=%s\n", ompt_get_thread_data()->value, encountering_task_data ? encountering_task_data->value : 0, encountering_task_frame ? encountering_task_frame->exit_frame.ptr : NULL, encountering_task_frame ? encountering_task_frame->enter_frame.ptr : NULL, new_task_data->value, codeptr_ra, buffer, type, has_dependences ? "yes" : "no"); 638 } 639 640 static void 641 on_ompt_callback_task_schedule( 642 ompt_data_t *first_task_data, 643 ompt_task_status_t prior_task_status, 644 ompt_data_t *second_task_data) 645 { 646 printf("%" PRIu64 ": ompt_event_task_schedule: first_task_id=%" PRIu64 ", second_task_id=%" PRIu64 ", prior_task_status=%s=%d\n", ompt_get_thread_data()->value, first_task_data->value, second_task_data->value, ompt_task_status_t_values[prior_task_status], prior_task_status); 647 if(prior_task_status == ompt_task_complete) 648 { 649 printf("%" PRIu64 ": ompt_event_task_end: task_id=%" PRIu64 "\n", ompt_get_thread_data()->value, first_task_data->value); 650 } 651 } 652 653 static void 654 on_ompt_callback_task_dependences( 655 ompt_data_t *task_data, 656 const ompt_task_dependence_t *deps, 657 int ndeps) 658 { 659 printf("%" PRIu64 ": ompt_event_task_dependences: task_id=%" PRIu64 ", deps=%p, ndeps=%d\n", ompt_get_thread_data()->value, task_data->value, (void *)deps, ndeps); 660 } 661 662 static void 663 on_ompt_callback_task_dependence( 664 ompt_data_t *first_task_data, 665 ompt_data_t *second_task_data) 666 { 667 printf("%" PRIu64 ": ompt_event_task_dependence_pair: first_task_id=%" PRIu64 ", second_task_id=%" PRIu64 "\n", ompt_get_thread_data()->value, first_task_data->value, second_task_data->value); 668 } 669 670 static void 671 on_ompt_callback_thread_begin( 672 ompt_thread_t thread_type, 673 ompt_data_t *thread_data) 674 { 675 if(thread_data->ptr) 676 printf("%s\n", "0: thread_data initially not null"); 677 thread_data->value = ompt_get_unique_id(); 678 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); 679 } 680 681 static void 682 on_ompt_callback_thread_end( 683 ompt_data_t *thread_data) 684 { 685 printf("%" PRIu64 ": ompt_event_thread_end: thread_id=%" PRIu64 "\n", ompt_get_thread_data()->value, thread_data->value); 686 } 687 688 static int 689 on_ompt_callback_control_tool( 690 uint64_t command, 691 uint64_t modifier, 692 void *arg, 693 const void *codeptr_ra) 694 { 695 ompt_frame_t* omptTaskFrame; 696 ompt_get_task_info(0, NULL, (ompt_data_t**) NULL, &omptTaskFrame, NULL, NULL); 697 printf("%" PRIu64 ": ompt_event_control_tool: command=%" PRIu64 ", modifier=%" PRIu64 ", arg=%p, codeptr_ra=%p, current_task_frame.exit=%p, current_task_frame.reenter=%p \n", ompt_get_thread_data()->value, command, modifier, arg, codeptr_ra, omptTaskFrame->exit_frame.ptr, omptTaskFrame->enter_frame.ptr); 698 return 0; //success 699 } 700 701 #define register_callback_t(name, type) \ 702 do{ \ 703 type f_##name = &on_##name; \ 704 if (ompt_set_callback(name, (ompt_callback_t)f_##name) == \ 705 ompt_set_never) \ 706 printf("0: Could not register callback '" #name "'\n"); \ 707 }while(0) 708 709 #define register_callback(name) register_callback_t(name, name##_t) 710 711 int ompt_initialize( 712 ompt_function_lookup_t lookup, 713 ompt_data_t *tool_data) 714 { 715 ompt_set_callback = (ompt_set_callback_t) lookup("ompt_set_callback"); 716 ompt_get_callback = (ompt_get_callback_t) lookup("ompt_get_callback"); 717 ompt_get_state = (ompt_get_state_t) lookup("ompt_get_state"); 718 ompt_get_task_info = (ompt_get_task_info_t) lookup("ompt_get_task_info"); 719 ompt_get_thread_data = (ompt_get_thread_data_t) lookup("ompt_get_thread_data"); 720 ompt_get_parallel_info = (ompt_get_parallel_info_t) lookup("ompt_get_parallel_info"); 721 ompt_get_unique_id = (ompt_get_unique_id_t) lookup("ompt_get_unique_id"); 722 723 ompt_get_num_procs = (ompt_get_num_procs_t) lookup("ompt_get_num_procs"); 724 ompt_get_num_places = (ompt_get_num_places_t) lookup("ompt_get_num_places"); 725 ompt_get_place_proc_ids = (ompt_get_place_proc_ids_t) lookup("ompt_get_place_proc_ids"); 726 ompt_get_place_num = (ompt_get_place_num_t) lookup("ompt_get_place_num"); 727 ompt_get_partition_place_nums = (ompt_get_partition_place_nums_t) lookup("ompt_get_partition_place_nums"); 728 ompt_get_proc_id = (ompt_get_proc_id_t) lookup("ompt_get_proc_id"); 729 ompt_enumerate_states = (ompt_enumerate_states_t) lookup("ompt_enumerate_states"); 730 ompt_enumerate_mutex_impls = (ompt_enumerate_mutex_impls_t) lookup("ompt_enumerate_mutex_impls"); 731 732 register_callback(ompt_callback_mutex_acquire); 733 register_callback_t(ompt_callback_mutex_acquired, ompt_callback_mutex_t); 734 register_callback_t(ompt_callback_mutex_released, ompt_callback_mutex_t); 735 register_callback(ompt_callback_nest_lock); 736 register_callback(ompt_callback_sync_region); 737 register_callback_t(ompt_callback_sync_region_wait, ompt_callback_sync_region_t); 738 register_callback(ompt_callback_control_tool); 739 register_callback(ompt_callback_flush); 740 register_callback(ompt_callback_cancel); 741 register_callback(ompt_callback_implicit_task); 742 register_callback_t(ompt_callback_lock_init, ompt_callback_mutex_acquire_t); 743 register_callback_t(ompt_callback_lock_destroy, ompt_callback_mutex_t); 744 register_callback(ompt_callback_work); 745 register_callback(ompt_callback_master); 746 register_callback(ompt_callback_parallel_begin); 747 register_callback(ompt_callback_parallel_end); 748 register_callback(ompt_callback_task_create); 749 register_callback(ompt_callback_task_schedule); 750 register_callback(ompt_callback_task_dependences); 751 register_callback(ompt_callback_task_dependence); 752 register_callback(ompt_callback_thread_begin); 753 register_callback(ompt_callback_thread_end); 754 printf("0: NULL_POINTER=%p\n", (void*)NULL); 755 return 1; //success 756 } 757 758 void ompt_finalize(ompt_data_t *tool_data) 759 { 760 printf("0: ompt_event_runtime_shutdown\n"); 761 } 762 763 ompt_start_tool_result_t* ompt_start_tool( 764 unsigned int omp_version, 765 const char *runtime_version) 766 { 767 static ompt_start_tool_result_t ompt_start_tool_result = {&ompt_initialize,&ompt_finalize, 0}; 768 return &ompt_start_tool_result; 769 } 770