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