1 /* 2 * kmp_gsupport.cpp 3 */ 4 5 //===----------------------------------------------------------------------===// 6 // 7 // The LLVM Compiler Infrastructure 8 // 9 // This file is dual licensed under the MIT and the University of Illinois Open 10 // Source Licenses. See LICENSE.txt for details. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "kmp.h" 15 #include "kmp_atomic.h" 16 17 #if OMPT_SUPPORT 18 #include "ompt-specific.h" 19 #endif 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif // __cplusplus 24 25 #define MKLOC(loc, routine) \ 26 static ident_t(loc) = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"}; 27 28 #include "kmp_ftn_os.h" 29 30 void xexpand(KMP_API_NAME_GOMP_BARRIER)(void) { 31 int gtid = __kmp_entry_gtid(); 32 MKLOC(loc, "GOMP_barrier"); 33 KA_TRACE(20, ("GOMP_barrier: T#%d\n", gtid)); 34 #if OMPT_SUPPORT && OMPT_TRACE 35 ompt_frame_t *ompt_frame; 36 if (ompt_enabled) { 37 ompt_frame = __ompt_get_task_frame_internal(0); 38 ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); 39 } 40 #endif 41 __kmpc_barrier(&loc, gtid); 42 } 43 44 // Mutual exclusion 45 46 // The symbol that icc/ifort generates for unnamed for unnamed critical sections 47 // - .gomp_critical_user_ - is defined using .comm in any objects reference it. 48 // We can't reference it directly here in C code, as the symbol contains a ".". 49 // 50 // The RTL contains an assembly language definition of .gomp_critical_user_ 51 // with another symbol __kmp_unnamed_critical_addr initialized with it's 52 // address. 53 extern kmp_critical_name *__kmp_unnamed_critical_addr; 54 55 void xexpand(KMP_API_NAME_GOMP_CRITICAL_START)(void) { 56 int gtid = __kmp_entry_gtid(); 57 MKLOC(loc, "GOMP_critical_start"); 58 KA_TRACE(20, ("GOMP_critical_start: T#%d\n", gtid)); 59 __kmpc_critical(&loc, gtid, __kmp_unnamed_critical_addr); 60 } 61 62 void xexpand(KMP_API_NAME_GOMP_CRITICAL_END)(void) { 63 int gtid = __kmp_get_gtid(); 64 MKLOC(loc, "GOMP_critical_end"); 65 KA_TRACE(20, ("GOMP_critical_end: T#%d\n", gtid)); 66 __kmpc_end_critical(&loc, gtid, __kmp_unnamed_critical_addr); 67 } 68 69 void xexpand(KMP_API_NAME_GOMP_CRITICAL_NAME_START)(void **pptr) { 70 int gtid = __kmp_entry_gtid(); 71 MKLOC(loc, "GOMP_critical_name_start"); 72 KA_TRACE(20, ("GOMP_critical_name_start: T#%d\n", gtid)); 73 __kmpc_critical(&loc, gtid, (kmp_critical_name *)pptr); 74 } 75 76 void xexpand(KMP_API_NAME_GOMP_CRITICAL_NAME_END)(void **pptr) { 77 int gtid = __kmp_get_gtid(); 78 MKLOC(loc, "GOMP_critical_name_end"); 79 KA_TRACE(20, ("GOMP_critical_name_end: T#%d\n", gtid)); 80 __kmpc_end_critical(&loc, gtid, (kmp_critical_name *)pptr); 81 } 82 83 // The Gnu codegen tries to use locked operations to perform atomic updates 84 // inline. If it can't, then it calls GOMP_atomic_start() before performing 85 // the update and GOMP_atomic_end() afterward, regardless of the data type. 86 void xexpand(KMP_API_NAME_GOMP_ATOMIC_START)(void) { 87 int gtid = __kmp_entry_gtid(); 88 KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid)); 89 90 #if OMPT_SUPPORT 91 __ompt_thread_assign_wait_id(0); 92 #endif 93 94 __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid); 95 } 96 97 void xexpand(KMP_API_NAME_GOMP_ATOMIC_END)(void) { 98 int gtid = __kmp_get_gtid(); 99 KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid)); 100 __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid); 101 } 102 103 int xexpand(KMP_API_NAME_GOMP_SINGLE_START)(void) { 104 int gtid = __kmp_entry_gtid(); 105 MKLOC(loc, "GOMP_single_start"); 106 KA_TRACE(20, ("GOMP_single_start: T#%d\n", gtid)); 107 108 if (!TCR_4(__kmp_init_parallel)) 109 __kmp_parallel_initialize(); 110 111 // 3rd parameter == FALSE prevents kmp_enter_single from pushing a 112 // workshare when USE_CHECKS is defined. We need to avoid the push, 113 // as there is no corresponding GOMP_single_end() call. 114 return __kmp_enter_single(gtid, &loc, FALSE); 115 } 116 117 void *xexpand(KMP_API_NAME_GOMP_SINGLE_COPY_START)(void) { 118 void *retval; 119 int gtid = __kmp_entry_gtid(); 120 MKLOC(loc, "GOMP_single_copy_start"); 121 KA_TRACE(20, ("GOMP_single_copy_start: T#%d\n", gtid)); 122 123 if (!TCR_4(__kmp_init_parallel)) 124 __kmp_parallel_initialize(); 125 126 // If this is the first thread to enter, return NULL. The generated code will 127 // then call GOMP_single_copy_end() for this thread only, with the 128 // copyprivate data pointer as an argument. 129 if (__kmp_enter_single(gtid, &loc, FALSE)) 130 return NULL; 131 132 // Wait for the first thread to set the copyprivate data pointer, 133 // and for all other threads to reach this point. 134 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 135 136 // Retrieve the value of the copyprivate data point, and wait for all 137 // threads to do likewise, then return. 138 retval = __kmp_team_from_gtid(gtid)->t.t_copypriv_data; 139 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 140 return retval; 141 } 142 143 void xexpand(KMP_API_NAME_GOMP_SINGLE_COPY_END)(void *data) { 144 int gtid = __kmp_get_gtid(); 145 KA_TRACE(20, ("GOMP_single_copy_end: T#%d\n", gtid)); 146 147 // Set the copyprivate data pointer fo the team, then hit the barrier so that 148 // the other threads will continue on and read it. Hit another barrier before 149 // continuing, so that the know that the copyprivate data pointer has been 150 // propagated to all threads before trying to reuse the t_copypriv_data field. 151 __kmp_team_from_gtid(gtid)->t.t_copypriv_data = data; 152 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 153 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 154 } 155 156 void xexpand(KMP_API_NAME_GOMP_ORDERED_START)(void) { 157 int gtid = __kmp_entry_gtid(); 158 MKLOC(loc, "GOMP_ordered_start"); 159 KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid)); 160 __kmpc_ordered(&loc, gtid); 161 } 162 163 void xexpand(KMP_API_NAME_GOMP_ORDERED_END)(void) { 164 int gtid = __kmp_get_gtid(); 165 MKLOC(loc, "GOMP_ordered_end"); 166 KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid)); 167 __kmpc_end_ordered(&loc, gtid); 168 } 169 170 // Dispatch macro defs 171 // 172 // They come in two flavors: 64-bit unsigned, and either 32-bit signed 173 // (IA-32 architecture) or 64-bit signed (Intel(R) 64). 174 175 #if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS 176 #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4 177 #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4 178 #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4 179 #else 180 #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_8 181 #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_8 182 #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_8 183 #endif /* KMP_ARCH_X86 */ 184 185 #define KMP_DISPATCH_INIT_ULL __kmp_aux_dispatch_init_8u 186 #define KMP_DISPATCH_FINI_CHUNK_ULL __kmp_aux_dispatch_fini_chunk_8u 187 #define KMP_DISPATCH_NEXT_ULL __kmpc_dispatch_next_8u 188 189 // The parallel contruct 190 191 #ifndef KMP_DEBUG 192 static 193 #endif /* KMP_DEBUG */ 194 void 195 __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), 196 void *data) { 197 #if OMPT_SUPPORT 198 kmp_info_t *thr; 199 ompt_frame_t *ompt_frame; 200 ompt_state_t enclosing_state; 201 202 if (ompt_enabled) { 203 // get pointer to thread data structure 204 thr = __kmp_threads[*gtid]; 205 206 // save enclosing task state; set current state for task 207 enclosing_state = thr->th.ompt_thread_info.state; 208 thr->th.ompt_thread_info.state = ompt_state_work_parallel; 209 210 // set task frame 211 ompt_frame = __ompt_get_task_frame_internal(0); 212 ompt_frame->exit_runtime_frame = __builtin_frame_address(0); 213 } 214 #endif 215 216 task(data); 217 218 #if OMPT_SUPPORT 219 if (ompt_enabled) { 220 // clear task frame 221 ompt_frame->exit_runtime_frame = NULL; 222 223 // restore enclosing state 224 thr->th.ompt_thread_info.state = enclosing_state; 225 } 226 #endif 227 } 228 229 #ifndef KMP_DEBUG 230 static 231 #endif /* KMP_DEBUG */ 232 void 233 __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, 234 void (*task)(void *), void *data, 235 unsigned num_threads, ident_t *loc, 236 enum sched_type schedule, long start, 237 long end, long incr, 238 long chunk_size) { 239 // Intialize the loop worksharing construct. 240 KMP_DISPATCH_INIT(loc, *gtid, schedule, start, end, incr, chunk_size, 241 schedule != kmp_sch_static); 242 243 #if OMPT_SUPPORT 244 kmp_info_t *thr; 245 ompt_frame_t *ompt_frame; 246 ompt_state_t enclosing_state; 247 248 if (ompt_enabled) { 249 thr = __kmp_threads[*gtid]; 250 // save enclosing task state; set current state for task 251 enclosing_state = thr->th.ompt_thread_info.state; 252 thr->th.ompt_thread_info.state = ompt_state_work_parallel; 253 254 // set task frame 255 ompt_frame = __ompt_get_task_frame_internal(0); 256 ompt_frame->exit_runtime_frame = __builtin_frame_address(0); 257 } 258 #endif 259 260 // Now invoke the microtask. 261 task(data); 262 263 #if OMPT_SUPPORT 264 if (ompt_enabled) { 265 // clear task frame 266 ompt_frame->exit_runtime_frame = NULL; 267 268 // reset enclosing state 269 thr->th.ompt_thread_info.state = enclosing_state; 270 } 271 #endif 272 } 273 274 #ifndef KMP_DEBUG 275 static 276 #endif /* KMP_DEBUG */ 277 void 278 __kmp_GOMP_fork_call(ident_t *loc, int gtid, void (*unwrapped_task)(void *), 279 microtask_t wrapper, int argc, ...) { 280 int rc; 281 kmp_info_t *thr = __kmp_threads[gtid]; 282 kmp_team_t *team = thr->th.th_team; 283 int tid = __kmp_tid_from_gtid(gtid); 284 285 va_list ap; 286 va_start(ap, argc); 287 288 rc = __kmp_fork_call(loc, gtid, fork_context_gnu, argc, 289 #if OMPT_SUPPORT 290 VOLATILE_CAST(void *) unwrapped_task, 291 #endif 292 wrapper, __kmp_invoke_task_func, 293 #if (KMP_ARCH_X86_64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64) && KMP_OS_LINUX 294 &ap 295 #else 296 ap 297 #endif 298 ); 299 300 va_end(ap); 301 302 if (rc) { 303 __kmp_run_before_invoked_task(gtid, tid, thr, team); 304 } 305 306 #if OMPT_SUPPORT 307 if (ompt_enabled) { 308 #if OMPT_TRACE 309 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); 310 ompt_task_info_t *task_info = __ompt_get_taskinfo(0); 311 312 // implicit task callback 313 if (ompt_callbacks.ompt_callback(ompt_event_implicit_task_begin)) { 314 ompt_callbacks.ompt_callback(ompt_event_implicit_task_begin)( 315 team_info->parallel_id, task_info->task_id); 316 } 317 #endif 318 thr->th.ompt_thread_info.state = ompt_state_work_parallel; 319 } 320 #endif 321 } 322 323 static void __kmp_GOMP_serialized_parallel(ident_t *loc, kmp_int32 gtid, 324 void (*task)(void *)) { 325 #if OMPT_SUPPORT 326 ompt_parallel_id_t ompt_parallel_id; 327 if (ompt_enabled) { 328 ompt_task_info_t *task_info = __ompt_get_taskinfo(0); 329 330 ompt_parallel_id = __ompt_parallel_id_new(gtid); 331 332 // parallel region callback 333 if (ompt_callbacks.ompt_callback(ompt_event_parallel_begin)) { 334 int team_size = 1; 335 ompt_callbacks.ompt_callback(ompt_event_parallel_begin)( 336 task_info->task_id, &task_info->frame, ompt_parallel_id, team_size, 337 (void *)task, OMPT_INVOKER(fork_context_gnu)); 338 } 339 } 340 #endif 341 342 __kmp_serialized_parallel(loc, gtid); 343 344 #if OMPT_SUPPORT 345 if (ompt_enabled) { 346 kmp_info_t *thr = __kmp_threads[gtid]; 347 348 ompt_task_id_t my_ompt_task_id = __ompt_task_id_new(gtid); 349 350 // set up lightweight task 351 ompt_lw_taskteam_t *lwt = 352 (ompt_lw_taskteam_t *)__kmp_allocate(sizeof(ompt_lw_taskteam_t)); 353 __ompt_lw_taskteam_init(lwt, thr, gtid, (void *)task, ompt_parallel_id); 354 lwt->ompt_task_info.task_id = my_ompt_task_id; 355 __ompt_lw_taskteam_link(lwt, thr); 356 357 #if OMPT_TRACE 358 // implicit task callback 359 if (ompt_callbacks.ompt_callback(ompt_event_implicit_task_begin)) { 360 ompt_callbacks.ompt_callback(ompt_event_implicit_task_begin)( 361 ompt_parallel_id, my_ompt_task_id); 362 } 363 thr->th.ompt_thread_info.state = ompt_state_work_parallel; 364 #endif 365 } 366 #endif 367 } 368 369 void xexpand(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *), void *data, 370 unsigned num_threads) { 371 int gtid = __kmp_entry_gtid(); 372 373 #if OMPT_SUPPORT 374 ompt_frame_t *parent_frame, *frame; 375 376 if (ompt_enabled) { 377 parent_frame = __ompt_get_task_frame_internal(0); 378 parent_frame->reenter_runtime_frame = __builtin_frame_address(1); 379 } 380 #endif 381 382 MKLOC(loc, "GOMP_parallel_start"); 383 KA_TRACE(20, ("GOMP_parallel_start: T#%d\n", gtid)); 384 385 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { 386 if (num_threads != 0) { 387 __kmp_push_num_threads(&loc, gtid, num_threads); 388 } 389 __kmp_GOMP_fork_call(&loc, gtid, task, 390 (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, 391 data); 392 } else { 393 __kmp_GOMP_serialized_parallel(&loc, gtid, task); 394 } 395 396 #if OMPT_SUPPORT 397 if (ompt_enabled) { 398 frame = __ompt_get_task_frame_internal(0); 399 frame->exit_runtime_frame = __builtin_frame_address(1); 400 } 401 #endif 402 } 403 404 void xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) { 405 int gtid = __kmp_get_gtid(); 406 kmp_info_t *thr; 407 408 thr = __kmp_threads[gtid]; 409 410 MKLOC(loc, "GOMP_parallel_end"); 411 KA_TRACE(20, ("GOMP_parallel_end: T#%d\n", gtid)); 412 413 #if OMPT_SUPPORT 414 ompt_parallel_id_t parallel_id; 415 ompt_task_id_t serialized_task_id; 416 ompt_frame_t *ompt_frame = NULL; 417 418 if (ompt_enabled) { 419 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); 420 parallel_id = team_info->parallel_id; 421 422 ompt_task_info_t *task_info = __ompt_get_taskinfo(0); 423 serialized_task_id = task_info->task_id; 424 425 // unlink if necessary. no-op if there is not a lightweight task. 426 ompt_lw_taskteam_t *lwt = __ompt_lw_taskteam_unlink(thr); 427 // GOMP allocates/frees lwt since it can't be kept on the stack 428 if (lwt) { 429 __kmp_free(lwt); 430 } 431 } 432 #endif 433 434 if (!thr->th.th_team->t.t_serialized) { 435 __kmp_run_after_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr, 436 thr->th.th_team); 437 438 #if OMPT_SUPPORT 439 if (ompt_enabled) { 440 // Implicit task is finished here, in the barrier we might schedule 441 // deferred tasks, 442 // these don't see the implicit task on the stack 443 ompt_frame = __ompt_get_task_frame_internal(0); 444 ompt_frame->exit_runtime_frame = NULL; 445 } 446 #endif 447 448 __kmp_join_call(&loc, gtid 449 #if OMPT_SUPPORT 450 , 451 fork_context_gnu 452 #endif 453 ); 454 } else { 455 #if OMPT_SUPPORT && OMPT_TRACE 456 if (ompt_enabled && 457 ompt_callbacks.ompt_callback(ompt_event_implicit_task_end)) { 458 ompt_callbacks.ompt_callback(ompt_event_implicit_task_end)( 459 parallel_id, serialized_task_id); 460 } 461 #endif 462 463 __kmpc_end_serialized_parallel(&loc, gtid); 464 465 #if OMPT_SUPPORT 466 if (ompt_enabled) { 467 // Record that we re-entered the runtime system in the frame that 468 // created the parallel region. 469 ompt_task_info_t *parent_task_info = __ompt_get_taskinfo(0); 470 471 if (ompt_callbacks.ompt_callback(ompt_event_parallel_end)) { 472 ompt_callbacks.ompt_callback(ompt_event_parallel_end)( 473 parallel_id, parent_task_info->task_id, 474 OMPT_INVOKER(fork_context_gnu)); 475 } 476 477 parent_task_info->frame.reenter_runtime_frame = NULL; 478 479 thr->th.ompt_thread_info.state = 480 (((thr->th.th_team)->t.t_serialized) ? ompt_state_work_serial 481 : ompt_state_work_parallel); 482 } 483 #endif 484 } 485 } 486 487 // Loop worksharing constructs 488 489 // The Gnu codegen passes in an exclusive upper bound for the overall range, 490 // but the libguide dispatch code expects an inclusive upper bound, hence the 491 // "end - incr" 5th argument to KMP_DISPATCH_INIT (and the " ub - str" 11th 492 // argument to __kmp_GOMP_fork_call). 493 // 494 // Conversely, KMP_DISPATCH_NEXT returns and inclusive upper bound in *p_ub, 495 // but the Gnu codegen expects an excluside upper bound, so the adjustment 496 // "*p_ub += stride" compenstates for the discrepancy. 497 // 498 // Correction: the gnu codegen always adjusts the upper bound by +-1, not the 499 // stride value. We adjust the dispatch parameters accordingly (by +-1), but 500 // we still adjust p_ub by the actual stride value. 501 // 502 // The "runtime" versions do not take a chunk_sz parameter. 503 // 504 // The profile lib cannot support construct checking of unordered loops that 505 // are predetermined by the compiler to be statically scheduled, as the gcc 506 // codegen will not always emit calls to GOMP_loop_static_next() to get the 507 // next iteration. Instead, it emits inline code to call omp_get_thread_num() 508 // num and calculate the iteration space using the result. It doesn't do this 509 // with ordered static loop, so they can be checked. 510 511 #define LOOP_START(func, schedule) \ 512 int func(long lb, long ub, long str, long chunk_sz, long *p_lb, \ 513 long *p_ub) { \ 514 int status; \ 515 long stride; \ 516 int gtid = __kmp_entry_gtid(); \ 517 MKLOC(loc, #func); \ 518 KA_TRACE(20, \ 519 (#func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 520 gtid, lb, ub, str, chunk_sz)); \ 521 \ 522 if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 523 KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 524 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 525 (schedule) != kmp_sch_static); \ 526 status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 527 (kmp_int *)p_ub, (kmp_int *)&stride); \ 528 if (status) { \ 529 KMP_DEBUG_ASSERT(stride == str); \ 530 *p_ub += (str > 0) ? 1 : -1; \ 531 } \ 532 } else { \ 533 status = 0; \ 534 } \ 535 \ 536 KA_TRACE(20, \ 537 (#func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 538 gtid, *p_lb, *p_ub, status)); \ 539 return status; \ 540 } 541 542 #define LOOP_RUNTIME_START(func, schedule) \ 543 int func(long lb, long ub, long str, long *p_lb, long *p_ub) { \ 544 int status; \ 545 long stride; \ 546 long chunk_sz = 0; \ 547 int gtid = __kmp_entry_gtid(); \ 548 MKLOC(loc, #func); \ 549 KA_TRACE(20, \ 550 (#func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \ 551 gtid, lb, ub, str, chunk_sz)); \ 552 \ 553 if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 554 KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 555 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, TRUE); \ 556 status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 557 (kmp_int *)p_ub, (kmp_int *)&stride); \ 558 if (status) { \ 559 KMP_DEBUG_ASSERT(stride == str); \ 560 *p_ub += (str > 0) ? 1 : -1; \ 561 } \ 562 } else { \ 563 status = 0; \ 564 } \ 565 \ 566 KA_TRACE(20, \ 567 (#func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 568 gtid, *p_lb, *p_ub, status)); \ 569 return status; \ 570 } 571 572 #define LOOP_NEXT(func, fini_code) \ 573 int func(long *p_lb, long *p_ub) { \ 574 int status; \ 575 long stride; \ 576 int gtid = __kmp_get_gtid(); \ 577 MKLOC(loc, #func); \ 578 KA_TRACE(20, (#func ": T#%d\n", gtid)); \ 579 \ 580 fini_code status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 581 (kmp_int *)p_ub, (kmp_int *)&stride); \ 582 if (status) { \ 583 *p_ub += (stride > 0) ? 1 : -1; \ 584 } \ 585 \ 586 KA_TRACE(20, \ 587 (#func " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, stride 0x%lx, " \ 588 "returning %d\n", \ 589 gtid, *p_lb, *p_ub, stride, status)); \ 590 return status; \ 591 } 592 593 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_STATIC_START), kmp_sch_static) 594 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT), {}) 595 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START), 596 kmp_sch_dynamic_chunked) 597 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT), {}) 598 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_GUIDED_START), kmp_sch_guided_chunked) 599 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT), {}) 600 LOOP_RUNTIME_START(xexpand(KMP_API_NAME_GOMP_LOOP_RUNTIME_START), 601 kmp_sch_runtime) 602 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT), {}) 603 604 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START), kmp_ord_static) 605 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT), 606 { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 607 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START), 608 kmp_ord_dynamic_chunked) 609 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT), 610 { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 611 LOOP_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START), 612 kmp_ord_guided_chunked) 613 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT), 614 { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 615 LOOP_RUNTIME_START(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START), 616 kmp_ord_runtime) 617 LOOP_NEXT(xexpand(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT), 618 { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 619 620 void xexpand(KMP_API_NAME_GOMP_LOOP_END)(void) { 621 int gtid = __kmp_get_gtid(); 622 KA_TRACE(20, ("GOMP_loop_end: T#%d\n", gtid)) 623 624 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 625 626 KA_TRACE(20, ("GOMP_loop_end exit: T#%d\n", gtid)) 627 } 628 629 void xexpand(KMP_API_NAME_GOMP_LOOP_END_NOWAIT)(void) { 630 KA_TRACE(20, ("GOMP_loop_end_nowait: T#%d\n", __kmp_get_gtid())) 631 } 632 633 // Unsigned long long loop worksharing constructs 634 // 635 // These are new with gcc 4.4 636 637 #define LOOP_START_ULL(func, schedule) \ 638 int func(int up, unsigned long long lb, unsigned long long ub, \ 639 unsigned long long str, unsigned long long chunk_sz, \ 640 unsigned long long *p_lb, unsigned long long *p_ub) { \ 641 int status; \ 642 long long str2 = up ? ((long long)str) : -((long long)str); \ 643 long long stride; \ 644 int gtid = __kmp_entry_gtid(); \ 645 MKLOC(loc, #func); \ 646 \ 647 KA_TRACE( \ 648 20, \ 649 (#func \ 650 ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str 0x%llx, chunk_sz 0x%llx\n", \ 651 gtid, up, lb, ub, str, chunk_sz)); \ 652 \ 653 if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 654 KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 655 (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \ 656 (schedule) != kmp_sch_static); \ 657 status = \ 658 KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 659 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 660 if (status) { \ 661 KMP_DEBUG_ASSERT(stride == str2); \ 662 *p_ub += (str > 0) ? 1 : -1; \ 663 } \ 664 } else { \ 665 status = 0; \ 666 } \ 667 \ 668 KA_TRACE(20, \ 669 (#func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 670 gtid, *p_lb, *p_ub, status)); \ 671 return status; \ 672 } 673 674 #define LOOP_RUNTIME_START_ULL(func, schedule) \ 675 int func(int up, unsigned long long lb, unsigned long long ub, \ 676 unsigned long long str, unsigned long long *p_lb, \ 677 unsigned long long *p_ub) { \ 678 int status; \ 679 long long str2 = up ? ((long long)str) : -((long long)str); \ 680 unsigned long long stride; \ 681 unsigned long long chunk_sz = 0; \ 682 int gtid = __kmp_entry_gtid(); \ 683 MKLOC(loc, #func); \ 684 \ 685 KA_TRACE( \ 686 20, \ 687 (#func \ 688 ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str 0x%llx, chunk_sz 0x%llx\n", \ 689 gtid, up, lb, ub, str, chunk_sz)); \ 690 \ 691 if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 692 KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 693 (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \ 694 TRUE); \ 695 status = \ 696 KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 697 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 698 if (status) { \ 699 KMP_DEBUG_ASSERT((long long)stride == str2); \ 700 *p_ub += (str > 0) ? 1 : -1; \ 701 } \ 702 } else { \ 703 status = 0; \ 704 } \ 705 \ 706 KA_TRACE(20, \ 707 (#func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 708 gtid, *p_lb, *p_ub, status)); \ 709 return status; \ 710 } 711 712 #define LOOP_NEXT_ULL(func, fini_code) \ 713 int func(unsigned long long *p_lb, unsigned long long *p_ub) { \ 714 int status; \ 715 long long stride; \ 716 int gtid = __kmp_get_gtid(); \ 717 MKLOC(loc, #func); \ 718 KA_TRACE(20, (#func ": T#%d\n", gtid)); \ 719 \ 720 fini_code status = \ 721 KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 722 (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 723 if (status) { \ 724 *p_ub += (stride > 0) ? 1 : -1; \ 725 } \ 726 \ 727 KA_TRACE(20, \ 728 (#func " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, stride 0x%llx, " \ 729 "returning %d\n", \ 730 gtid, *p_lb, *p_ub, stride, status)); \ 731 return status; \ 732 } 733 734 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START), kmp_sch_static) 735 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT), {}) 736 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START), 737 kmp_sch_dynamic_chunked) 738 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT), {}) 739 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START), 740 kmp_sch_guided_chunked) 741 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT), {}) 742 LOOP_RUNTIME_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START), 743 kmp_sch_runtime) 744 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT), {}) 745 746 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START), 747 kmp_ord_static) 748 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT), 749 { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 750 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START), 751 kmp_ord_dynamic_chunked) 752 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT), 753 { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 754 LOOP_START_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START), 755 kmp_ord_guided_chunked) 756 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT), 757 { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 758 LOOP_RUNTIME_START_ULL( 759 xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START), kmp_ord_runtime) 760 LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT), 761 { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 762 763 // Combined parallel / loop worksharing constructs 764 // 765 // There are no ull versions (yet). 766 767 #define PARALLEL_LOOP_START(func, schedule, ompt_pre, ompt_post) \ 768 void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \ 769 long ub, long str, long chunk_sz) { \ 770 int gtid = __kmp_entry_gtid(); \ 771 MKLOC(loc, #func); \ 772 KA_TRACE(20, \ 773 (#func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 774 gtid, lb, ub, str, chunk_sz)); \ 775 \ 776 ompt_pre(); \ 777 \ 778 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { \ 779 if (num_threads != 0) { \ 780 __kmp_push_num_threads(&loc, gtid, num_threads); \ 781 } \ 782 __kmp_GOMP_fork_call(&loc, gtid, task, \ 783 (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \ 784 9, task, data, num_threads, &loc, (schedule), lb, \ 785 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \ 786 } else { \ 787 __kmp_GOMP_serialized_parallel(&loc, gtid, task); \ 788 } \ 789 \ 790 KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 791 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 792 (schedule) != kmp_sch_static); \ 793 \ 794 ompt_post(); \ 795 \ 796 KA_TRACE(20, (#func " exit: T#%d\n", gtid)); \ 797 } 798 799 #if OMPT_SUPPORT 800 801 #define OMPT_LOOP_PRE() \ 802 ompt_frame_t *parent_frame; \ 803 if (ompt_enabled) { \ 804 parent_frame = __ompt_get_task_frame_internal(0); \ 805 parent_frame->reenter_runtime_frame = __builtin_frame_address(1); \ 806 } 807 808 #define OMPT_LOOP_POST() \ 809 if (ompt_enabled) { \ 810 parent_frame->reenter_runtime_frame = NULL; \ 811 } 812 813 #else 814 815 #define OMPT_LOOP_PRE() 816 817 #define OMPT_LOOP_POST() 818 819 #endif 820 821 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START), 822 kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST) 823 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START), 824 kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 825 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START), 826 kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 827 PARALLEL_LOOP_START(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START), 828 kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST) 829 830 // Tasking constructs 831 832 void xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, 833 void (*copy_func)(void *, void *), 834 long arg_size, long arg_align, 835 bool if_cond, unsigned gomp_flags 836 #if OMP_40_ENABLED 837 , 838 void **depend 839 #endif 840 ) { 841 MKLOC(loc, "GOMP_task"); 842 int gtid = __kmp_entry_gtid(); 843 kmp_int32 flags = 0; 844 kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags; 845 846 KA_TRACE(20, ("GOMP_task: T#%d\n", gtid)); 847 848 // The low-order bit is the "untied" flag 849 if (!(gomp_flags & 1)) { 850 input_flags->tiedness = 1; 851 } 852 // The second low-order bit is the "final" flag 853 if (gomp_flags & 2) { 854 input_flags->final = 1; 855 } 856 input_flags->native = 1; 857 // __kmp_task_alloc() sets up all other flags 858 859 if (!if_cond) { 860 arg_size = 0; 861 } 862 863 kmp_task_t *task = __kmp_task_alloc( 864 &loc, gtid, input_flags, sizeof(kmp_task_t), 865 arg_size ? arg_size + arg_align - 1 : 0, (kmp_routine_entry_t)func); 866 867 if (arg_size > 0) { 868 if (arg_align > 0) { 869 task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) / 870 arg_align * arg_align); 871 } 872 // else error?? 873 874 if (copy_func) { 875 (*copy_func)(task->shareds, data); 876 } else { 877 KMP_MEMCPY(task->shareds, data, arg_size); 878 } 879 } 880 881 if (if_cond) { 882 #if OMP_40_ENABLED 883 if (gomp_flags & 8) { 884 KMP_ASSERT(depend); 885 const size_t ndeps = (kmp_intptr_t)depend[0]; 886 const size_t nout = (kmp_intptr_t)depend[1]; 887 kmp_depend_info_t dep_list[ndeps]; 888 889 for (size_t i = 0U; i < ndeps; i++) { 890 dep_list[i].base_addr = (kmp_intptr_t)depend[2U + i]; 891 dep_list[i].len = 0U; 892 dep_list[i].flags.in = 1; 893 dep_list[i].flags.out = (i < nout); 894 } 895 __kmpc_omp_task_with_deps(&loc, gtid, task, ndeps, dep_list, 0, NULL); 896 } else 897 #endif 898 __kmpc_omp_task(&loc, gtid, task); 899 } else { 900 #if OMPT_SUPPORT 901 ompt_thread_info_t oldInfo; 902 kmp_info_t *thread; 903 kmp_taskdata_t *taskdata; 904 if (ompt_enabled) { 905 // Store the threads states and restore them after the task 906 thread = __kmp_threads[gtid]; 907 taskdata = KMP_TASK_TO_TASKDATA(task); 908 oldInfo = thread->th.ompt_thread_info; 909 thread->th.ompt_thread_info.wait_id = 0; 910 thread->th.ompt_thread_info.state = ompt_state_work_parallel; 911 taskdata->ompt_task_info.frame.exit_runtime_frame = 912 __builtin_frame_address(0); 913 } 914 #endif 915 916 __kmpc_omp_task_begin_if0(&loc, gtid, task); 917 func(data); 918 __kmpc_omp_task_complete_if0(&loc, gtid, task); 919 920 #if OMPT_SUPPORT 921 if (ompt_enabled) { 922 thread->th.ompt_thread_info = oldInfo; 923 taskdata->ompt_task_info.frame.exit_runtime_frame = NULL; 924 } 925 #endif 926 } 927 928 KA_TRACE(20, ("GOMP_task exit: T#%d\n", gtid)); 929 } 930 931 void xexpand(KMP_API_NAME_GOMP_TASKWAIT)(void) { 932 MKLOC(loc, "GOMP_taskwait"); 933 int gtid = __kmp_entry_gtid(); 934 935 KA_TRACE(20, ("GOMP_taskwait: T#%d\n", gtid)); 936 937 __kmpc_omp_taskwait(&loc, gtid); 938 939 KA_TRACE(20, ("GOMP_taskwait exit: T#%d\n", gtid)); 940 } 941 942 // Sections worksharing constructs 943 // 944 // For the sections construct, we initialize a dynamically scheduled loop 945 // worksharing construct with lb 1 and stride 1, and use the iteration #'s 946 // that its returns as sections ids. 947 // 948 // There are no special entry points for ordered sections, so we always use 949 // the dynamically scheduled workshare, even if the sections aren't ordered. 950 951 unsigned xexpand(KMP_API_NAME_GOMP_SECTIONS_START)(unsigned count) { 952 int status; 953 kmp_int lb, ub, stride; 954 int gtid = __kmp_entry_gtid(); 955 MKLOC(loc, "GOMP_sections_start"); 956 KA_TRACE(20, ("GOMP_sections_start: T#%d\n", gtid)); 957 958 KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 959 960 status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride); 961 if (status) { 962 KMP_DEBUG_ASSERT(stride == 1); 963 KMP_DEBUG_ASSERT(lb > 0); 964 KMP_ASSERT(lb == ub); 965 } else { 966 lb = 0; 967 } 968 969 KA_TRACE(20, ("GOMP_sections_start exit: T#%d returning %u\n", gtid, 970 (unsigned)lb)); 971 return (unsigned)lb; 972 } 973 974 unsigned xexpand(KMP_API_NAME_GOMP_SECTIONS_NEXT)(void) { 975 int status; 976 kmp_int lb, ub, stride; 977 int gtid = __kmp_get_gtid(); 978 MKLOC(loc, "GOMP_sections_next"); 979 KA_TRACE(20, ("GOMP_sections_next: T#%d\n", gtid)); 980 981 status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride); 982 if (status) { 983 KMP_DEBUG_ASSERT(stride == 1); 984 KMP_DEBUG_ASSERT(lb > 0); 985 KMP_ASSERT(lb == ub); 986 } else { 987 lb = 0; 988 } 989 990 KA_TRACE( 991 20, ("GOMP_sections_next exit: T#%d returning %u\n", gtid, (unsigned)lb)); 992 return (unsigned)lb; 993 } 994 995 void xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(void (*task)(void *), 996 void *data, 997 unsigned num_threads, 998 unsigned count) { 999 int gtid = __kmp_entry_gtid(); 1000 1001 #if OMPT_SUPPORT 1002 ompt_frame_t *parent_frame; 1003 1004 if (ompt_enabled) { 1005 parent_frame = __ompt_get_task_frame_internal(0); 1006 parent_frame->reenter_runtime_frame = __builtin_frame_address(1); 1007 } 1008 #endif 1009 1010 MKLOC(loc, "GOMP_parallel_sections_start"); 1011 KA_TRACE(20, ("GOMP_parallel_sections_start: T#%d\n", gtid)); 1012 1013 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { 1014 if (num_threads != 0) { 1015 __kmp_push_num_threads(&loc, gtid, num_threads); 1016 } 1017 __kmp_GOMP_fork_call(&loc, gtid, task, 1018 (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, 1019 task, data, num_threads, &loc, kmp_nm_dynamic_chunked, 1020 (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1); 1021 } else { 1022 __kmp_GOMP_serialized_parallel(&loc, gtid, task); 1023 } 1024 1025 #if OMPT_SUPPORT 1026 if (ompt_enabled) { 1027 parent_frame->reenter_runtime_frame = NULL; 1028 } 1029 #endif 1030 1031 KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 1032 1033 KA_TRACE(20, ("GOMP_parallel_sections_start exit: T#%d\n", gtid)); 1034 } 1035 1036 void xexpand(KMP_API_NAME_GOMP_SECTIONS_END)(void) { 1037 int gtid = __kmp_get_gtid(); 1038 KA_TRACE(20, ("GOMP_sections_end: T#%d\n", gtid)) 1039 1040 __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 1041 1042 KA_TRACE(20, ("GOMP_sections_end exit: T#%d\n", gtid)) 1043 } 1044 1045 void xexpand(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT)(void) { 1046 KA_TRACE(20, ("GOMP_sections_end_nowait: T#%d\n", __kmp_get_gtid())) 1047 } 1048 1049 // libgomp has an empty function for GOMP_taskyield as of 2013-10-10 1050 void xexpand(KMP_API_NAME_GOMP_TASKYIELD)(void) { 1051 KA_TRACE(20, ("GOMP_taskyield: T#%d\n", __kmp_get_gtid())) 1052 return; 1053 } 1054 1055 #if OMP_40_ENABLED // these are new GOMP_4.0 entry points 1056 1057 void xexpand(KMP_API_NAME_GOMP_PARALLEL)(void (*task)(void *), void *data, 1058 unsigned num_threads, 1059 unsigned int flags) { 1060 int gtid = __kmp_entry_gtid(); 1061 MKLOC(loc, "GOMP_parallel"); 1062 KA_TRACE(20, ("GOMP_parallel: T#%d\n", gtid)); 1063 1064 #if OMPT_SUPPORT 1065 ompt_task_info_t *parent_task_info, *task_info; 1066 if (ompt_enabled) { 1067 parent_task_info = __ompt_get_taskinfo(0); 1068 parent_task_info->frame.reenter_runtime_frame = __builtin_frame_address(1); 1069 } 1070 #endif 1071 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { 1072 if (num_threads != 0) { 1073 __kmp_push_num_threads(&loc, gtid, num_threads); 1074 } 1075 if (flags != 0) { 1076 __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags); 1077 } 1078 __kmp_GOMP_fork_call(&loc, gtid, task, 1079 (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, 1080 data); 1081 } else { 1082 __kmp_GOMP_serialized_parallel(&loc, gtid, task); 1083 } 1084 #if OMPT_SUPPORT 1085 if (ompt_enabled) { 1086 task_info = __ompt_get_taskinfo(0); 1087 task_info->frame.exit_runtime_frame = __builtin_frame_address(0); 1088 } 1089 #endif 1090 task(data); 1091 xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(); 1092 #if OMPT_SUPPORT 1093 if (ompt_enabled) { 1094 task_info->frame.exit_runtime_frame = NULL; 1095 parent_task_info->frame.reenter_runtime_frame = NULL; 1096 } 1097 #endif 1098 } 1099 1100 void xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS)(void (*task)(void *), 1101 void *data, 1102 unsigned num_threads, 1103 unsigned count, 1104 unsigned flags) { 1105 int gtid = __kmp_entry_gtid(); 1106 MKLOC(loc, "GOMP_parallel_sections"); 1107 KA_TRACE(20, ("GOMP_parallel_sections: T#%d\n", gtid)); 1108 1109 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { 1110 if (num_threads != 0) { 1111 __kmp_push_num_threads(&loc, gtid, num_threads); 1112 } 1113 if (flags != 0) { 1114 __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags); 1115 } 1116 __kmp_GOMP_fork_call(&loc, gtid, task, 1117 (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, 1118 task, data, num_threads, &loc, kmp_nm_dynamic_chunked, 1119 (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1); 1120 } else { 1121 __kmp_GOMP_serialized_parallel(&loc, gtid, task); 1122 } 1123 1124 KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 1125 1126 task(data); 1127 xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(); 1128 KA_TRACE(20, ("GOMP_parallel_sections exit: T#%d\n", gtid)); 1129 } 1130 1131 #define PARALLEL_LOOP(func, schedule, ompt_pre, ompt_post) \ 1132 void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \ 1133 long ub, long str, long chunk_sz, unsigned flags) { \ 1134 int gtid = __kmp_entry_gtid(); \ 1135 MKLOC(loc, #func); \ 1136 KA_TRACE(20, \ 1137 (#func ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 1138 gtid, lb, ub, str, chunk_sz)); \ 1139 \ 1140 ompt_pre(); \ 1141 if (__kmpc_ok_to_fork(&loc) && (num_threads != 1)) { \ 1142 if (num_threads != 0) { \ 1143 __kmp_push_num_threads(&loc, gtid, num_threads); \ 1144 } \ 1145 if (flags != 0) { \ 1146 __kmp_push_proc_bind(&loc, gtid, (kmp_proc_bind_t)flags); \ 1147 } \ 1148 __kmp_GOMP_fork_call(&loc, gtid, task, \ 1149 (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \ 1150 9, task, data, num_threads, &loc, (schedule), lb, \ 1151 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \ 1152 } else { \ 1153 __kmp_GOMP_serialized_parallel(&loc, gtid, task); \ 1154 } \ 1155 \ 1156 KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 1157 (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 1158 (schedule) != kmp_sch_static); \ 1159 task(data); \ 1160 xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(); \ 1161 ompt_post(); \ 1162 \ 1163 KA_TRACE(20, (#func " exit: T#%d\n", gtid)); \ 1164 } 1165 1166 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC), kmp_sch_static, 1167 OMPT_LOOP_PRE, OMPT_LOOP_POST) 1168 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC), 1169 kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 1170 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED), 1171 kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 1172 PARALLEL_LOOP(xexpand(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME), kmp_sch_runtime, 1173 OMPT_LOOP_PRE, OMPT_LOOP_POST) 1174 1175 void xexpand(KMP_API_NAME_GOMP_TASKGROUP_START)(void) { 1176 int gtid = __kmp_entry_gtid(); 1177 MKLOC(loc, "GOMP_taskgroup_start"); 1178 KA_TRACE(20, ("GOMP_taskgroup_start: T#%d\n", gtid)); 1179 1180 __kmpc_taskgroup(&loc, gtid); 1181 1182 return; 1183 } 1184 1185 void xexpand(KMP_API_NAME_GOMP_TASKGROUP_END)(void) { 1186 int gtid = __kmp_get_gtid(); 1187 MKLOC(loc, "GOMP_taskgroup_end"); 1188 KA_TRACE(20, ("GOMP_taskgroup_end: T#%d\n", gtid)); 1189 1190 __kmpc_end_taskgroup(&loc, gtid); 1191 1192 return; 1193 } 1194 1195 #ifndef KMP_DEBUG 1196 static 1197 #endif /* KMP_DEBUG */ 1198 kmp_int32 1199 __kmp_gomp_to_omp_cancellation_kind(int gomp_kind) { 1200 kmp_int32 cncl_kind = 0; 1201 switch (gomp_kind) { 1202 case 1: 1203 cncl_kind = cancel_parallel; 1204 break; 1205 case 2: 1206 cncl_kind = cancel_loop; 1207 break; 1208 case 4: 1209 cncl_kind = cancel_sections; 1210 break; 1211 case 8: 1212 cncl_kind = cancel_taskgroup; 1213 break; 1214 } 1215 return cncl_kind; 1216 } 1217 1218 bool xexpand(KMP_API_NAME_GOMP_CANCELLATION_POINT)(int which) { 1219 if (__kmp_omp_cancellation) { 1220 KMP_FATAL(NoGompCancellation); 1221 } 1222 int gtid = __kmp_get_gtid(); 1223 MKLOC(loc, "GOMP_cancellation_point"); 1224 KA_TRACE(20, ("GOMP_cancellation_point: T#%d\n", gtid)); 1225 1226 kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which); 1227 1228 return __kmpc_cancellationpoint(&loc, gtid, cncl_kind); 1229 } 1230 1231 bool xexpand(KMP_API_NAME_GOMP_BARRIER_CANCEL)(void) { 1232 if (__kmp_omp_cancellation) { 1233 KMP_FATAL(NoGompCancellation); 1234 } 1235 KMP_FATAL(NoGompCancellation); 1236 int gtid = __kmp_get_gtid(); 1237 MKLOC(loc, "GOMP_barrier_cancel"); 1238 KA_TRACE(20, ("GOMP_barrier_cancel: T#%d\n", gtid)); 1239 1240 return __kmpc_cancel_barrier(&loc, gtid); 1241 } 1242 1243 bool xexpand(KMP_API_NAME_GOMP_CANCEL)(int which, bool do_cancel) { 1244 if (__kmp_omp_cancellation) { 1245 KMP_FATAL(NoGompCancellation); 1246 } else { 1247 return FALSE; 1248 } 1249 1250 int gtid = __kmp_get_gtid(); 1251 MKLOC(loc, "GOMP_cancel"); 1252 KA_TRACE(20, ("GOMP_cancel: T#%d\n", gtid)); 1253 1254 kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which); 1255 1256 if (do_cancel == FALSE) { 1257 return xexpand(KMP_API_NAME_GOMP_CANCELLATION_POINT)(which); 1258 } else { 1259 return __kmpc_cancel(&loc, gtid, cncl_kind); 1260 } 1261 } 1262 1263 bool xexpand(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL)(void) { 1264 if (__kmp_omp_cancellation) { 1265 KMP_FATAL(NoGompCancellation); 1266 } 1267 int gtid = __kmp_get_gtid(); 1268 MKLOC(loc, "GOMP_sections_end_cancel"); 1269 KA_TRACE(20, ("GOMP_sections_end_cancel: T#%d\n", gtid)); 1270 1271 return __kmpc_cancel_barrier(&loc, gtid); 1272 } 1273 1274 bool xexpand(KMP_API_NAME_GOMP_LOOP_END_CANCEL)(void) { 1275 if (__kmp_omp_cancellation) { 1276 KMP_FATAL(NoGompCancellation); 1277 } 1278 int gtid = __kmp_get_gtid(); 1279 MKLOC(loc, "GOMP_loop_end_cancel"); 1280 KA_TRACE(20, ("GOMP_loop_end_cancel: T#%d\n", gtid)); 1281 1282 return __kmpc_cancel_barrier(&loc, gtid); 1283 } 1284 1285 // All target functions are empty as of 2014-05-29 1286 void xexpand(KMP_API_NAME_GOMP_TARGET)(int device, void (*fn)(void *), 1287 const void *openmp_target, size_t mapnum, 1288 void **hostaddrs, size_t *sizes, 1289 unsigned char *kinds) { 1290 return; 1291 } 1292 1293 void xexpand(KMP_API_NAME_GOMP_TARGET_DATA)(int device, 1294 const void *openmp_target, 1295 size_t mapnum, void **hostaddrs, 1296 size_t *sizes, 1297 unsigned char *kinds) { 1298 return; 1299 } 1300 1301 void xexpand(KMP_API_NAME_GOMP_TARGET_END_DATA)(void) { return; } 1302 1303 void xexpand(KMP_API_NAME_GOMP_TARGET_UPDATE)(int device, 1304 const void *openmp_target, 1305 size_t mapnum, void **hostaddrs, 1306 size_t *sizes, 1307 unsigned char *kinds) { 1308 return; 1309 } 1310 1311 void xexpand(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams, 1312 unsigned int thread_limit) { 1313 return; 1314 } 1315 #endif // OMP_40_ENABLED 1316 1317 /* The following sections of code create aliases for the GOMP_* functions, then 1318 create versioned symbols using the assembler directive .symver. This is only 1319 pertinent for ELF .so library xaliasify and xversionify are defined in 1320 kmp_ftn_os.h */ 1321 1322 #ifdef KMP_USE_VERSION_SYMBOLS 1323 1324 // GOMP_1.0 aliases 1325 xaliasify(KMP_API_NAME_GOMP_ATOMIC_END, 10); 1326 xaliasify(KMP_API_NAME_GOMP_ATOMIC_START, 10); 1327 xaliasify(KMP_API_NAME_GOMP_BARRIER, 10); 1328 xaliasify(KMP_API_NAME_GOMP_CRITICAL_END, 10); 1329 xaliasify(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10); 1330 xaliasify(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10); 1331 xaliasify(KMP_API_NAME_GOMP_CRITICAL_START, 10); 1332 xaliasify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10); 1333 xaliasify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10); 1334 xaliasify(KMP_API_NAME_GOMP_LOOP_END, 10); 1335 xaliasify(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10); 1336 xaliasify(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10); 1337 xaliasify(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10); 1338 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10); 1339 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10); 1340 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10); 1341 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10); 1342 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10); 1343 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10); 1344 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10); 1345 xaliasify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10); 1346 xaliasify(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10); 1347 xaliasify(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10); 1348 xaliasify(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10); 1349 xaliasify(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10); 1350 xaliasify(KMP_API_NAME_GOMP_ORDERED_END, 10); 1351 xaliasify(KMP_API_NAME_GOMP_ORDERED_START, 10); 1352 xaliasify(KMP_API_NAME_GOMP_PARALLEL_END, 10); 1353 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10); 1354 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10); 1355 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10); 1356 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10); 1357 xaliasify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10); 1358 xaliasify(KMP_API_NAME_GOMP_PARALLEL_START, 10); 1359 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END, 10); 1360 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10); 1361 xaliasify(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10); 1362 xaliasify(KMP_API_NAME_GOMP_SECTIONS_START, 10); 1363 xaliasify(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10); 1364 xaliasify(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10); 1365 xaliasify(KMP_API_NAME_GOMP_SINGLE_START, 10); 1366 1367 // GOMP_2.0 aliases 1368 xaliasify(KMP_API_NAME_GOMP_TASK, 20); 1369 xaliasify(KMP_API_NAME_GOMP_TASKWAIT, 20); 1370 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20); 1371 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20); 1372 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20); 1373 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20); 1374 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20); 1375 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20); 1376 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20); 1377 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20); 1378 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20); 1379 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20); 1380 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20); 1381 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20); 1382 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20); 1383 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20); 1384 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20); 1385 xaliasify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20); 1386 1387 // GOMP_3.0 aliases 1388 xaliasify(KMP_API_NAME_GOMP_TASKYIELD, 30); 1389 1390 // GOMP_4.0 aliases 1391 // The GOMP_parallel* entry points below aren't OpenMP 4.0 related. 1392 #if OMP_40_ENABLED 1393 xaliasify(KMP_API_NAME_GOMP_PARALLEL, 40); 1394 xaliasify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40); 1395 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40); 1396 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40); 1397 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40); 1398 xaliasify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40); 1399 xaliasify(KMP_API_NAME_GOMP_TASKGROUP_START, 40); 1400 xaliasify(KMP_API_NAME_GOMP_TASKGROUP_END, 40); 1401 xaliasify(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40); 1402 xaliasify(KMP_API_NAME_GOMP_CANCEL, 40); 1403 xaliasify(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40); 1404 xaliasify(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40); 1405 xaliasify(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40); 1406 xaliasify(KMP_API_NAME_GOMP_TARGET, 40); 1407 xaliasify(KMP_API_NAME_GOMP_TARGET_DATA, 40); 1408 xaliasify(KMP_API_NAME_GOMP_TARGET_END_DATA, 40); 1409 xaliasify(KMP_API_NAME_GOMP_TARGET_UPDATE, 40); 1410 xaliasify(KMP_API_NAME_GOMP_TEAMS, 40); 1411 #endif 1412 1413 // GOMP_1.0 versioned symbols 1414 xversionify(KMP_API_NAME_GOMP_ATOMIC_END, 10, "GOMP_1.0"); 1415 xversionify(KMP_API_NAME_GOMP_ATOMIC_START, 10, "GOMP_1.0"); 1416 xversionify(KMP_API_NAME_GOMP_BARRIER, 10, "GOMP_1.0"); 1417 xversionify(KMP_API_NAME_GOMP_CRITICAL_END, 10, "GOMP_1.0"); 1418 xversionify(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10, "GOMP_1.0"); 1419 xversionify(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10, "GOMP_1.0"); 1420 xversionify(KMP_API_NAME_GOMP_CRITICAL_START, 10, "GOMP_1.0"); 1421 xversionify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10, "GOMP_1.0"); 1422 xversionify(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10, "GOMP_1.0"); 1423 xversionify(KMP_API_NAME_GOMP_LOOP_END, 10, "GOMP_1.0"); 1424 xversionify(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10, "GOMP_1.0"); 1425 xversionify(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10, "GOMP_1.0"); 1426 xversionify(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10, "GOMP_1.0"); 1427 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10, "GOMP_1.0"); 1428 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10, "GOMP_1.0"); 1429 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10, "GOMP_1.0"); 1430 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10, "GOMP_1.0"); 1431 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10, "GOMP_1.0"); 1432 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10, "GOMP_1.0"); 1433 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10, "GOMP_1.0"); 1434 xversionify(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10, "GOMP_1.0"); 1435 xversionify(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10, "GOMP_1.0"); 1436 xversionify(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10, "GOMP_1.0"); 1437 xversionify(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10, "GOMP_1.0"); 1438 xversionify(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10, "GOMP_1.0"); 1439 xversionify(KMP_API_NAME_GOMP_ORDERED_END, 10, "GOMP_1.0"); 1440 xversionify(KMP_API_NAME_GOMP_ORDERED_START, 10, "GOMP_1.0"); 1441 xversionify(KMP_API_NAME_GOMP_PARALLEL_END, 10, "GOMP_1.0"); 1442 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10, "GOMP_1.0"); 1443 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10, "GOMP_1.0"); 1444 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10, "GOMP_1.0"); 1445 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10, "GOMP_1.0"); 1446 xversionify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10, "GOMP_1.0"); 1447 xversionify(KMP_API_NAME_GOMP_PARALLEL_START, 10, "GOMP_1.0"); 1448 xversionify(KMP_API_NAME_GOMP_SECTIONS_END, 10, "GOMP_1.0"); 1449 xversionify(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10, "GOMP_1.0"); 1450 xversionify(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10, "GOMP_1.0"); 1451 xversionify(KMP_API_NAME_GOMP_SECTIONS_START, 10, "GOMP_1.0"); 1452 xversionify(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10, "GOMP_1.0"); 1453 xversionify(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10, "GOMP_1.0"); 1454 xversionify(KMP_API_NAME_GOMP_SINGLE_START, 10, "GOMP_1.0"); 1455 1456 // GOMP_2.0 versioned symbols 1457 xversionify(KMP_API_NAME_GOMP_TASK, 20, "GOMP_2.0"); 1458 xversionify(KMP_API_NAME_GOMP_TASKWAIT, 20, "GOMP_2.0"); 1459 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20, "GOMP_2.0"); 1460 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20, "GOMP_2.0"); 1461 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20, "GOMP_2.0"); 1462 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20, "GOMP_2.0"); 1463 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20, "GOMP_2.0"); 1464 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20, "GOMP_2.0"); 1465 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20, "GOMP_2.0"); 1466 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20, "GOMP_2.0"); 1467 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20, "GOMP_2.0"); 1468 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20, "GOMP_2.0"); 1469 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20, "GOMP_2.0"); 1470 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20, "GOMP_2.0"); 1471 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20, "GOMP_2.0"); 1472 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20, "GOMP_2.0"); 1473 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20, "GOMP_2.0"); 1474 xversionify(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20, "GOMP_2.0"); 1475 1476 // GOMP_3.0 versioned symbols 1477 xversionify(KMP_API_NAME_GOMP_TASKYIELD, 30, "GOMP_3.0"); 1478 1479 // GOMP_4.0 versioned symbols 1480 #if OMP_40_ENABLED 1481 xversionify(KMP_API_NAME_GOMP_PARALLEL, 40, "GOMP_4.0"); 1482 xversionify(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40, "GOMP_4.0"); 1483 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40, "GOMP_4.0"); 1484 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40, "GOMP_4.0"); 1485 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40, "GOMP_4.0"); 1486 xversionify(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40, "GOMP_4.0"); 1487 xversionify(KMP_API_NAME_GOMP_TASKGROUP_START, 40, "GOMP_4.0"); 1488 xversionify(KMP_API_NAME_GOMP_TASKGROUP_END, 40, "GOMP_4.0"); 1489 xversionify(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40, "GOMP_4.0"); 1490 xversionify(KMP_API_NAME_GOMP_CANCEL, 40, "GOMP_4.0"); 1491 xversionify(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40, "GOMP_4.0"); 1492 xversionify(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40, "GOMP_4.0"); 1493 xversionify(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40, "GOMP_4.0"); 1494 xversionify(KMP_API_NAME_GOMP_TARGET, 40, "GOMP_4.0"); 1495 xversionify(KMP_API_NAME_GOMP_TARGET_DATA, 40, "GOMP_4.0"); 1496 xversionify(KMP_API_NAME_GOMP_TARGET_END_DATA, 40, "GOMP_4.0"); 1497 xversionify(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0"); 1498 xversionify(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0"); 1499 #endif 1500 1501 #endif // KMP_USE_VERSION_SYMBOLS 1502 1503 #ifdef __cplusplus 1504 } // extern "C" 1505 #endif // __cplusplus 1506