10b57cec5SDimitry Andric /* 20b57cec5SDimitry Andric * kmp_gsupport.cpp 30b57cec5SDimitry Andric */ 40b57cec5SDimitry Andric 50b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "kmp.h" 140b57cec5SDimitry Andric #include "kmp_atomic.h" 155f757f3fSDimitry Andric #include "kmp_utils.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #if OMPT_SUPPORT 180b57cec5SDimitry Andric #include "ompt-specific.h" 190b57cec5SDimitry Andric #endif 200b57cec5SDimitry Andric 21e8d8bef9SDimitry Andric enum { 22e8d8bef9SDimitry Andric KMP_GOMP_TASK_UNTIED_FLAG = 1, 23e8d8bef9SDimitry Andric KMP_GOMP_TASK_FINAL_FLAG = 2, 24e8d8bef9SDimitry Andric KMP_GOMP_TASK_DEPENDS_FLAG = 8 25e8d8bef9SDimitry Andric }; 26e8d8bef9SDimitry Andric 27349cc55cSDimitry Andric enum { 28349cc55cSDimitry Andric KMP_GOMP_DEPOBJ_IN = 1, 29349cc55cSDimitry Andric KMP_GOMP_DEPOBJ_OUT = 2, 30349cc55cSDimitry Andric KMP_GOMP_DEPOBJ_INOUT = 3, 31349cc55cSDimitry Andric KMP_GOMP_DEPOBJ_MTXINOUTSET = 4 32349cc55cSDimitry Andric }; 33349cc55cSDimitry Andric 34e8d8bef9SDimitry Andric // This class helps convert gomp dependency info into 35e8d8bef9SDimitry Andric // kmp_depend_info_t structures 36e8d8bef9SDimitry Andric class kmp_gomp_depends_info_t { 37e8d8bef9SDimitry Andric void **depend; 38e8d8bef9SDimitry Andric kmp_int32 num_deps; 39349cc55cSDimitry Andric size_t num_out, num_mutexinout, num_in, num_depobj; 40e8d8bef9SDimitry Andric size_t offset; 41e8d8bef9SDimitry Andric 42e8d8bef9SDimitry Andric public: 43e8d8bef9SDimitry Andric kmp_gomp_depends_info_t(void **depend) : depend(depend) { 44e8d8bef9SDimitry Andric size_t ndeps = (kmp_intptr_t)depend[0]; 45e8d8bef9SDimitry Andric // GOMP taskdep structure: 46e8d8bef9SDimitry Andric // if depend[0] != 0: 47e8d8bef9SDimitry Andric // depend = [ ndeps | nout | &out | ... | &out | &in | ... | &in ] 48e8d8bef9SDimitry Andric // 49e8d8bef9SDimitry Andric // if depend[0] == 0: 50e8d8bef9SDimitry Andric // depend = [ 0 | ndeps | nout | nmtx | nin | &out | ... | &out | &mtx | 51e8d8bef9SDimitry Andric // ... | &mtx | &in | ... | &in | &depobj | ... | &depobj ] 52e8d8bef9SDimitry Andric if (ndeps) { 53e8d8bef9SDimitry Andric num_out = (kmp_intptr_t)depend[1]; 54e8d8bef9SDimitry Andric num_in = ndeps - num_out; 55349cc55cSDimitry Andric num_mutexinout = num_depobj = 0; 56e8d8bef9SDimitry Andric offset = 2; 57e8d8bef9SDimitry Andric } else { 58e8d8bef9SDimitry Andric ndeps = (kmp_intptr_t)depend[1]; 59e8d8bef9SDimitry Andric num_out = (kmp_intptr_t)depend[2]; 60e8d8bef9SDimitry Andric num_mutexinout = (kmp_intptr_t)depend[3]; 61e8d8bef9SDimitry Andric num_in = (kmp_intptr_t)depend[4]; 62349cc55cSDimitry Andric num_depobj = ndeps - num_out - num_mutexinout - num_in; 63349cc55cSDimitry Andric KMP_ASSERT(num_depobj <= ndeps); 64e8d8bef9SDimitry Andric offset = 5; 65e8d8bef9SDimitry Andric } 66e8d8bef9SDimitry Andric num_deps = static_cast<kmp_int32>(ndeps); 67e8d8bef9SDimitry Andric } 68e8d8bef9SDimitry Andric kmp_int32 get_num_deps() const { return num_deps; } 69e8d8bef9SDimitry Andric kmp_depend_info_t get_kmp_depend(size_t index) const { 70e8d8bef9SDimitry Andric kmp_depend_info_t retval; 71e8d8bef9SDimitry Andric memset(&retval, '\0', sizeof(retval)); 72e8d8bef9SDimitry Andric KMP_ASSERT(index < (size_t)num_deps); 73e8d8bef9SDimitry Andric retval.len = 0; 74e8d8bef9SDimitry Andric // Because inout and out are logically equivalent, 75e8d8bef9SDimitry Andric // use inout and in dependency flags. GOMP does not provide a 76e8d8bef9SDimitry Andric // way to distinguish if user specified out vs. inout. 77e8d8bef9SDimitry Andric if (index < num_out) { 78e8d8bef9SDimitry Andric retval.flags.in = 1; 79e8d8bef9SDimitry Andric retval.flags.out = 1; 80349cc55cSDimitry Andric retval.base_addr = (kmp_intptr_t)depend[offset + index]; 81e8d8bef9SDimitry Andric } else if (index >= num_out && index < (num_out + num_mutexinout)) { 82e8d8bef9SDimitry Andric retval.flags.mtx = 1; 83349cc55cSDimitry Andric retval.base_addr = (kmp_intptr_t)depend[offset + index]; 84349cc55cSDimitry Andric } else if (index >= (num_out + num_mutexinout) && 85349cc55cSDimitry Andric index < (num_out + num_mutexinout + num_in)) { 86e8d8bef9SDimitry Andric retval.flags.in = 1; 87349cc55cSDimitry Andric retval.base_addr = (kmp_intptr_t)depend[offset + index]; 88349cc55cSDimitry Andric } else { 89349cc55cSDimitry Andric // depobj is a two element array (size of elements are size of pointer) 90349cc55cSDimitry Andric // depobj[0] = base_addr 91349cc55cSDimitry Andric // depobj[1] = type (in, out, inout, mutexinoutset, etc.) 92349cc55cSDimitry Andric kmp_intptr_t *depobj = (kmp_intptr_t *)depend[offset + index]; 93349cc55cSDimitry Andric retval.base_addr = depobj[0]; 94349cc55cSDimitry Andric switch (depobj[1]) { 95349cc55cSDimitry Andric case KMP_GOMP_DEPOBJ_IN: 96349cc55cSDimitry Andric retval.flags.in = 1; 97349cc55cSDimitry Andric break; 98349cc55cSDimitry Andric case KMP_GOMP_DEPOBJ_OUT: 99349cc55cSDimitry Andric retval.flags.out = 1; 100349cc55cSDimitry Andric break; 101349cc55cSDimitry Andric case KMP_GOMP_DEPOBJ_INOUT: 102349cc55cSDimitry Andric retval.flags.in = 1; 103349cc55cSDimitry Andric retval.flags.out = 1; 104349cc55cSDimitry Andric break; 105349cc55cSDimitry Andric case KMP_GOMP_DEPOBJ_MTXINOUTSET: 106349cc55cSDimitry Andric retval.flags.mtx = 1; 107349cc55cSDimitry Andric break; 108349cc55cSDimitry Andric default: 109349cc55cSDimitry Andric KMP_FATAL(GompFeatureNotSupported, "Unknown depobj type"); 110349cc55cSDimitry Andric } 111e8d8bef9SDimitry Andric } 112e8d8bef9SDimitry Andric return retval; 113e8d8bef9SDimitry Andric } 114e8d8bef9SDimitry Andric }; 115e8d8bef9SDimitry Andric 1160b57cec5SDimitry Andric #ifdef __cplusplus 1170b57cec5SDimitry Andric extern "C" { 1180b57cec5SDimitry Andric #endif // __cplusplus 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric #define MKLOC(loc, routine) \ 121489b1cf2SDimitry Andric static ident_t loc = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"}; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric #include "kmp_ftn_os.h" 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER)(void) { 1260b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 1270b57cec5SDimitry Andric MKLOC(loc, "GOMP_barrier"); 1280b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_barrier: T#%d\n", gtid)); 1290b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1300b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 1310b57cec5SDimitry Andric if (ompt_enabled.enabled) { 1320b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 1330b57cec5SDimitry Andric ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 1340b57cec5SDimitry Andric } 135e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 1360b57cec5SDimitry Andric #endif 1370b57cec5SDimitry Andric __kmpc_barrier(&loc, gtid); 1380b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1390b57cec5SDimitry Andric if (ompt_enabled.enabled) { 1400b57cec5SDimitry Andric ompt_frame->enter_frame = ompt_data_none; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric #endif 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric // Mutual exclusion 1460b57cec5SDimitry Andric 14774626c16SDimitry Andric // The symbol that icc/ifort generates for unnamed critical sections 1480b57cec5SDimitry Andric // - .gomp_critical_user_ - is defined using .comm in any objects reference it. 1490b57cec5SDimitry Andric // We can't reference it directly here in C code, as the symbol contains a ".". 1500b57cec5SDimitry Andric // 1510b57cec5SDimitry Andric // The RTL contains an assembly language definition of .gomp_critical_user_ 1520b57cec5SDimitry Andric // with another symbol __kmp_unnamed_critical_addr initialized with it's 1530b57cec5SDimitry Andric // address. 1540b57cec5SDimitry Andric extern kmp_critical_name *__kmp_unnamed_critical_addr; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_START)(void) { 1570b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 1580b57cec5SDimitry Andric MKLOC(loc, "GOMP_critical_start"); 1590b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_critical_start: T#%d\n", gtid)); 1600b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1610b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 1620b57cec5SDimitry Andric #endif 1630b57cec5SDimitry Andric __kmpc_critical(&loc, gtid, __kmp_unnamed_critical_addr); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_END)(void) { 1670b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 1680b57cec5SDimitry Andric MKLOC(loc, "GOMP_critical_end"); 1690b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_critical_end: T#%d\n", gtid)); 1700b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1710b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 1720b57cec5SDimitry Andric #endif 1730b57cec5SDimitry Andric __kmpc_end_critical(&loc, gtid, __kmp_unnamed_critical_addr); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_START)(void **pptr) { 1770b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 1780b57cec5SDimitry Andric MKLOC(loc, "GOMP_critical_name_start"); 1790b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_critical_name_start: T#%d\n", gtid)); 1800b57cec5SDimitry Andric __kmpc_critical(&loc, gtid, (kmp_critical_name *)pptr); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_END)(void **pptr) { 1840b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 1850b57cec5SDimitry Andric MKLOC(loc, "GOMP_critical_name_end"); 1860b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_critical_name_end: T#%d\n", gtid)); 1870b57cec5SDimitry Andric __kmpc_end_critical(&loc, gtid, (kmp_critical_name *)pptr); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // The Gnu codegen tries to use locked operations to perform atomic updates 1910b57cec5SDimitry Andric // inline. If it can't, then it calls GOMP_atomic_start() before performing 1920b57cec5SDimitry Andric // the update and GOMP_atomic_end() afterward, regardless of the data type. 1930b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_START)(void) { 1940b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 1950b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid)); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric #if OMPT_SUPPORT 1980b57cec5SDimitry Andric __ompt_thread_assign_wait_id(0); 1990b57cec5SDimitry Andric #endif 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_END)(void) { 2050b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 2060b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_atomic_end: T#%d\n", gtid)); 2070b57cec5SDimitry Andric __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric int KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_START)(void) { 2110b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 2120b57cec5SDimitry Andric MKLOC(loc, "GOMP_single_start"); 2130b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_single_start: T#%d\n", gtid)); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric if (!TCR_4(__kmp_init_parallel)) 2160b57cec5SDimitry Andric __kmp_parallel_initialize(); 2170b57cec5SDimitry Andric __kmp_resume_if_soft_paused(); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // 3rd parameter == FALSE prevents kmp_enter_single from pushing a 2200b57cec5SDimitry Andric // workshare when USE_CHECKS is defined. We need to avoid the push, 2210b57cec5SDimitry Andric // as there is no corresponding GOMP_single_end() call. 2220b57cec5SDimitry Andric kmp_int32 rc = __kmp_enter_single(gtid, &loc, FALSE); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2250b57cec5SDimitry Andric kmp_info_t *this_thr = __kmp_threads[gtid]; 2260b57cec5SDimitry Andric kmp_team_t *team = this_thr->th.th_team; 2270b57cec5SDimitry Andric int tid = __kmp_tid_from_gtid(gtid); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric if (ompt_enabled.enabled) { 2300b57cec5SDimitry Andric if (rc) { 2310b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 2320b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 2330b57cec5SDimitry Andric ompt_work_single_executor, ompt_scope_begin, 2340b57cec5SDimitry Andric &(team->t.ompt_team_info.parallel_data), 2350b57cec5SDimitry Andric &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data), 2360b57cec5SDimitry Andric 1, OMPT_GET_RETURN_ADDRESS(0)); 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric } else { 2390b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_work) { 2400b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 2410b57cec5SDimitry Andric ompt_work_single_other, ompt_scope_begin, 2420b57cec5SDimitry Andric &(team->t.ompt_team_info.parallel_data), 2430b57cec5SDimitry Andric &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data), 2440b57cec5SDimitry Andric 1, OMPT_GET_RETURN_ADDRESS(0)); 2450b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_work)( 2460b57cec5SDimitry Andric ompt_work_single_other, ompt_scope_end, 2470b57cec5SDimitry Andric &(team->t.ompt_team_info.parallel_data), 2480b57cec5SDimitry Andric &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data), 2490b57cec5SDimitry Andric 1, OMPT_GET_RETURN_ADDRESS(0)); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric #endif 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric return rc; 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_START)(void) { 2590b57cec5SDimitry Andric void *retval; 2600b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 2610b57cec5SDimitry Andric MKLOC(loc, "GOMP_single_copy_start"); 2620b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_single_copy_start: T#%d\n", gtid)); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric if (!TCR_4(__kmp_init_parallel)) 2650b57cec5SDimitry Andric __kmp_parallel_initialize(); 2660b57cec5SDimitry Andric __kmp_resume_if_soft_paused(); 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric // If this is the first thread to enter, return NULL. The generated code will 2690b57cec5SDimitry Andric // then call GOMP_single_copy_end() for this thread only, with the 2700b57cec5SDimitry Andric // copyprivate data pointer as an argument. 2710b57cec5SDimitry Andric if (__kmp_enter_single(gtid, &loc, FALSE)) 2720b57cec5SDimitry Andric return NULL; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric // Wait for the first thread to set the copyprivate data pointer, 2750b57cec5SDimitry Andric // and for all other threads to reach this point. 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2780b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 2790b57cec5SDimitry Andric if (ompt_enabled.enabled) { 2800b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 2810b57cec5SDimitry Andric ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 2820b57cec5SDimitry Andric } 283e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 2840b57cec5SDimitry Andric #endif 2850b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // Retrieve the value of the copyprivate data point, and wait for all 2880b57cec5SDimitry Andric // threads to do likewise, then return. 2890b57cec5SDimitry Andric retval = __kmp_team_from_gtid(gtid)->t.t_copypriv_data; 290e8d8bef9SDimitry Andric { 2910b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2920b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 2930b57cec5SDimitry Andric #endif 2940b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 295e8d8bef9SDimitry Andric } 2960b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2970b57cec5SDimitry Andric if (ompt_enabled.enabled) { 2980b57cec5SDimitry Andric ompt_frame->enter_frame = ompt_data_none; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric #endif 3010b57cec5SDimitry Andric return retval; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_END)(void *data) { 3050b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 3060b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_single_copy_end: T#%d\n", gtid)); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // Set the copyprivate data pointer fo the team, then hit the barrier so that 3090b57cec5SDimitry Andric // the other threads will continue on and read it. Hit another barrier before 3100b57cec5SDimitry Andric // continuing, so that the know that the copyprivate data pointer has been 3110b57cec5SDimitry Andric // propagated to all threads before trying to reuse the t_copypriv_data field. 3120b57cec5SDimitry Andric __kmp_team_from_gtid(gtid)->t.t_copypriv_data = data; 3130b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 3140b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 3150b57cec5SDimitry Andric if (ompt_enabled.enabled) { 3160b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 3170b57cec5SDimitry Andric ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 3180b57cec5SDimitry Andric } 319e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 3200b57cec5SDimitry Andric #endif 3210b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 322e8d8bef9SDimitry Andric { 3230b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 3240b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 3250b57cec5SDimitry Andric #endif 3260b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 327e8d8bef9SDimitry Andric } 3280b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 3290b57cec5SDimitry Andric if (ompt_enabled.enabled) { 3300b57cec5SDimitry Andric ompt_frame->enter_frame = ompt_data_none; 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric #endif 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_START)(void) { 3360b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 3370b57cec5SDimitry Andric MKLOC(loc, "GOMP_ordered_start"); 3380b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid)); 3390b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 3400b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 3410b57cec5SDimitry Andric #endif 3420b57cec5SDimitry Andric __kmpc_ordered(&loc, gtid); 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_END)(void) { 3460b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 3470b57cec5SDimitry Andric MKLOC(loc, "GOMP_ordered_end"); 3480b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid)); 3490b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 3500b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 3510b57cec5SDimitry Andric #endif 3520b57cec5SDimitry Andric __kmpc_end_ordered(&loc, gtid); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric // Dispatch macro defs 3560b57cec5SDimitry Andric // 3570b57cec5SDimitry Andric // They come in two flavors: 64-bit unsigned, and either 32-bit signed 3580b57cec5SDimitry Andric // (IA-32 architecture) or 64-bit signed (Intel(R) 64). 3590b57cec5SDimitry Andric 3601db9f3b2SDimitry Andric #if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS || KMP_ARCH_WASM || \ 361*0fca6ea1SDimitry Andric KMP_ARCH_PPC || KMP_ARCH_AARCH64_32 3620b57cec5SDimitry Andric #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4 3630b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4 3640b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4 3650b57cec5SDimitry Andric #else 3660b57cec5SDimitry Andric #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_8 3670b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_8 3680b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_8 3690b57cec5SDimitry Andric #endif /* KMP_ARCH_X86 */ 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric #define KMP_DISPATCH_INIT_ULL __kmp_aux_dispatch_init_8u 3720b57cec5SDimitry Andric #define KMP_DISPATCH_FINI_CHUNK_ULL __kmp_aux_dispatch_fini_chunk_8u 3730b57cec5SDimitry Andric #define KMP_DISPATCH_NEXT_ULL __kmpc_dispatch_next_8u 3740b57cec5SDimitry Andric 3755ffd83dbSDimitry Andric // The parallel construct 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric #ifndef KMP_DEBUG 3780b57cec5SDimitry Andric static 3790b57cec5SDimitry Andric #endif /* KMP_DEBUG */ 3800b57cec5SDimitry Andric void 3810b57cec5SDimitry Andric __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), 3820b57cec5SDimitry Andric void *data) { 3830b57cec5SDimitry Andric #if OMPT_SUPPORT 3840b57cec5SDimitry Andric kmp_info_t *thr; 3850b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 3860b57cec5SDimitry Andric ompt_state_t enclosing_state; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric if (ompt_enabled.enabled) { 3890b57cec5SDimitry Andric // get pointer to thread data structure 3900b57cec5SDimitry Andric thr = __kmp_threads[*gtid]; 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // save enclosing task state; set current state for task 3930b57cec5SDimitry Andric enclosing_state = thr->th.ompt_thread_info.state; 3940b57cec5SDimitry Andric thr->th.ompt_thread_info.state = ompt_state_work_parallel; 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric // set task frame 3970b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 3980b57cec5SDimitry Andric ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric #endif 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric task(data); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric #if OMPT_SUPPORT 4050b57cec5SDimitry Andric if (ompt_enabled.enabled) { 4060b57cec5SDimitry Andric // clear task frame 4070b57cec5SDimitry Andric ompt_frame->exit_frame = ompt_data_none; 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric // restore enclosing state 4100b57cec5SDimitry Andric thr->th.ompt_thread_info.state = enclosing_state; 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric #endif 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric #ifndef KMP_DEBUG 4160b57cec5SDimitry Andric static 4170b57cec5SDimitry Andric #endif /* KMP_DEBUG */ 4180b57cec5SDimitry Andric void 4190b57cec5SDimitry Andric __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, 4200b57cec5SDimitry Andric void (*task)(void *), void *data, 4210b57cec5SDimitry Andric unsigned num_threads, ident_t *loc, 4220b57cec5SDimitry Andric enum sched_type schedule, long start, 4230b57cec5SDimitry Andric long end, long incr, 4240b57cec5SDimitry Andric long chunk_size) { 4255ffd83dbSDimitry Andric // Initialize the loop worksharing construct. 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric KMP_DISPATCH_INIT(loc, *gtid, schedule, start, end, incr, chunk_size, 4280b57cec5SDimitry Andric schedule != kmp_sch_static); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric #if OMPT_SUPPORT 4310b57cec5SDimitry Andric kmp_info_t *thr; 4320b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 4330b57cec5SDimitry Andric ompt_state_t enclosing_state; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric if (ompt_enabled.enabled) { 4360b57cec5SDimitry Andric thr = __kmp_threads[*gtid]; 4370b57cec5SDimitry Andric // save enclosing task state; set current state for task 4380b57cec5SDimitry Andric enclosing_state = thr->th.ompt_thread_info.state; 4390b57cec5SDimitry Andric thr->th.ompt_thread_info.state = ompt_state_work_parallel; 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric // set task frame 4420b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 4430b57cec5SDimitry Andric ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric #endif 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric // Now invoke the microtask. 4480b57cec5SDimitry Andric task(data); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric #if OMPT_SUPPORT 4510b57cec5SDimitry Andric if (ompt_enabled.enabled) { 4520b57cec5SDimitry Andric // clear task frame 4530b57cec5SDimitry Andric ompt_frame->exit_frame = ompt_data_none; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric // reset enclosing state 4560b57cec5SDimitry Andric thr->th.ompt_thread_info.state = enclosing_state; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric #endif 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 461e8d8bef9SDimitry Andric static void __kmp_GOMP_fork_call(ident_t *loc, int gtid, unsigned num_threads, 462e8d8bef9SDimitry Andric unsigned flags, void (*unwrapped_task)(void *), 4630b57cec5SDimitry Andric microtask_t wrapper, int argc, ...) { 4640b57cec5SDimitry Andric int rc; 4650b57cec5SDimitry Andric kmp_info_t *thr = __kmp_threads[gtid]; 4660b57cec5SDimitry Andric kmp_team_t *team = thr->th.th_team; 4670b57cec5SDimitry Andric int tid = __kmp_tid_from_gtid(gtid); 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric va_list ap; 4700b57cec5SDimitry Andric va_start(ap, argc); 4710b57cec5SDimitry Andric 472e8d8bef9SDimitry Andric if (num_threads != 0) 473e8d8bef9SDimitry Andric __kmp_push_num_threads(loc, gtid, num_threads); 474e8d8bef9SDimitry Andric if (flags != 0) 475e8d8bef9SDimitry Andric __kmp_push_proc_bind(loc, gtid, (kmp_proc_bind_t)flags); 4760b57cec5SDimitry Andric rc = __kmp_fork_call(loc, gtid, fork_context_gnu, argc, wrapper, 47716794618SDimitry Andric __kmp_invoke_task_func, kmp_va_addr_of(ap)); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric va_end(ap); 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric if (rc) { 4820b57cec5SDimitry Andric __kmp_run_before_invoked_task(gtid, tid, thr, team); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric #if OMPT_SUPPORT 4860b57cec5SDimitry Andric int ompt_team_size; 4870b57cec5SDimitry Andric if (ompt_enabled.enabled) { 4880b57cec5SDimitry Andric ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL); 4890b57cec5SDimitry Andric ompt_task_info_t *task_info = __ompt_get_task_info_object(0); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric // implicit task callback 4920b57cec5SDimitry Andric if (ompt_enabled.ompt_callback_implicit_task) { 4930b57cec5SDimitry Andric ompt_team_size = __kmp_team_from_gtid(gtid)->t.t_nproc; 4940b57cec5SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_implicit_task)( 4950b57cec5SDimitry Andric ompt_scope_begin, &(team_info->parallel_data), 496fe6060f1SDimitry Andric &(task_info->task_data), ompt_team_size, __kmp_tid_from_gtid(gtid), 497fe6060f1SDimitry Andric ompt_task_implicit); // TODO: Can this be ompt_task_initial? 4980b57cec5SDimitry Andric task_info->thread_num = __kmp_tid_from_gtid(gtid); 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric thr->th.ompt_thread_info.state = ompt_state_work_parallel; 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric #endif 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *), 5060b57cec5SDimitry Andric void *data, 5070b57cec5SDimitry Andric unsigned num_threads) { 5080b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric #if OMPT_SUPPORT 5110b57cec5SDimitry Andric ompt_frame_t *parent_frame, *frame; 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric if (ompt_enabled.enabled) { 5140b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL); 5150b57cec5SDimitry Andric parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 5160b57cec5SDimitry Andric } 517e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 5180b57cec5SDimitry Andric #endif 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric MKLOC(loc, "GOMP_parallel_start"); 5210b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_start: T#%d\n", gtid)); 522e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task, 5230b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, 5240b57cec5SDimitry Andric data); 5250b57cec5SDimitry Andric #if OMPT_SUPPORT 5260b57cec5SDimitry Andric if (ompt_enabled.enabled) { 5270b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &frame, NULL, NULL); 5280b57cec5SDimitry Andric frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric #endif 531fe6060f1SDimitry Andric #if OMPD_SUPPORT 532fe6060f1SDimitry Andric if (ompd_state & OMPD_ENABLE_BP) 533fe6060f1SDimitry Andric ompd_bp_parallel_begin(); 534fe6060f1SDimitry Andric #endif 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(void) { 5380b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 5390b57cec5SDimitry Andric kmp_info_t *thr; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric thr = __kmp_threads[gtid]; 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric MKLOC(loc, "GOMP_parallel_end"); 5440b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_end: T#%d\n", gtid)); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric if (!thr->th.th_team->t.t_serialized) { 5470b57cec5SDimitry Andric __kmp_run_after_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr, 5480b57cec5SDimitry Andric thr->th.th_team); 549e8d8bef9SDimitry Andric } 5500b57cec5SDimitry Andric #if OMPT_SUPPORT 5510b57cec5SDimitry Andric if (ompt_enabled.enabled) { 5520b57cec5SDimitry Andric // Implicit task is finished here, in the barrier we might schedule 5530b57cec5SDimitry Andric // deferred tasks, 5540b57cec5SDimitry Andric // these don't see the implicit task on the stack 5550b57cec5SDimitry Andric OMPT_CUR_TASK_INFO(thr)->frame.exit_frame = ompt_data_none; 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric #endif 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric __kmp_join_call(&loc, gtid 5600b57cec5SDimitry Andric #if OMPT_SUPPORT 5610b57cec5SDimitry Andric , 5620b57cec5SDimitry Andric fork_context_gnu 5630b57cec5SDimitry Andric #endif 5640b57cec5SDimitry Andric ); 565fe6060f1SDimitry Andric #if OMPD_SUPPORT 566fe6060f1SDimitry Andric if (ompd_state & OMPD_ENABLE_BP) 567fe6060f1SDimitry Andric ompd_bp_parallel_end(); 568fe6060f1SDimitry Andric #endif 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric // Loop worksharing constructs 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric // The Gnu codegen passes in an exclusive upper bound for the overall range, 5740b57cec5SDimitry Andric // but the libguide dispatch code expects an inclusive upper bound, hence the 5750b57cec5SDimitry Andric // "end - incr" 5th argument to KMP_DISPATCH_INIT (and the " ub - str" 11th 5760b57cec5SDimitry Andric // argument to __kmp_GOMP_fork_call). 5770b57cec5SDimitry Andric // 5780b57cec5SDimitry Andric // Conversely, KMP_DISPATCH_NEXT returns and inclusive upper bound in *p_ub, 579480093f4SDimitry Andric // but the Gnu codegen expects an exclusive upper bound, so the adjustment 580480093f4SDimitry Andric // "*p_ub += stride" compensates for the discrepancy. 5810b57cec5SDimitry Andric // 5820b57cec5SDimitry Andric // Correction: the gnu codegen always adjusts the upper bound by +-1, not the 5830b57cec5SDimitry Andric // stride value. We adjust the dispatch parameters accordingly (by +-1), but 5840b57cec5SDimitry Andric // we still adjust p_ub by the actual stride value. 5850b57cec5SDimitry Andric // 5860b57cec5SDimitry Andric // The "runtime" versions do not take a chunk_sz parameter. 5870b57cec5SDimitry Andric // 5880b57cec5SDimitry Andric // The profile lib cannot support construct checking of unordered loops that 5890b57cec5SDimitry Andric // are predetermined by the compiler to be statically scheduled, as the gcc 5900b57cec5SDimitry Andric // codegen will not always emit calls to GOMP_loop_static_next() to get the 5910b57cec5SDimitry Andric // next iteration. Instead, it emits inline code to call omp_get_thread_num() 5920b57cec5SDimitry Andric // num and calculate the iteration space using the result. It doesn't do this 5930b57cec5SDimitry Andric // with ordered static loop, so they can be checked. 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric #if OMPT_SUPPORT 5960b57cec5SDimitry Andric #define IF_OMPT_SUPPORT(code) code 5970b57cec5SDimitry Andric #else 5980b57cec5SDimitry Andric #define IF_OMPT_SUPPORT(code) 5990b57cec5SDimitry Andric #endif 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric #define LOOP_START(func, schedule) \ 6020b57cec5SDimitry Andric int func(long lb, long ub, long str, long chunk_sz, long *p_lb, \ 6030b57cec5SDimitry Andric long *p_ub) { \ 6040b57cec5SDimitry Andric int status; \ 6050b57cec5SDimitry Andric long stride; \ 6060b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 6070b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 6080b57cec5SDimitry Andric KA_TRACE( \ 6090b57cec5SDimitry Andric 20, \ 6100b57cec5SDimitry Andric (KMP_STR( \ 6110b57cec5SDimitry Andric func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 6120b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 6130b57cec5SDimitry Andric \ 6140b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 615e8d8bef9SDimitry Andric { \ 6160b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 6170b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 6180b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 6190b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 620e8d8bef9SDimitry Andric } \ 621e8d8bef9SDimitry Andric { \ 6220b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 6230b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 6240b57cec5SDimitry Andric (kmp_int *)p_ub, (kmp_int *)&stride); \ 625e8d8bef9SDimitry Andric } \ 6260b57cec5SDimitry Andric if (status) { \ 6270b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 6280b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 6290b57cec5SDimitry Andric } \ 6300b57cec5SDimitry Andric } else { \ 6310b57cec5SDimitry Andric status = 0; \ 6320b57cec5SDimitry Andric } \ 6330b57cec5SDimitry Andric \ 6340b57cec5SDimitry Andric KA_TRACE( \ 6350b57cec5SDimitry Andric 20, \ 6360b57cec5SDimitry Andric (KMP_STR( \ 6370b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 6380b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 6390b57cec5SDimitry Andric return status; \ 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric #define LOOP_RUNTIME_START(func, schedule) \ 6430b57cec5SDimitry Andric int func(long lb, long ub, long str, long *p_lb, long *p_ub) { \ 6440b57cec5SDimitry Andric int status; \ 6450b57cec5SDimitry Andric long stride; \ 6460b57cec5SDimitry Andric long chunk_sz = 0; \ 6470b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 6480b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 6490b57cec5SDimitry Andric KA_TRACE( \ 6500b57cec5SDimitry Andric 20, \ 6510b57cec5SDimitry Andric (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \ 6520b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 6530b57cec5SDimitry Andric \ 6540b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 655e8d8bef9SDimitry Andric { \ 6560b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 6570b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 658e8d8bef9SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 659e8d8bef9SDimitry Andric TRUE); \ 660e8d8bef9SDimitry Andric } \ 661e8d8bef9SDimitry Andric { \ 6620b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 6630b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 6640b57cec5SDimitry Andric (kmp_int *)p_ub, (kmp_int *)&stride); \ 665e8d8bef9SDimitry Andric } \ 6660b57cec5SDimitry Andric if (status) { \ 6670b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 6680b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 6690b57cec5SDimitry Andric } \ 6700b57cec5SDimitry Andric } else { \ 6710b57cec5SDimitry Andric status = 0; \ 6720b57cec5SDimitry Andric } \ 6730b57cec5SDimitry Andric \ 6740b57cec5SDimitry Andric KA_TRACE( \ 6750b57cec5SDimitry Andric 20, \ 6760b57cec5SDimitry Andric (KMP_STR( \ 6770b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 6780b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 6790b57cec5SDimitry Andric return status; \ 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric #define KMP_DOACROSS_FINI(status, gtid) \ 6830b57cec5SDimitry Andric if (!status && __kmp_threads[gtid]->th.th_dispatch->th_doacross_flags) { \ 6840b57cec5SDimitry Andric __kmpc_doacross_fini(NULL, gtid); \ 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric #define LOOP_NEXT(func, fini_code) \ 6880b57cec5SDimitry Andric int func(long *p_lb, long *p_ub) { \ 6890b57cec5SDimitry Andric int status; \ 6900b57cec5SDimitry Andric long stride; \ 6910b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); \ 6920b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 6930b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid)); \ 6940b57cec5SDimitry Andric \ 6950b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 6960b57cec5SDimitry Andric fini_code status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 6970b57cec5SDimitry Andric (kmp_int *)p_ub, (kmp_int *)&stride); \ 6980b57cec5SDimitry Andric if (status) { \ 6990b57cec5SDimitry Andric *p_ub += (stride > 0) ? 1 : -1; \ 7000b57cec5SDimitry Andric } \ 7010b57cec5SDimitry Andric KMP_DOACROSS_FINI(status, gtid) \ 7020b57cec5SDimitry Andric \ 7030b57cec5SDimitry Andric KA_TRACE( \ 7040b57cec5SDimitry Andric 20, \ 7050b57cec5SDimitry Andric (KMP_STR(func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, stride 0x%lx, " \ 7060b57cec5SDimitry Andric "returning %d\n", \ 7070b57cec5SDimitry Andric gtid, *p_lb, *p_ub, stride, status)); \ 7080b57cec5SDimitry Andric return status; \ 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START), kmp_sch_static) 7120b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT), {}) 7130b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START), 7140b57cec5SDimitry Andric kmp_sch_dynamic_chunked) 715489b1cf2SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START), 716489b1cf2SDimitry Andric kmp_sch_dynamic_chunked) 7170b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT), {}) 718489b1cf2SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT), {}) 7190b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START), 7200b57cec5SDimitry Andric kmp_sch_guided_chunked) 721489b1cf2SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START), 722489b1cf2SDimitry Andric kmp_sch_guided_chunked) 7230b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT), {}) 724489b1cf2SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT), {}) 7250b57cec5SDimitry Andric LOOP_RUNTIME_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START), 7260b57cec5SDimitry Andric kmp_sch_runtime) 7270b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT), {}) 7285ffd83dbSDimitry Andric LOOP_RUNTIME_START( 7295ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START), 7305ffd83dbSDimitry Andric kmp_sch_runtime) 7315ffd83dbSDimitry Andric LOOP_RUNTIME_START( 7325ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START), 7335ffd83dbSDimitry Andric kmp_sch_runtime) 7345ffd83dbSDimitry Andric LOOP_NEXT( 7355ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT), {}) 7365ffd83dbSDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT), {}) 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START), 7390b57cec5SDimitry Andric kmp_ord_static) 7400b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT), 7410b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 7420b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START), 7430b57cec5SDimitry Andric kmp_ord_dynamic_chunked) 7440b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT), 7450b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 7460b57cec5SDimitry Andric LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START), 7470b57cec5SDimitry Andric kmp_ord_guided_chunked) 7480b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT), 7490b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 7500b57cec5SDimitry Andric LOOP_RUNTIME_START( 7510b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START), 7520b57cec5SDimitry Andric kmp_ord_runtime) 7530b57cec5SDimitry Andric LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT), 7540b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); }) 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric #define LOOP_DOACROSS_START(func, schedule) \ 7570b57cec5SDimitry Andric bool func(unsigned ncounts, long *counts, long chunk_sz, long *p_lb, \ 7580b57cec5SDimitry Andric long *p_ub) { \ 7590b57cec5SDimitry Andric int status; \ 7600b57cec5SDimitry Andric long stride, lb, ub, str; \ 7610b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 7620b57cec5SDimitry Andric struct kmp_dim *dims = \ 7630b57cec5SDimitry Andric (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \ 7640b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 7650b57cec5SDimitry Andric for (unsigned i = 0; i < ncounts; ++i) { \ 7660b57cec5SDimitry Andric dims[i].lo = 0; \ 7670b57cec5SDimitry Andric dims[i].up = counts[i] - 1; \ 7680b57cec5SDimitry Andric dims[i].st = 1; \ 7690b57cec5SDimitry Andric } \ 7700b57cec5SDimitry Andric __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \ 7710b57cec5SDimitry Andric lb = 0; \ 7720b57cec5SDimitry Andric ub = counts[0]; \ 7730b57cec5SDimitry Andric str = 1; \ 7740b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d, ncounts %u, lb 0x%lx, ub 0x%lx, str " \ 7750b57cec5SDimitry Andric "0x%lx, chunk_sz " \ 7760b57cec5SDimitry Andric "0x%lx\n", \ 7770b57cec5SDimitry Andric gtid, ncounts, lb, ub, str, chunk_sz)); \ 7780b57cec5SDimitry Andric \ 7790b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 7800b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 7810b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 7820b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 7830b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 7840b57cec5SDimitry Andric (kmp_int *)p_ub, (kmp_int *)&stride); \ 7850b57cec5SDimitry Andric if (status) { \ 7860b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 7870b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 7880b57cec5SDimitry Andric } \ 7890b57cec5SDimitry Andric } else { \ 7900b57cec5SDimitry Andric status = 0; \ 7910b57cec5SDimitry Andric } \ 7920b57cec5SDimitry Andric KMP_DOACROSS_FINI(status, gtid); \ 7930b57cec5SDimitry Andric \ 7940b57cec5SDimitry Andric KA_TRACE( \ 7950b57cec5SDimitry Andric 20, \ 7960b57cec5SDimitry Andric (KMP_STR( \ 7970b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 7980b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 7990b57cec5SDimitry Andric __kmp_free(dims); \ 8000b57cec5SDimitry Andric return status; \ 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric #define LOOP_DOACROSS_RUNTIME_START(func, schedule) \ 8040b57cec5SDimitry Andric int func(unsigned ncounts, long *counts, long *p_lb, long *p_ub) { \ 8050b57cec5SDimitry Andric int status; \ 8060b57cec5SDimitry Andric long stride, lb, ub, str; \ 8070b57cec5SDimitry Andric long chunk_sz = 0; \ 8080b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 8090b57cec5SDimitry Andric struct kmp_dim *dims = \ 8100b57cec5SDimitry Andric (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \ 8110b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 8120b57cec5SDimitry Andric for (unsigned i = 0; i < ncounts; ++i) { \ 8130b57cec5SDimitry Andric dims[i].lo = 0; \ 8140b57cec5SDimitry Andric dims[i].up = counts[i] - 1; \ 8150b57cec5SDimitry Andric dims[i].st = 1; \ 8160b57cec5SDimitry Andric } \ 8170b57cec5SDimitry Andric __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \ 8180b57cec5SDimitry Andric lb = 0; \ 8190b57cec5SDimitry Andric ub = counts[0]; \ 8200b57cec5SDimitry Andric str = 1; \ 8210b57cec5SDimitry Andric KA_TRACE( \ 8220b57cec5SDimitry Andric 20, \ 8230b57cec5SDimitry Andric (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \ 8240b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 8250b57cec5SDimitry Andric \ 8260b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 8270b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 8280b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, TRUE); \ 8290b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \ 8300b57cec5SDimitry Andric (kmp_int *)p_ub, (kmp_int *)&stride); \ 8310b57cec5SDimitry Andric if (status) { \ 8320b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 8330b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 8340b57cec5SDimitry Andric } \ 8350b57cec5SDimitry Andric } else { \ 8360b57cec5SDimitry Andric status = 0; \ 8370b57cec5SDimitry Andric } \ 8380b57cec5SDimitry Andric KMP_DOACROSS_FINI(status, gtid); \ 8390b57cec5SDimitry Andric \ 8400b57cec5SDimitry Andric KA_TRACE( \ 8410b57cec5SDimitry Andric 20, \ 8420b57cec5SDimitry Andric (KMP_STR( \ 8430b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \ 8440b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 8450b57cec5SDimitry Andric __kmp_free(dims); \ 8460b57cec5SDimitry Andric return status; \ 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric LOOP_DOACROSS_START( 8500b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START), 8510b57cec5SDimitry Andric kmp_sch_static) 8520b57cec5SDimitry Andric LOOP_DOACROSS_START( 8530b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START), 8540b57cec5SDimitry Andric kmp_sch_dynamic_chunked) 8550b57cec5SDimitry Andric LOOP_DOACROSS_START( 8560b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START), 8570b57cec5SDimitry Andric kmp_sch_guided_chunked) 8580b57cec5SDimitry Andric LOOP_DOACROSS_RUNTIME_START( 8590b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START), 8600b57cec5SDimitry Andric kmp_sch_runtime) 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END)(void) { 8630b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 8640b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_loop_end: T#%d\n", gtid)) 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 8670b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 8680b57cec5SDimitry Andric if (ompt_enabled.enabled) { 8690b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 8700b57cec5SDimitry Andric ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 8710b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 8720b57cec5SDimitry Andric } 8730b57cec5SDimitry Andric #endif 8740b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 8750b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 8760b57cec5SDimitry Andric if (ompt_enabled.enabled) { 8770b57cec5SDimitry Andric ompt_frame->enter_frame = ompt_data_none; 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric #endif 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_loop_end exit: T#%d\n", gtid)) 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_NOWAIT)(void) { 8850b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_loop_end_nowait: T#%d\n", __kmp_get_gtid())) 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric // Unsigned long long loop worksharing constructs 8890b57cec5SDimitry Andric // 8900b57cec5SDimitry Andric // These are new with gcc 4.4 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric #define LOOP_START_ULL(func, schedule) \ 8930b57cec5SDimitry Andric int func(int up, unsigned long long lb, unsigned long long ub, \ 8940b57cec5SDimitry Andric unsigned long long str, unsigned long long chunk_sz, \ 8950b57cec5SDimitry Andric unsigned long long *p_lb, unsigned long long *p_ub) { \ 8960b57cec5SDimitry Andric int status; \ 8970b57cec5SDimitry Andric long long str2 = up ? ((long long)str) : -((long long)str); \ 8980b57cec5SDimitry Andric long long stride; \ 8990b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 9000b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 9010b57cec5SDimitry Andric \ 9020b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str " \ 9030b57cec5SDimitry Andric "0x%llx, chunk_sz 0x%llx\n", \ 9040b57cec5SDimitry Andric gtid, up, lb, ub, str, chunk_sz)); \ 9050b57cec5SDimitry Andric \ 9060b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 9070b57cec5SDimitry Andric KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 9080b57cec5SDimitry Andric (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \ 9090b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 9100b57cec5SDimitry Andric status = \ 9110b57cec5SDimitry Andric KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 9120b57cec5SDimitry Andric (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 9130b57cec5SDimitry Andric if (status) { \ 9140b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str2); \ 9150b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 9160b57cec5SDimitry Andric } \ 9170b57cec5SDimitry Andric } else { \ 9180b57cec5SDimitry Andric status = 0; \ 9190b57cec5SDimitry Andric } \ 9200b57cec5SDimitry Andric \ 9210b57cec5SDimitry Andric KA_TRACE( \ 9220b57cec5SDimitry Andric 20, \ 9230b57cec5SDimitry Andric (KMP_STR( \ 9240b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 9250b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 9260b57cec5SDimitry Andric return status; \ 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric #define LOOP_RUNTIME_START_ULL(func, schedule) \ 9300b57cec5SDimitry Andric int func(int up, unsigned long long lb, unsigned long long ub, \ 9310b57cec5SDimitry Andric unsigned long long str, unsigned long long *p_lb, \ 9320b57cec5SDimitry Andric unsigned long long *p_ub) { \ 9330b57cec5SDimitry Andric int status; \ 9340b57cec5SDimitry Andric long long str2 = up ? ((long long)str) : -((long long)str); \ 9350b57cec5SDimitry Andric unsigned long long stride; \ 9360b57cec5SDimitry Andric unsigned long long chunk_sz = 0; \ 9370b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 9380b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 9390b57cec5SDimitry Andric \ 9400b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str " \ 9410b57cec5SDimitry Andric "0x%llx, chunk_sz 0x%llx\n", \ 9420b57cec5SDimitry Andric gtid, up, lb, ub, str, chunk_sz)); \ 9430b57cec5SDimitry Andric \ 9440b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 9450b57cec5SDimitry Andric KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 9460b57cec5SDimitry Andric (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \ 9470b57cec5SDimitry Andric TRUE); \ 9480b57cec5SDimitry Andric status = \ 9490b57cec5SDimitry Andric KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 9500b57cec5SDimitry Andric (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 9510b57cec5SDimitry Andric if (status) { \ 9520b57cec5SDimitry Andric KMP_DEBUG_ASSERT((long long)stride == str2); \ 9530b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 9540b57cec5SDimitry Andric } \ 9550b57cec5SDimitry Andric } else { \ 9560b57cec5SDimitry Andric status = 0; \ 9570b57cec5SDimitry Andric } \ 9580b57cec5SDimitry Andric \ 9590b57cec5SDimitry Andric KA_TRACE( \ 9600b57cec5SDimitry Andric 20, \ 9610b57cec5SDimitry Andric (KMP_STR( \ 9620b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 9630b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 9640b57cec5SDimitry Andric return status; \ 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric #define LOOP_NEXT_ULL(func, fini_code) \ 9680b57cec5SDimitry Andric int func(unsigned long long *p_lb, unsigned long long *p_ub) { \ 9690b57cec5SDimitry Andric int status; \ 9700b57cec5SDimitry Andric long long stride; \ 9710b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); \ 9720b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 9730b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid)); \ 9740b57cec5SDimitry Andric \ 9750b57cec5SDimitry Andric fini_code status = \ 9760b57cec5SDimitry Andric KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 9770b57cec5SDimitry Andric (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 9780b57cec5SDimitry Andric if (status) { \ 9790b57cec5SDimitry Andric *p_ub += (stride > 0) ? 1 : -1; \ 9800b57cec5SDimitry Andric } \ 9810b57cec5SDimitry Andric \ 9820b57cec5SDimitry Andric KA_TRACE( \ 9830b57cec5SDimitry Andric 20, \ 9840b57cec5SDimitry Andric (KMP_STR( \ 9850b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, stride 0x%llx, " \ 9860b57cec5SDimitry Andric "returning %d\n", \ 9870b57cec5SDimitry Andric gtid, *p_lb, *p_ub, stride, status)); \ 9880b57cec5SDimitry Andric return status; \ 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START), 9920b57cec5SDimitry Andric kmp_sch_static) 9930b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT), {}) 9940b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START), 9950b57cec5SDimitry Andric kmp_sch_dynamic_chunked) 9960b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT), {}) 9970b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START), 9980b57cec5SDimitry Andric kmp_sch_guided_chunked) 9990b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT), {}) 1000489b1cf2SDimitry Andric LOOP_START_ULL( 1001489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START), 1002489b1cf2SDimitry Andric kmp_sch_dynamic_chunked) 1003489b1cf2SDimitry Andric LOOP_NEXT_ULL( 1004489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT), {}) 1005489b1cf2SDimitry Andric LOOP_START_ULL( 1006489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START), 1007489b1cf2SDimitry Andric kmp_sch_guided_chunked) 1008489b1cf2SDimitry Andric LOOP_NEXT_ULL( 1009489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT), {}) 10100b57cec5SDimitry Andric LOOP_RUNTIME_START_ULL( 10110b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START), kmp_sch_runtime) 10120b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT), {}) 10135ffd83dbSDimitry Andric LOOP_RUNTIME_START_ULL( 10145ffd83dbSDimitry Andric KMP_EXPAND_NAME( 10155ffd83dbSDimitry Andric KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START), 10165ffd83dbSDimitry Andric kmp_sch_runtime) 10175ffd83dbSDimitry Andric LOOP_RUNTIME_START_ULL( 10185ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START), 10195ffd83dbSDimitry Andric kmp_sch_runtime) 10205ffd83dbSDimitry Andric LOOP_NEXT_ULL( 10215ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT), 10225ffd83dbSDimitry Andric {}) 10235ffd83dbSDimitry Andric LOOP_NEXT_ULL( 10245ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT), {}) 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START), 10270b57cec5SDimitry Andric kmp_ord_static) 10280b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT), 10290b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 10300b57cec5SDimitry Andric LOOP_START_ULL( 10310b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START), 10320b57cec5SDimitry Andric kmp_ord_dynamic_chunked) 10330b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT), 10340b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 10350b57cec5SDimitry Andric LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START), 10360b57cec5SDimitry Andric kmp_ord_guided_chunked) 10370b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT), 10380b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 10390b57cec5SDimitry Andric LOOP_RUNTIME_START_ULL( 10400b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START), 10410b57cec5SDimitry Andric kmp_ord_runtime) 10420b57cec5SDimitry Andric LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT), 10430b57cec5SDimitry Andric { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); }) 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric #define LOOP_DOACROSS_START_ULL(func, schedule) \ 10460b57cec5SDimitry Andric int func(unsigned ncounts, unsigned long long *counts, \ 10470b57cec5SDimitry Andric unsigned long long chunk_sz, unsigned long long *p_lb, \ 10480b57cec5SDimitry Andric unsigned long long *p_ub) { \ 10490b57cec5SDimitry Andric int status; \ 10500b57cec5SDimitry Andric long long stride, str, lb, ub; \ 10510b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 10520b57cec5SDimitry Andric struct kmp_dim *dims = \ 10530b57cec5SDimitry Andric (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \ 10540b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 10550b57cec5SDimitry Andric for (unsigned i = 0; i < ncounts; ++i) { \ 10560b57cec5SDimitry Andric dims[i].lo = 0; \ 10570b57cec5SDimitry Andric dims[i].up = counts[i] - 1; \ 10580b57cec5SDimitry Andric dims[i].st = 1; \ 10590b57cec5SDimitry Andric } \ 10600b57cec5SDimitry Andric __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \ 10610b57cec5SDimitry Andric lb = 0; \ 10620b57cec5SDimitry Andric ub = counts[0]; \ 10630b57cec5SDimitry Andric str = 1; \ 10640b57cec5SDimitry Andric \ 10650b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str " \ 10660b57cec5SDimitry Andric "0x%llx, chunk_sz 0x%llx\n", \ 10670b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 10680b57cec5SDimitry Andric \ 10690b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 10700b57cec5SDimitry Andric KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 10710b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 10720b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 10730b57cec5SDimitry Andric status = \ 10740b57cec5SDimitry Andric KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 10750b57cec5SDimitry Andric (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 10760b57cec5SDimitry Andric if (status) { \ 10770b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 10780b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 10790b57cec5SDimitry Andric } \ 10800b57cec5SDimitry Andric } else { \ 10810b57cec5SDimitry Andric status = 0; \ 10820b57cec5SDimitry Andric } \ 10830b57cec5SDimitry Andric KMP_DOACROSS_FINI(status, gtid); \ 10840b57cec5SDimitry Andric \ 10850b57cec5SDimitry Andric KA_TRACE( \ 10860b57cec5SDimitry Andric 20, \ 10870b57cec5SDimitry Andric (KMP_STR( \ 10880b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 10890b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 10900b57cec5SDimitry Andric __kmp_free(dims); \ 10910b57cec5SDimitry Andric return status; \ 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric #define LOOP_DOACROSS_RUNTIME_START_ULL(func, schedule) \ 10950b57cec5SDimitry Andric int func(unsigned ncounts, unsigned long long *counts, \ 10960b57cec5SDimitry Andric unsigned long long *p_lb, unsigned long long *p_ub) { \ 10970b57cec5SDimitry Andric int status; \ 10980b57cec5SDimitry Andric unsigned long long stride, str, lb, ub; \ 10990b57cec5SDimitry Andric unsigned long long chunk_sz = 0; \ 11000b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 11010b57cec5SDimitry Andric struct kmp_dim *dims = \ 11020b57cec5SDimitry Andric (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \ 11030b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 11040b57cec5SDimitry Andric for (unsigned i = 0; i < ncounts; ++i) { \ 11050b57cec5SDimitry Andric dims[i].lo = 0; \ 11060b57cec5SDimitry Andric dims[i].up = counts[i] - 1; \ 11070b57cec5SDimitry Andric dims[i].st = 1; \ 11080b57cec5SDimitry Andric } \ 11090b57cec5SDimitry Andric __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \ 11100b57cec5SDimitry Andric lb = 0; \ 11110b57cec5SDimitry Andric ub = counts[0]; \ 11120b57cec5SDimitry Andric str = 1; \ 11130b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str " \ 11140b57cec5SDimitry Andric "0x%llx, chunk_sz 0x%llx\n", \ 11150b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 11160b57cec5SDimitry Andric \ 11170b57cec5SDimitry Andric if ((str > 0) ? (lb < ub) : (lb > ub)) { \ 11180b57cec5SDimitry Andric KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \ 11190b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 11200b57cec5SDimitry Andric TRUE); \ 11210b57cec5SDimitry Andric status = \ 11220b57cec5SDimitry Andric KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \ 11230b57cec5SDimitry Andric (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \ 11240b57cec5SDimitry Andric if (status) { \ 11250b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == str); \ 11260b57cec5SDimitry Andric *p_ub += (str > 0) ? 1 : -1; \ 11270b57cec5SDimitry Andric } \ 11280b57cec5SDimitry Andric } else { \ 11290b57cec5SDimitry Andric status = 0; \ 11300b57cec5SDimitry Andric } \ 11310b57cec5SDimitry Andric KMP_DOACROSS_FINI(status, gtid); \ 11320b57cec5SDimitry Andric \ 11330b57cec5SDimitry Andric KA_TRACE( \ 11340b57cec5SDimitry Andric 20, \ 11350b57cec5SDimitry Andric (KMP_STR( \ 11360b57cec5SDimitry Andric func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \ 11370b57cec5SDimitry Andric gtid, *p_lb, *p_ub, status)); \ 11380b57cec5SDimitry Andric __kmp_free(dims); \ 11390b57cec5SDimitry Andric return status; \ 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL( 11430b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START), 11440b57cec5SDimitry Andric kmp_sch_static) 11450b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL( 11460b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START), 11470b57cec5SDimitry Andric kmp_sch_dynamic_chunked) 11480b57cec5SDimitry Andric LOOP_DOACROSS_START_ULL( 11490b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START), 11500b57cec5SDimitry Andric kmp_sch_guided_chunked) 11510b57cec5SDimitry Andric LOOP_DOACROSS_RUNTIME_START_ULL( 11520b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START), 11530b57cec5SDimitry Andric kmp_sch_runtime) 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric // Combined parallel / loop worksharing constructs 11560b57cec5SDimitry Andric // 11570b57cec5SDimitry Andric // There are no ull versions (yet). 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric #define PARALLEL_LOOP_START(func, schedule, ompt_pre, ompt_post) \ 11600b57cec5SDimitry Andric void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \ 11610b57cec5SDimitry Andric long ub, long str, long chunk_sz) { \ 11620b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 11630b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 11640b57cec5SDimitry Andric KA_TRACE( \ 11650b57cec5SDimitry Andric 20, \ 11660b57cec5SDimitry Andric (KMP_STR( \ 11670b57cec5SDimitry Andric func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 11680b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 11690b57cec5SDimitry Andric \ 11700b57cec5SDimitry Andric ompt_pre(); \ 11710b57cec5SDimitry Andric \ 1172e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task, \ 11730b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \ 11740b57cec5SDimitry Andric 9, task, data, num_threads, &loc, (schedule), lb, \ 11750b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \ 11760b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid)); \ 11770b57cec5SDimitry Andric \ 11780b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 11790b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 11800b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 11810b57cec5SDimitry Andric \ 11820b57cec5SDimitry Andric ompt_post(); \ 11830b57cec5SDimitry Andric \ 11840b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid)); \ 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric #define OMPT_LOOP_PRE() \ 11900b57cec5SDimitry Andric ompt_frame_t *parent_frame; \ 11910b57cec5SDimitry Andric if (ompt_enabled.enabled) { \ 11920b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL); \ 11930b57cec5SDimitry Andric parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); \ 11940b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); \ 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric #define OMPT_LOOP_POST() \ 11980b57cec5SDimitry Andric if (ompt_enabled.enabled) { \ 11990b57cec5SDimitry Andric parent_frame->enter_frame = ompt_data_none; \ 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric #else 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric #define OMPT_LOOP_PRE() 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric #define OMPT_LOOP_POST() 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric #endif 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric PARALLEL_LOOP_START( 12110b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START), 12120b57cec5SDimitry Andric kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST) 12130b57cec5SDimitry Andric PARALLEL_LOOP_START( 12140b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START), 12150b57cec5SDimitry Andric kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 12160b57cec5SDimitry Andric PARALLEL_LOOP_START( 12170b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START), 12180b57cec5SDimitry Andric kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 12190b57cec5SDimitry Andric PARALLEL_LOOP_START( 12200b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START), 12210b57cec5SDimitry Andric kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST) 12220b57cec5SDimitry Andric 12230b57cec5SDimitry Andric // Tasking constructs 12240b57cec5SDimitry Andric 12250b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, 12260b57cec5SDimitry Andric void (*copy_func)(void *, void *), 12270b57cec5SDimitry Andric long arg_size, long arg_align, 12280b57cec5SDimitry Andric bool if_cond, unsigned gomp_flags, 12290b57cec5SDimitry Andric void **depend) { 12300b57cec5SDimitry Andric MKLOC(loc, "GOMP_task"); 12310b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 12320b57cec5SDimitry Andric kmp_int32 flags = 0; 12330b57cec5SDimitry Andric kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags; 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_task: T#%d\n", gtid)); 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric // The low-order bit is the "untied" flag 1238e8d8bef9SDimitry Andric if (!(gomp_flags & KMP_GOMP_TASK_UNTIED_FLAG)) { 1239349cc55cSDimitry Andric input_flags->tiedness = TASK_TIED; 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric // The second low-order bit is the "final" flag 1242e8d8bef9SDimitry Andric if (gomp_flags & KMP_GOMP_TASK_FINAL_FLAG) { 12430b57cec5SDimitry Andric input_flags->final = 1; 12440b57cec5SDimitry Andric } 12450b57cec5SDimitry Andric input_flags->native = 1; 12460b57cec5SDimitry Andric // __kmp_task_alloc() sets up all other flags 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric if (!if_cond) { 12490b57cec5SDimitry Andric arg_size = 0; 12500b57cec5SDimitry Andric } 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andric kmp_task_t *task = __kmp_task_alloc( 12530b57cec5SDimitry Andric &loc, gtid, input_flags, sizeof(kmp_task_t), 12540b57cec5SDimitry Andric arg_size ? arg_size + arg_align - 1 : 0, (kmp_routine_entry_t)func); 12550b57cec5SDimitry Andric 12560b57cec5SDimitry Andric if (arg_size > 0) { 12570b57cec5SDimitry Andric if (arg_align > 0) { 12580b57cec5SDimitry Andric task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) / 12590b57cec5SDimitry Andric arg_align * arg_align); 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric // else error?? 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric if (copy_func) { 12640b57cec5SDimitry Andric (*copy_func)(task->shareds, data); 12650b57cec5SDimitry Andric } else { 12660b57cec5SDimitry Andric KMP_MEMCPY(task->shareds, data, arg_size); 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric } 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric #if OMPT_SUPPORT 12710b57cec5SDimitry Andric kmp_taskdata_t *current_task; 12720b57cec5SDimitry Andric if (ompt_enabled.enabled) { 12730b57cec5SDimitry Andric current_task = __kmp_threads[gtid]->th.th_current_task; 1274fe6060f1SDimitry Andric current_task->ompt_task_info.frame.enter_frame.ptr = 1275fe6060f1SDimitry Andric OMPT_GET_FRAME_ADDRESS(0); 12760b57cec5SDimitry Andric } 1277e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 12780b57cec5SDimitry Andric #endif 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric if (if_cond) { 1281e8d8bef9SDimitry Andric if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) { 12820b57cec5SDimitry Andric KMP_ASSERT(depend); 1283e8d8bef9SDimitry Andric kmp_gomp_depends_info_t gomp_depends(depend); 1284e8d8bef9SDimitry Andric kmp_int32 ndeps = gomp_depends.get_num_deps(); 12855f757f3fSDimitry Andric SimpleVLA<kmp_depend_info_t> dep_list(ndeps); 1286e8d8bef9SDimitry Andric for (kmp_int32 i = 0; i < ndeps; i++) 1287e8d8bef9SDimitry Andric dep_list[i] = gomp_depends.get_kmp_depend(i); 1288e8d8bef9SDimitry Andric kmp_int32 ndeps_cnv; 1289e8d8bef9SDimitry Andric __kmp_type_convert(ndeps, &ndeps_cnv); 1290e8d8bef9SDimitry Andric __kmpc_omp_task_with_deps(&loc, gtid, task, ndeps_cnv, dep_list, 0, NULL); 12910b57cec5SDimitry Andric } else { 12920b57cec5SDimitry Andric __kmpc_omp_task(&loc, gtid, task); 12930b57cec5SDimitry Andric } 12940b57cec5SDimitry Andric } else { 12950b57cec5SDimitry Andric #if OMPT_SUPPORT 12960b57cec5SDimitry Andric ompt_thread_info_t oldInfo; 12970b57cec5SDimitry Andric kmp_info_t *thread; 12980b57cec5SDimitry Andric kmp_taskdata_t *taskdata; 12990b57cec5SDimitry Andric if (ompt_enabled.enabled) { 13000b57cec5SDimitry Andric // Store the threads states and restore them after the task 13010b57cec5SDimitry Andric thread = __kmp_threads[gtid]; 13020b57cec5SDimitry Andric taskdata = KMP_TASK_TO_TASKDATA(task); 13030b57cec5SDimitry Andric oldInfo = thread->th.ompt_thread_info; 13040b57cec5SDimitry Andric thread->th.ompt_thread_info.wait_id = 0; 13050b57cec5SDimitry Andric thread->th.ompt_thread_info.state = ompt_state_work_parallel; 13060b57cec5SDimitry Andric taskdata->ompt_task_info.frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 13070b57cec5SDimitry Andric } 1308e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 13090b57cec5SDimitry Andric #endif 1310e8d8bef9SDimitry Andric if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) { 1311e8d8bef9SDimitry Andric KMP_ASSERT(depend); 1312e8d8bef9SDimitry Andric kmp_gomp_depends_info_t gomp_depends(depend); 1313e8d8bef9SDimitry Andric kmp_int32 ndeps = gomp_depends.get_num_deps(); 13145f757f3fSDimitry Andric SimpleVLA<kmp_depend_info_t> dep_list(ndeps); 1315e8d8bef9SDimitry Andric for (kmp_int32 i = 0; i < ndeps; i++) 1316e8d8bef9SDimitry Andric dep_list[i] = gomp_depends.get_kmp_depend(i); 1317e8d8bef9SDimitry Andric __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL); 1318e8d8bef9SDimitry Andric } 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric __kmpc_omp_task_begin_if0(&loc, gtid, task); 13210b57cec5SDimitry Andric func(data); 13220b57cec5SDimitry Andric __kmpc_omp_task_complete_if0(&loc, gtid, task); 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric #if OMPT_SUPPORT 13250b57cec5SDimitry Andric if (ompt_enabled.enabled) { 13260b57cec5SDimitry Andric thread->th.ompt_thread_info = oldInfo; 13270b57cec5SDimitry Andric taskdata->ompt_task_info.frame.exit_frame = ompt_data_none; 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric #endif 13300b57cec5SDimitry Andric } 13310b57cec5SDimitry Andric #if OMPT_SUPPORT 13320b57cec5SDimitry Andric if (ompt_enabled.enabled) { 13330b57cec5SDimitry Andric current_task->ompt_task_info.frame.enter_frame = ompt_data_none; 13340b57cec5SDimitry Andric } 13350b57cec5SDimitry Andric #endif 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_task exit: T#%d\n", gtid)); 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT)(void) { 13410b57cec5SDimitry Andric MKLOC(loc, "GOMP_taskwait"); 13420b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 13430b57cec5SDimitry Andric 13440b57cec5SDimitry Andric #if OMPT_SUPPORT 13450b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 13460b57cec5SDimitry Andric #endif 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_taskwait: T#%d\n", gtid)); 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric __kmpc_omp_taskwait(&loc, gtid); 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_taskwait exit: T#%d\n", gtid)); 13530b57cec5SDimitry Andric } 13540b57cec5SDimitry Andric 13550b57cec5SDimitry Andric // Sections worksharing constructs 13560b57cec5SDimitry Andric // 13570b57cec5SDimitry Andric // For the sections construct, we initialize a dynamically scheduled loop 13580b57cec5SDimitry Andric // worksharing construct with lb 1 and stride 1, and use the iteration #'s 13590b57cec5SDimitry Andric // that its returns as sections ids. 13600b57cec5SDimitry Andric // 13610b57cec5SDimitry Andric // There are no special entry points for ordered sections, so we always use 13620b57cec5SDimitry Andric // the dynamically scheduled workshare, even if the sections aren't ordered. 13630b57cec5SDimitry Andric 13640b57cec5SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(unsigned count) { 13650b57cec5SDimitry Andric int status; 13660b57cec5SDimitry Andric kmp_int lb, ub, stride; 13670b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 13680b57cec5SDimitry Andric MKLOC(loc, "GOMP_sections_start"); 13690b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_start: T#%d\n", gtid)); 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 13720b57cec5SDimitry Andric 13730b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride); 13740b57cec5SDimitry Andric if (status) { 13750b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == 1); 13760b57cec5SDimitry Andric KMP_DEBUG_ASSERT(lb > 0); 13770b57cec5SDimitry Andric KMP_ASSERT(lb == ub); 13780b57cec5SDimitry Andric } else { 13790b57cec5SDimitry Andric lb = 0; 13800b57cec5SDimitry Andric } 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_start exit: T#%d returning %u\n", gtid, 13830b57cec5SDimitry Andric (unsigned)lb)); 13840b57cec5SDimitry Andric return (unsigned)lb; 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_NEXT)(void) { 13880b57cec5SDimitry Andric int status; 13890b57cec5SDimitry Andric kmp_int lb, ub, stride; 13900b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 13910b57cec5SDimitry Andric MKLOC(loc, "GOMP_sections_next"); 13920b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_next: T#%d\n", gtid)); 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric #if OMPT_SUPPORT 13950b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 13960b57cec5SDimitry Andric #endif 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride); 13990b57cec5SDimitry Andric if (status) { 14000b57cec5SDimitry Andric KMP_DEBUG_ASSERT(stride == 1); 14010b57cec5SDimitry Andric KMP_DEBUG_ASSERT(lb > 0); 14020b57cec5SDimitry Andric KMP_ASSERT(lb == ub); 14030b57cec5SDimitry Andric } else { 14040b57cec5SDimitry Andric lb = 0; 14050b57cec5SDimitry Andric } 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric KA_TRACE( 14080b57cec5SDimitry Andric 20, ("GOMP_sections_next exit: T#%d returning %u\n", gtid, (unsigned)lb)); 14090b57cec5SDimitry Andric return (unsigned)lb; 14100b57cec5SDimitry Andric } 14110b57cec5SDimitry Andric 14120b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)( 14130b57cec5SDimitry Andric void (*task)(void *), void *data, unsigned num_threads, unsigned count) { 14140b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric #if OMPT_SUPPORT 14170b57cec5SDimitry Andric ompt_frame_t *parent_frame; 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14200b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL); 14210b57cec5SDimitry Andric parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 14220b57cec5SDimitry Andric } 1423e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 14240b57cec5SDimitry Andric #endif 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andric MKLOC(loc, "GOMP_parallel_sections_start"); 14270b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_sections_start: T#%d\n", gtid)); 14280b57cec5SDimitry Andric 1429e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task, 14300b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, 14310b57cec5SDimitry Andric task, data, num_threads, &loc, kmp_nm_dynamic_chunked, 14320b57cec5SDimitry Andric (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1); 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric #if OMPT_SUPPORT 14350b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14360b57cec5SDimitry Andric parent_frame->enter_frame = ompt_data_none; 14370b57cec5SDimitry Andric } 14380b57cec5SDimitry Andric #endif 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_sections_start exit: T#%d\n", gtid)); 14430b57cec5SDimitry Andric } 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END)(void) { 14460b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 14470b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_end: T#%d\n", gtid)) 14480b57cec5SDimitry Andric 14490b57cec5SDimitry Andric #if OMPT_SUPPORT 14500b57cec5SDimitry Andric ompt_frame_t *ompt_frame; 14510b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14520b57cec5SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 14530b57cec5SDimitry Andric ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 14540b57cec5SDimitry Andric } 1455e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 14560b57cec5SDimitry Andric #endif 14570b57cec5SDimitry Andric __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL); 14580b57cec5SDimitry Andric #if OMPT_SUPPORT 14590b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14600b57cec5SDimitry Andric ompt_frame->enter_frame = ompt_data_none; 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric #endif 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_end exit: T#%d\n", gtid)) 14650b57cec5SDimitry Andric } 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT)(void) { 14680b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_end_nowait: T#%d\n", __kmp_get_gtid())) 14690b57cec5SDimitry Andric } 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric // libgomp has an empty function for GOMP_taskyield as of 2013-10-10 14720b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKYIELD)(void) { 14730b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_taskyield: T#%d\n", __kmp_get_gtid())) 14740b57cec5SDimitry Andric return; 14750b57cec5SDimitry Andric } 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL)(void (*task)(void *), 14780b57cec5SDimitry Andric void *data, 14790b57cec5SDimitry Andric unsigned num_threads, 14800b57cec5SDimitry Andric unsigned int flags) { 14810b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 14820b57cec5SDimitry Andric MKLOC(loc, "GOMP_parallel"); 14830b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel: T#%d\n", gtid)); 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric #if OMPT_SUPPORT 14860b57cec5SDimitry Andric ompt_task_info_t *parent_task_info, *task_info; 14870b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14880b57cec5SDimitry Andric parent_task_info = __ompt_get_task_info_object(0); 14890b57cec5SDimitry Andric parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 1490e8d8bef9SDimitry Andric } 14910b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 14920b57cec5SDimitry Andric #endif 1493e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task, 14940b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task, 14950b57cec5SDimitry Andric data); 14960b57cec5SDimitry Andric #if OMPT_SUPPORT 14970b57cec5SDimitry Andric if (ompt_enabled.enabled) { 14980b57cec5SDimitry Andric task_info = __ompt_get_task_info_object(0); 14990b57cec5SDimitry Andric task_info->frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 15000b57cec5SDimitry Andric } 15010b57cec5SDimitry Andric #endif 15020b57cec5SDimitry Andric task(data); 1503e8d8bef9SDimitry Andric { 15040b57cec5SDimitry Andric #if OMPT_SUPPORT 15050b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 15060b57cec5SDimitry Andric #endif 15070b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(); 1508e8d8bef9SDimitry Andric } 15090b57cec5SDimitry Andric #if OMPT_SUPPORT 15100b57cec5SDimitry Andric if (ompt_enabled.enabled) { 15110b57cec5SDimitry Andric task_info->frame.exit_frame = ompt_data_none; 15120b57cec5SDimitry Andric parent_task_info->frame.enter_frame = ompt_data_none; 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric #endif 15150b57cec5SDimitry Andric } 15160b57cec5SDimitry Andric 15170b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS)(void (*task)(void *), 15180b57cec5SDimitry Andric void *data, 15190b57cec5SDimitry Andric unsigned num_threads, 15200b57cec5SDimitry Andric unsigned count, 15210b57cec5SDimitry Andric unsigned flags) { 15220b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 15230b57cec5SDimitry Andric MKLOC(loc, "GOMP_parallel_sections"); 15240b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_sections: T#%d\n", gtid)); 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric #if OMPT_SUPPORT 1527349cc55cSDimitry Andric ompt_frame_t *task_frame; 1528349cc55cSDimitry Andric kmp_info_t *thr; 1529349cc55cSDimitry Andric if (ompt_enabled.enabled) { 1530349cc55cSDimitry Andric thr = __kmp_threads[gtid]; 1531349cc55cSDimitry Andric task_frame = &(thr->th.th_current_task->ompt_task_info.frame); 1532349cc55cSDimitry Andric task_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 1533349cc55cSDimitry Andric } 15340b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 15350b57cec5SDimitry Andric #endif 15360b57cec5SDimitry Andric 1537e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task, 15380b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9, 15390b57cec5SDimitry Andric task, data, num_threads, &loc, kmp_nm_dynamic_chunked, 15400b57cec5SDimitry Andric (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1); 15410b57cec5SDimitry Andric 1542e8d8bef9SDimitry Andric { 15430b57cec5SDimitry Andric #if OMPT_SUPPORT 15440b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 15450b57cec5SDimitry Andric #endif 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE); 1548e8d8bef9SDimitry Andric } 1549349cc55cSDimitry Andric 1550349cc55cSDimitry Andric #if OMPT_SUPPORT 1551349cc55cSDimitry Andric ompt_frame_t *child_frame; 1552349cc55cSDimitry Andric if (ompt_enabled.enabled) { 1553349cc55cSDimitry Andric child_frame = &(thr->th.th_current_task->ompt_task_info.frame); 1554349cc55cSDimitry Andric child_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 1555349cc55cSDimitry Andric } 1556349cc55cSDimitry Andric #endif 1557349cc55cSDimitry Andric 15580b57cec5SDimitry Andric task(data); 1559349cc55cSDimitry Andric 1560349cc55cSDimitry Andric #if OMPT_SUPPORT 1561349cc55cSDimitry Andric if (ompt_enabled.enabled) { 1562349cc55cSDimitry Andric child_frame->exit_frame = ompt_data_none; 1563349cc55cSDimitry Andric } 1564349cc55cSDimitry Andric #endif 1565349cc55cSDimitry Andric 15660b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(); 15670b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_parallel_sections exit: T#%d\n", gtid)); 1568349cc55cSDimitry Andric 1569349cc55cSDimitry Andric #if OMPT_SUPPORT 1570349cc55cSDimitry Andric if (ompt_enabled.enabled) { 1571349cc55cSDimitry Andric task_frame->enter_frame = ompt_data_none; 1572349cc55cSDimitry Andric } 1573349cc55cSDimitry Andric #endif 15740b57cec5SDimitry Andric } 15750b57cec5SDimitry Andric 15760b57cec5SDimitry Andric #define PARALLEL_LOOP(func, schedule, ompt_pre, ompt_post) \ 15770b57cec5SDimitry Andric void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \ 15780b57cec5SDimitry Andric long ub, long str, long chunk_sz, unsigned flags) { \ 15790b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); \ 15800b57cec5SDimitry Andric MKLOC(loc, KMP_STR(func)); \ 15810b57cec5SDimitry Andric KA_TRACE( \ 15820b57cec5SDimitry Andric 20, \ 15830b57cec5SDimitry Andric (KMP_STR( \ 15840b57cec5SDimitry Andric func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \ 15850b57cec5SDimitry Andric gtid, lb, ub, str, chunk_sz)); \ 15860b57cec5SDimitry Andric \ 15870b57cec5SDimitry Andric ompt_pre(); \ 1588e8d8bef9SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 1589e8d8bef9SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task, \ 15900b57cec5SDimitry Andric (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \ 15910b57cec5SDimitry Andric 9, task, data, num_threads, &loc, (schedule), lb, \ 15920b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \ 15930b57cec5SDimitry Andric \ 1594e8d8bef9SDimitry Andric { \ 15950b57cec5SDimitry Andric IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \ 15960b57cec5SDimitry Andric KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \ 15970b57cec5SDimitry Andric (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \ 15980b57cec5SDimitry Andric (schedule) != kmp_sch_static); \ 1599e8d8bef9SDimitry Andric } \ 16000b57cec5SDimitry Andric task(data); \ 16010b57cec5SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(); \ 16020b57cec5SDimitry Andric ompt_post(); \ 16030b57cec5SDimitry Andric \ 16040b57cec5SDimitry Andric KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid)); \ 16050b57cec5SDimitry Andric } 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC), 16080b57cec5SDimitry Andric kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16090b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC), 16100b57cec5SDimitry Andric kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 1611489b1cf2SDimitry Andric PARALLEL_LOOP( 1612489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED), 1613489b1cf2SDimitry Andric kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 1614489b1cf2SDimitry Andric PARALLEL_LOOP( 1615489b1cf2SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC), 1616489b1cf2SDimitry Andric kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16170b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED), 16180b57cec5SDimitry Andric kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16190b57cec5SDimitry Andric PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME), 16200b57cec5SDimitry Andric kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16215ffd83dbSDimitry Andric PARALLEL_LOOP( 16225ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME), 16235ffd83dbSDimitry Andric kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16245ffd83dbSDimitry Andric PARALLEL_LOOP( 16255ffd83dbSDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME), 16265ffd83dbSDimitry Andric kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST) 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_START)(void) { 16290b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 16300b57cec5SDimitry Andric MKLOC(loc, "GOMP_taskgroup_start"); 16310b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_taskgroup_start: T#%d\n", gtid)); 16320b57cec5SDimitry Andric 16330b57cec5SDimitry Andric #if OMPT_SUPPORT 16340b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 16350b57cec5SDimitry Andric #endif 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andric __kmpc_taskgroup(&loc, gtid); 16380b57cec5SDimitry Andric 16390b57cec5SDimitry Andric return; 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric 16420b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_END)(void) { 16430b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 16440b57cec5SDimitry Andric MKLOC(loc, "GOMP_taskgroup_end"); 16450b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_taskgroup_end: T#%d\n", gtid)); 16460b57cec5SDimitry Andric 16470b57cec5SDimitry Andric #if OMPT_SUPPORT 16480b57cec5SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 16490b57cec5SDimitry Andric #endif 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric __kmpc_end_taskgroup(&loc, gtid); 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric return; 16540b57cec5SDimitry Andric } 16550b57cec5SDimitry Andric 16560b57cec5SDimitry Andric static kmp_int32 __kmp_gomp_to_omp_cancellation_kind(int gomp_kind) { 16570b57cec5SDimitry Andric kmp_int32 cncl_kind = 0; 16580b57cec5SDimitry Andric switch (gomp_kind) { 16590b57cec5SDimitry Andric case 1: 16600b57cec5SDimitry Andric cncl_kind = cancel_parallel; 16610b57cec5SDimitry Andric break; 16620b57cec5SDimitry Andric case 2: 16630b57cec5SDimitry Andric cncl_kind = cancel_loop; 16640b57cec5SDimitry Andric break; 16650b57cec5SDimitry Andric case 4: 16660b57cec5SDimitry Andric cncl_kind = cancel_sections; 16670b57cec5SDimitry Andric break; 16680b57cec5SDimitry Andric case 8: 16690b57cec5SDimitry Andric cncl_kind = cancel_taskgroup; 16700b57cec5SDimitry Andric break; 16710b57cec5SDimitry Andric } 16720b57cec5SDimitry Andric return cncl_kind; 16730b57cec5SDimitry Andric } 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise 16760b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCELLATION_POINT)(int which) { 16770b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 16780b57cec5SDimitry Andric MKLOC(loc, "GOMP_cancellation_point"); 16790b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_cancellation_point: T#%d which:%d\n", gtid, which)); 16800b57cec5SDimitry Andric kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which); 16810b57cec5SDimitry Andric return __kmpc_cancellationpoint(&loc, gtid, cncl_kind); 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise 16850b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCEL)(int which, bool do_cancel) { 16860b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 16870b57cec5SDimitry Andric MKLOC(loc, "GOMP_cancel"); 16880b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_cancel: T#%d which:%d do_cancel:%d\n", gtid, which, 16890b57cec5SDimitry Andric (int)do_cancel)); 16900b57cec5SDimitry Andric kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which); 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric if (do_cancel == FALSE) { 16930b57cec5SDimitry Andric return __kmpc_cancellationpoint(&loc, gtid, cncl_kind); 16940b57cec5SDimitry Andric } else { 16950b57cec5SDimitry Andric return __kmpc_cancel(&loc, gtid, cncl_kind); 16960b57cec5SDimitry Andric } 16970b57cec5SDimitry Andric } 16980b57cec5SDimitry Andric 16990b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise 17000b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER_CANCEL)(void) { 17010b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 17020b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_barrier_cancel: T#%d\n", gtid)); 17030b57cec5SDimitry Andric return __kmp_barrier_gomp_cancel(gtid); 17040b57cec5SDimitry Andric } 17050b57cec5SDimitry Andric 17060b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise 17070b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL)(void) { 17080b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 17090b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_sections_end_cancel: T#%d\n", gtid)); 17100b57cec5SDimitry Andric return __kmp_barrier_gomp_cancel(gtid); 17110b57cec5SDimitry Andric } 17120b57cec5SDimitry Andric 17130b57cec5SDimitry Andric // Return true if cancellation should take place, false otherwise 17140b57cec5SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_CANCEL)(void) { 17150b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 17160b57cec5SDimitry Andric KA_TRACE(20, ("GOMP_loop_end_cancel: T#%d\n", gtid)); 17170b57cec5SDimitry Andric return __kmp_barrier_gomp_cancel(gtid); 17180b57cec5SDimitry Andric } 17190b57cec5SDimitry Andric 17200b57cec5SDimitry Andric // All target functions are empty as of 2014-05-29 17210b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET)(int device, void (*fn)(void *), 17220b57cec5SDimitry Andric const void *openmp_target, 17230b57cec5SDimitry Andric size_t mapnum, void **hostaddrs, 17240b57cec5SDimitry Andric size_t *sizes, 17250b57cec5SDimitry Andric unsigned char *kinds) { 17260b57cec5SDimitry Andric return; 17270b57cec5SDimitry Andric } 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_DATA)( 17300b57cec5SDimitry Andric int device, const void *openmp_target, size_t mapnum, void **hostaddrs, 17310b57cec5SDimitry Andric size_t *sizes, unsigned char *kinds) { 17320b57cec5SDimitry Andric return; 17330b57cec5SDimitry Andric } 17340b57cec5SDimitry Andric 17350b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_END_DATA)(void) { return; } 17360b57cec5SDimitry Andric 17370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_UPDATE)( 17380b57cec5SDimitry Andric int device, const void *openmp_target, size_t mapnum, void **hostaddrs, 17390b57cec5SDimitry Andric size_t *sizes, unsigned char *kinds) { 17400b57cec5SDimitry Andric return; 17410b57cec5SDimitry Andric } 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams, 17440b57cec5SDimitry Andric unsigned int thread_limit) { 17450b57cec5SDimitry Andric return; 17460b57cec5SDimitry Andric } 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric // Task duplication function which copies src to dest (both are 17490b57cec5SDimitry Andric // preallocated task structures) 17500b57cec5SDimitry Andric static void __kmp_gomp_task_dup(kmp_task_t *dest, kmp_task_t *src, 17510b57cec5SDimitry Andric kmp_int32 last_private) { 17520b57cec5SDimitry Andric kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(src); 17530b57cec5SDimitry Andric if (taskdata->td_copy_func) { 17540b57cec5SDimitry Andric (taskdata->td_copy_func)(dest->shareds, src->shareds); 17550b57cec5SDimitry Andric } 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric 1758fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)( 1759fe6060f1SDimitry Andric uintptr_t *); 1760fe6060f1SDimitry Andric 17610b57cec5SDimitry Andric #ifdef __cplusplus 17620b57cec5SDimitry Andric } // extern "C" 17630b57cec5SDimitry Andric #endif 17640b57cec5SDimitry Andric 17650b57cec5SDimitry Andric template <typename T> 17660b57cec5SDimitry Andric void __GOMP_taskloop(void (*func)(void *), void *data, 17670b57cec5SDimitry Andric void (*copy_func)(void *, void *), long arg_size, 17680b57cec5SDimitry Andric long arg_align, unsigned gomp_flags, 17690b57cec5SDimitry Andric unsigned long num_tasks, int priority, T start, T end, 17700b57cec5SDimitry Andric T step) { 17710b57cec5SDimitry Andric typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32); 17720b57cec5SDimitry Andric MKLOC(loc, "GOMP_taskloop"); 17730b57cec5SDimitry Andric int sched; 17740b57cec5SDimitry Andric T *loop_bounds; 17750b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 17760b57cec5SDimitry Andric kmp_int32 flags = 0; 17770b57cec5SDimitry Andric int if_val = gomp_flags & (1u << 10); 17780b57cec5SDimitry Andric int nogroup = gomp_flags & (1u << 11); 17790b57cec5SDimitry Andric int up = gomp_flags & (1u << 8); 1780fe6060f1SDimitry Andric int reductions = gomp_flags & (1u << 12); 17810b57cec5SDimitry Andric p_task_dup_t task_dup = NULL; 17820b57cec5SDimitry Andric kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags; 17830b57cec5SDimitry Andric #ifdef KMP_DEBUG 17840b57cec5SDimitry Andric { 17850b57cec5SDimitry Andric char *buff; 17860b57cec5SDimitry Andric buff = __kmp_str_format( 17870b57cec5SDimitry Andric "GOMP_taskloop: T#%%d: func:%%p data:%%p copy_func:%%p " 17880b57cec5SDimitry Andric "arg_size:%%ld arg_align:%%ld gomp_flags:0x%%x num_tasks:%%lu " 17890b57cec5SDimitry Andric "priority:%%d start:%%%s end:%%%s step:%%%s\n", 17900b57cec5SDimitry Andric traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec); 17910b57cec5SDimitry Andric KA_TRACE(20, (buff, gtid, func, data, copy_func, arg_size, arg_align, 17920b57cec5SDimitry Andric gomp_flags, num_tasks, priority, start, end, step)); 17930b57cec5SDimitry Andric __kmp_str_free(&buff); 17940b57cec5SDimitry Andric } 17950b57cec5SDimitry Andric #endif 17960b57cec5SDimitry Andric KMP_ASSERT((size_t)arg_size >= 2 * sizeof(T)); 17970b57cec5SDimitry Andric KMP_ASSERT(arg_align > 0); 17980b57cec5SDimitry Andric // The low-order bit is the "untied" flag 17990b57cec5SDimitry Andric if (!(gomp_flags & 1)) { 1800349cc55cSDimitry Andric input_flags->tiedness = TASK_TIED; 18010b57cec5SDimitry Andric } 18020b57cec5SDimitry Andric // The second low-order bit is the "final" flag 18030b57cec5SDimitry Andric if (gomp_flags & 2) { 18040b57cec5SDimitry Andric input_flags->final = 1; 18050b57cec5SDimitry Andric } 18060b57cec5SDimitry Andric // Negative step flag 18070b57cec5SDimitry Andric if (!up) { 18080b57cec5SDimitry Andric // If step is flagged as negative, but isn't properly sign extended 18090b57cec5SDimitry Andric // Then manually sign extend it. Could be a short, int, char embedded 18100b57cec5SDimitry Andric // in a long. So cannot assume any cast. 18110b57cec5SDimitry Andric if (step > 0) { 18120b57cec5SDimitry Andric for (int i = sizeof(T) * CHAR_BIT - 1; i >= 0L; --i) { 18130b57cec5SDimitry Andric // break at the first 1 bit 18140b57cec5SDimitry Andric if (step & ((T)1 << i)) 18150b57cec5SDimitry Andric break; 18160b57cec5SDimitry Andric step |= ((T)1 << i); 18170b57cec5SDimitry Andric } 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric } 18200b57cec5SDimitry Andric input_flags->native = 1; 18210b57cec5SDimitry Andric // Figure out if none/grainsize/num_tasks clause specified 18220b57cec5SDimitry Andric if (num_tasks > 0) { 18230b57cec5SDimitry Andric if (gomp_flags & (1u << 9)) 18240b57cec5SDimitry Andric sched = 1; // grainsize specified 18250b57cec5SDimitry Andric else 18260b57cec5SDimitry Andric sched = 2; // num_tasks specified 18270b57cec5SDimitry Andric // neither grainsize nor num_tasks specified 18280b57cec5SDimitry Andric } else { 18290b57cec5SDimitry Andric sched = 0; 18300b57cec5SDimitry Andric } 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric // __kmp_task_alloc() sets up all other flags 18330b57cec5SDimitry Andric kmp_task_t *task = 18340b57cec5SDimitry Andric __kmp_task_alloc(&loc, gtid, input_flags, sizeof(kmp_task_t), 18350b57cec5SDimitry Andric arg_size + arg_align - 1, (kmp_routine_entry_t)func); 18360b57cec5SDimitry Andric kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task); 18370b57cec5SDimitry Andric taskdata->td_copy_func = copy_func; 18380b57cec5SDimitry Andric taskdata->td_size_loop_bounds = sizeof(T); 18390b57cec5SDimitry Andric 18400b57cec5SDimitry Andric // re-align shareds if needed and setup firstprivate copy constructors 18410b57cec5SDimitry Andric // through the task_dup mechanism 18420b57cec5SDimitry Andric task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) / 18430b57cec5SDimitry Andric arg_align * arg_align); 18440b57cec5SDimitry Andric if (copy_func) { 18450b57cec5SDimitry Andric task_dup = __kmp_gomp_task_dup; 18460b57cec5SDimitry Andric } 18470b57cec5SDimitry Andric KMP_MEMCPY(task->shareds, data, arg_size); 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric loop_bounds = (T *)task->shareds; 18500b57cec5SDimitry Andric loop_bounds[0] = start; 18510b57cec5SDimitry Andric loop_bounds[1] = end + (up ? -1 : 1); 1852fe6060f1SDimitry Andric 1853fe6060f1SDimitry Andric if (!nogroup) { 1854fe6060f1SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1855fe6060f1SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 1856fe6060f1SDimitry Andric #endif 1857fe6060f1SDimitry Andric __kmpc_taskgroup(&loc, gtid); 1858fe6060f1SDimitry Andric if (reductions) { 1859fe6060f1SDimitry Andric // The data pointer points to lb, ub, then reduction data 1860fe6060f1SDimitry Andric struct data_t { 1861fe6060f1SDimitry Andric T a, b; 1862fe6060f1SDimitry Andric uintptr_t *d; 1863fe6060f1SDimitry Andric }; 1864fe6060f1SDimitry Andric uintptr_t *d = ((data_t *)data)->d; 1865fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(d); 1866fe6060f1SDimitry Andric } 1867fe6060f1SDimitry Andric } 18680b57cec5SDimitry Andric __kmpc_taskloop(&loc, gtid, task, if_val, (kmp_uint64 *)&(loop_bounds[0]), 1869fe6060f1SDimitry Andric (kmp_uint64 *)&(loop_bounds[1]), (kmp_int64)step, 1, sched, 1870fe6060f1SDimitry Andric (kmp_uint64)num_tasks, (void *)task_dup); 1871fe6060f1SDimitry Andric if (!nogroup) { 1872fe6060f1SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 1873fe6060f1SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 1874fe6060f1SDimitry Andric #endif 1875fe6060f1SDimitry Andric __kmpc_end_taskgroup(&loc, gtid); 1876fe6060f1SDimitry Andric } 18770b57cec5SDimitry Andric } 18780b57cec5SDimitry Andric 18790b57cec5SDimitry Andric // 4 byte version of GOMP_doacross_post 18800b57cec5SDimitry Andric // This verison needs to create a temporary array which converts 4 byte 1881480093f4SDimitry Andric // integers into 8 byte integers 18820b57cec5SDimitry Andric template <typename T, bool need_conversion = (sizeof(long) == 4)> 18830b57cec5SDimitry Andric void __kmp_GOMP_doacross_post(T *count); 18840b57cec5SDimitry Andric 18850b57cec5SDimitry Andric template <> void __kmp_GOMP_doacross_post<long, true>(long *count) { 18860b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 18870b57cec5SDimitry Andric kmp_info_t *th = __kmp_threads[gtid]; 18880b57cec5SDimitry Andric MKLOC(loc, "GOMP_doacross_post"); 18890b57cec5SDimitry Andric kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0]; 1890e8d8bef9SDimitry Andric kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc( 1891e8d8bef9SDimitry Andric th, (size_t)(sizeof(kmp_int64) * num_dims)); 18920b57cec5SDimitry Andric for (kmp_int64 i = 0; i < num_dims; ++i) { 18930b57cec5SDimitry Andric vec[i] = (kmp_int64)count[i]; 18940b57cec5SDimitry Andric } 18950b57cec5SDimitry Andric __kmpc_doacross_post(&loc, gtid, vec); 18960b57cec5SDimitry Andric __kmp_thread_free(th, vec); 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric // 8 byte versions of GOMP_doacross_post 19000b57cec5SDimitry Andric // This version can just pass in the count array directly instead of creating 19010b57cec5SDimitry Andric // a temporary array 19020b57cec5SDimitry Andric template <> void __kmp_GOMP_doacross_post<long, false>(long *count) { 19030b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 19040b57cec5SDimitry Andric MKLOC(loc, "GOMP_doacross_post"); 19050b57cec5SDimitry Andric __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count)); 19060b57cec5SDimitry Andric } 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andric template <typename T> void __kmp_GOMP_doacross_wait(T first, va_list args) { 19090b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 19100b57cec5SDimitry Andric kmp_info_t *th = __kmp_threads[gtid]; 19110b57cec5SDimitry Andric MKLOC(loc, "GOMP_doacross_wait"); 19120b57cec5SDimitry Andric kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0]; 1913e8d8bef9SDimitry Andric kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc( 1914e8d8bef9SDimitry Andric th, (size_t)(sizeof(kmp_int64) * num_dims)); 19150b57cec5SDimitry Andric vec[0] = (kmp_int64)first; 19160b57cec5SDimitry Andric for (kmp_int64 i = 1; i < num_dims; ++i) { 19170b57cec5SDimitry Andric T item = va_arg(args, T); 19180b57cec5SDimitry Andric vec[i] = (kmp_int64)item; 19190b57cec5SDimitry Andric } 19200b57cec5SDimitry Andric __kmpc_doacross_wait(&loc, gtid, vec); 19210b57cec5SDimitry Andric __kmp_thread_free(th, vec); 19220b57cec5SDimitry Andric return; 19230b57cec5SDimitry Andric } 19240b57cec5SDimitry Andric 19250b57cec5SDimitry Andric #ifdef __cplusplus 19260b57cec5SDimitry Andric extern "C" { 19270b57cec5SDimitry Andric #endif // __cplusplus 19280b57cec5SDimitry Andric 19290b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP)( 19300b57cec5SDimitry Andric void (*func)(void *), void *data, void (*copy_func)(void *, void *), 19310b57cec5SDimitry Andric long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks, 19320b57cec5SDimitry Andric int priority, long start, long end, long step) { 19330b57cec5SDimitry Andric __GOMP_taskloop<long>(func, data, copy_func, arg_size, arg_align, gomp_flags, 19340b57cec5SDimitry Andric num_tasks, priority, start, end, step); 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP_ULL)( 19380b57cec5SDimitry Andric void (*func)(void *), void *data, void (*copy_func)(void *, void *), 19390b57cec5SDimitry Andric long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks, 19400b57cec5SDimitry Andric int priority, unsigned long long start, unsigned long long end, 19410b57cec5SDimitry Andric unsigned long long step) { 19420b57cec5SDimitry Andric __GOMP_taskloop<unsigned long long>(func, data, copy_func, arg_size, 19430b57cec5SDimitry Andric arg_align, gomp_flags, num_tasks, 19440b57cec5SDimitry Andric priority, start, end, step); 19450b57cec5SDimitry Andric } 19460b57cec5SDimitry Andric 19470b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_POST)(long *count) { 19480b57cec5SDimitry Andric __kmp_GOMP_doacross_post(count); 19490b57cec5SDimitry Andric } 19500b57cec5SDimitry Andric 19510b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_WAIT)(long first, ...) { 19520b57cec5SDimitry Andric va_list args; 19530b57cec5SDimitry Andric va_start(args, first); 19540b57cec5SDimitry Andric __kmp_GOMP_doacross_wait<long>(first, args); 19550b57cec5SDimitry Andric va_end(args); 19560b57cec5SDimitry Andric } 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_POST)( 19590b57cec5SDimitry Andric unsigned long long *count) { 19600b57cec5SDimitry Andric int gtid = __kmp_entry_gtid(); 19610b57cec5SDimitry Andric MKLOC(loc, "GOMP_doacross_ull_post"); 19620b57cec5SDimitry Andric __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count)); 19630b57cec5SDimitry Andric } 19640b57cec5SDimitry Andric 19650b57cec5SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT)( 19660b57cec5SDimitry Andric unsigned long long first, ...) { 19670b57cec5SDimitry Andric va_list args; 19680b57cec5SDimitry Andric va_start(args, first); 19690b57cec5SDimitry Andric __kmp_GOMP_doacross_wait<unsigned long long>(first, args); 19700b57cec5SDimitry Andric va_end(args); 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric 1973fe6060f1SDimitry Andric // fn: the function each primary thread of new team will call 1974e8d8bef9SDimitry Andric // data: argument to fn 1975e8d8bef9SDimitry Andric // num_teams, thread_limit: max bounds on respective ICV 1976e8d8bef9SDimitry Andric // flags: unused 1977e8d8bef9SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS_REG)(void (*fn)(void *), 1978e8d8bef9SDimitry Andric void *data, 1979e8d8bef9SDimitry Andric unsigned num_teams, 1980e8d8bef9SDimitry Andric unsigned thread_limit, 1981e8d8bef9SDimitry Andric unsigned flags) { 1982e8d8bef9SDimitry Andric MKLOC(loc, "GOMP_teams_reg"); 1983e8d8bef9SDimitry Andric int gtid = __kmp_entry_gtid(); 1984e8d8bef9SDimitry Andric KA_TRACE(20, ("GOMP_teams_reg: T#%d num_teams=%u thread_limit=%u flag=%u\n", 1985e8d8bef9SDimitry Andric gtid, num_teams, thread_limit, flags)); 1986e8d8bef9SDimitry Andric __kmpc_push_num_teams(&loc, gtid, num_teams, thread_limit); 1987e8d8bef9SDimitry Andric __kmpc_fork_teams(&loc, 2, (microtask_t)__kmp_GOMP_microtask_wrapper, fn, 1988e8d8bef9SDimitry Andric data); 1989e8d8bef9SDimitry Andric KA_TRACE(20, ("GOMP_teams_reg exit: T#%d\n", gtid)); 1990e8d8bef9SDimitry Andric } 1991e8d8bef9SDimitry Andric 1992e8d8bef9SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT_DEPEND)(void **depend) { 1993e8d8bef9SDimitry Andric MKLOC(loc, "GOMP_taskwait_depend"); 1994e8d8bef9SDimitry Andric int gtid = __kmp_entry_gtid(); 1995e8d8bef9SDimitry Andric KA_TRACE(20, ("GOMP_taskwait_depend: T#%d\n", gtid)); 1996e8d8bef9SDimitry Andric kmp_gomp_depends_info_t gomp_depends(depend); 1997e8d8bef9SDimitry Andric kmp_int32 ndeps = gomp_depends.get_num_deps(); 19985f757f3fSDimitry Andric SimpleVLA<kmp_depend_info_t> dep_list(ndeps); 1999e8d8bef9SDimitry Andric for (kmp_int32 i = 0; i < ndeps; i++) 2000e8d8bef9SDimitry Andric dep_list[i] = gomp_depends.get_kmp_depend(i); 2001e8d8bef9SDimitry Andric #if OMPT_SUPPORT 2002e8d8bef9SDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 2003e8d8bef9SDimitry Andric #endif 2004e8d8bef9SDimitry Andric __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL); 2005e8d8bef9SDimitry Andric KA_TRACE(20, ("GOMP_taskwait_depend exit: T#%d\n", gtid)); 2006e8d8bef9SDimitry Andric } 2007e8d8bef9SDimitry Andric 2008fe6060f1SDimitry Andric static inline void 2009fe6060f1SDimitry Andric __kmp_GOMP_taskgroup_reduction_register(uintptr_t *data, kmp_taskgroup_t *tg, 2010fe6060f1SDimitry Andric int nthreads, 2011fe6060f1SDimitry Andric uintptr_t *allocated = nullptr) { 2012fe6060f1SDimitry Andric KMP_ASSERT(data); 2013fe6060f1SDimitry Andric KMP_ASSERT(nthreads > 0); 2014fe6060f1SDimitry Andric // Have private copy pointers point to previously allocated 2015fe6060f1SDimitry Andric // reduction data or allocate new data here 2016fe6060f1SDimitry Andric if (allocated) { 2017fe6060f1SDimitry Andric data[2] = allocated[2]; 2018fe6060f1SDimitry Andric data[6] = allocated[6]; 2019fe6060f1SDimitry Andric } else { 2020fe6060f1SDimitry Andric data[2] = (uintptr_t)__kmp_allocate(nthreads * data[1]); 2021fe6060f1SDimitry Andric data[6] = data[2] + (nthreads * data[1]); 2022fe6060f1SDimitry Andric } 2023fe6060f1SDimitry Andric if (tg) 2024fe6060f1SDimitry Andric tg->gomp_data = data; 2025fe6060f1SDimitry Andric } 2026fe6060f1SDimitry Andric 2027fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)( 2028fe6060f1SDimitry Andric uintptr_t *data) { 2029fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2030fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_taskgroup_reduction_register: T#%d\n", gtid)); 2031fe6060f1SDimitry Andric kmp_info_t *thread = __kmp_threads[gtid]; 2032fe6060f1SDimitry Andric kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup; 2033fe6060f1SDimitry Andric int nthreads = thread->th.th_team_nproc; 2034fe6060f1SDimitry Andric __kmp_GOMP_taskgroup_reduction_register(data, tg, nthreads); 2035fe6060f1SDimitry Andric } 2036fe6060f1SDimitry Andric 2037fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER)( 2038fe6060f1SDimitry Andric uintptr_t *data) { 2039fe6060f1SDimitry Andric KA_TRACE(20, 2040fe6060f1SDimitry Andric ("GOMP_taskgroup_reduction_unregister: T#%d\n", __kmp_get_gtid())); 2041fe6060f1SDimitry Andric KMP_ASSERT(data && data[2]); 2042fe6060f1SDimitry Andric __kmp_free((void *)data[2]); 2043fe6060f1SDimitry Andric } 2044fe6060f1SDimitry Andric 2045fe6060f1SDimitry Andric // Search through reduction data and set ptrs[] elements 2046fe6060f1SDimitry Andric // to proper privatized copy address 2047fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP)(size_t cnt, 2048fe6060f1SDimitry Andric size_t cntorig, 2049fe6060f1SDimitry Andric void **ptrs) { 2050fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2051fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_task_reduction_remap: T#%d\n", gtid)); 2052fe6060f1SDimitry Andric kmp_info_t *thread = __kmp_threads[gtid]; 2053fe6060f1SDimitry Andric kmp_int32 tid = __kmp_get_tid(); 2054fe6060f1SDimitry Andric for (size_t i = 0; i < cnt; ++i) { 2055fe6060f1SDimitry Andric uintptr_t address = (uintptr_t)ptrs[i]; 2056fe6060f1SDimitry Andric void *propagated_address = NULL; 2057fe6060f1SDimitry Andric void *mapped_address = NULL; 2058fe6060f1SDimitry Andric // Check taskgroups reduce data 2059fe6060f1SDimitry Andric kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup; 2060fe6060f1SDimitry Andric while (tg) { 2061fe6060f1SDimitry Andric uintptr_t *gomp_data = tg->gomp_data; 2062fe6060f1SDimitry Andric if (!gomp_data) { 2063fe6060f1SDimitry Andric tg = tg->parent; 2064fe6060f1SDimitry Andric continue; 2065fe6060f1SDimitry Andric } 2066fe6060f1SDimitry Andric // Check the shared addresses list 2067fe6060f1SDimitry Andric size_t num_vars = (size_t)gomp_data[0]; 2068fe6060f1SDimitry Andric uintptr_t per_thread_size = gomp_data[1]; 2069fe6060f1SDimitry Andric uintptr_t reduce_data = gomp_data[2]; 2070fe6060f1SDimitry Andric uintptr_t end_reduce_data = gomp_data[6]; 2071fe6060f1SDimitry Andric for (size_t j = 0; j < num_vars; ++j) { 2072fe6060f1SDimitry Andric uintptr_t *entry = gomp_data + 7 + 3 * j; 2073fe6060f1SDimitry Andric if (entry[0] == address) { 2074fe6060f1SDimitry Andric uintptr_t offset = entry[1]; 2075fe6060f1SDimitry Andric mapped_address = 2076fe6060f1SDimitry Andric (void *)(reduce_data + tid * per_thread_size + offset); 2077fe6060f1SDimitry Andric if (i < cntorig) 2078fe6060f1SDimitry Andric propagated_address = (void *)entry[0]; 2079fe6060f1SDimitry Andric break; 2080fe6060f1SDimitry Andric } 2081fe6060f1SDimitry Andric } 2082fe6060f1SDimitry Andric if (mapped_address) 2083fe6060f1SDimitry Andric break; 2084fe6060f1SDimitry Andric // Check if address is within privatized copies range 2085fe6060f1SDimitry Andric if (!mapped_address && address >= reduce_data && 2086fe6060f1SDimitry Andric address < end_reduce_data) { 2087fe6060f1SDimitry Andric uintptr_t offset = (address - reduce_data) % per_thread_size; 2088fe6060f1SDimitry Andric mapped_address = (void *)(reduce_data + tid * per_thread_size + offset); 2089fe6060f1SDimitry Andric if (i < cntorig) { 2090fe6060f1SDimitry Andric for (size_t j = 0; j < num_vars; ++j) { 2091fe6060f1SDimitry Andric uintptr_t *entry = gomp_data + 7 + 3 * j; 2092fe6060f1SDimitry Andric if (entry[1] == offset) { 2093fe6060f1SDimitry Andric propagated_address = (void *)entry[0]; 2094fe6060f1SDimitry Andric break; 2095fe6060f1SDimitry Andric } 2096fe6060f1SDimitry Andric } 2097fe6060f1SDimitry Andric } 2098fe6060f1SDimitry Andric } 2099fe6060f1SDimitry Andric if (mapped_address) 2100fe6060f1SDimitry Andric break; 2101fe6060f1SDimitry Andric tg = tg->parent; 2102fe6060f1SDimitry Andric } 2103fe6060f1SDimitry Andric KMP_ASSERT(mapped_address); 2104fe6060f1SDimitry Andric ptrs[i] = mapped_address; 2105fe6060f1SDimitry Andric if (i < cntorig) { 2106fe6060f1SDimitry Andric KMP_ASSERT(propagated_address); 2107fe6060f1SDimitry Andric ptrs[cnt + i] = propagated_address; 2108fe6060f1SDimitry Andric } 2109fe6060f1SDimitry Andric } 2110fe6060f1SDimitry Andric } 2111fe6060f1SDimitry Andric 2112fe6060f1SDimitry Andric static void __kmp_GOMP_init_reductions(int gtid, uintptr_t *data, int is_ws) { 2113fe6060f1SDimitry Andric kmp_info_t *thr = __kmp_threads[gtid]; 2114fe6060f1SDimitry Andric kmp_team_t *team = thr->th.th_team; 2115fe6060f1SDimitry Andric // First start a taskgroup 2116fe6060f1SDimitry Andric __kmpc_taskgroup(NULL, gtid); 2117fe6060f1SDimitry Andric // Then setup reduction data 2118fe6060f1SDimitry Andric void *reduce_data = KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[is_ws]); 2119fe6060f1SDimitry Andric if (reduce_data == NULL && 2120fe6060f1SDimitry Andric __kmp_atomic_compare_store(&team->t.t_tg_reduce_data[is_ws], reduce_data, 2121fe6060f1SDimitry Andric (void *)1)) { 2122fe6060f1SDimitry Andric // Single thread enters this block to initialize common reduction data 2123fe6060f1SDimitry Andric KMP_DEBUG_ASSERT(reduce_data == NULL); 2124fe6060f1SDimitry Andric __kmp_GOMP_taskgroup_reduction_register(data, NULL, thr->th.th_team_nproc); 2125fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[is_ws], 0); 2126fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[is_ws], (void *)data); 2127fe6060f1SDimitry Andric } else { 2128fe6060f1SDimitry Andric // Wait for task reduction initialization 2129fe6060f1SDimitry Andric while ((reduce_data = KMP_ATOMIC_LD_ACQ( 2130fe6060f1SDimitry Andric &team->t.t_tg_reduce_data[is_ws])) == (void *)1) { 2131fe6060f1SDimitry Andric KMP_CPU_PAUSE(); 2132fe6060f1SDimitry Andric } 2133fe6060f1SDimitry Andric KMP_DEBUG_ASSERT(reduce_data > (void *)1); // should be valid pointer here 2134fe6060f1SDimitry Andric } 2135fe6060f1SDimitry Andric // For worksharing constructs, each thread has its own reduction structure. 2136fe6060f1SDimitry Andric // Have each reduction structure point to same privatized copies of vars. 2137fe6060f1SDimitry Andric // For parallel, each thread points to same reduction structure and privatized 2138fe6060f1SDimitry Andric // copies of vars 2139fe6060f1SDimitry Andric if (is_ws) { 2140fe6060f1SDimitry Andric __kmp_GOMP_taskgroup_reduction_register( 2141fe6060f1SDimitry Andric data, NULL, thr->th.th_team_nproc, 2142fe6060f1SDimitry Andric (uintptr_t *)KMP_ATOMIC_LD_ACQ(&team->t.t_tg_reduce_data[is_ws])); 2143fe6060f1SDimitry Andric } 2144fe6060f1SDimitry Andric kmp_taskgroup_t *tg = thr->th.th_current_task->td_taskgroup; 2145fe6060f1SDimitry Andric tg->gomp_data = data; 2146fe6060f1SDimitry Andric } 2147fe6060f1SDimitry Andric 2148fe6060f1SDimitry Andric static unsigned 2149fe6060f1SDimitry Andric __kmp_GOMP_par_reductions_microtask_wrapper(int *gtid, int *npr, 2150fe6060f1SDimitry Andric void (*task)(void *), void *data) { 2151fe6060f1SDimitry Andric kmp_info_t *thr = __kmp_threads[*gtid]; 2152fe6060f1SDimitry Andric kmp_team_t *team = thr->th.th_team; 2153fe6060f1SDimitry Andric uintptr_t *reduce_data = *(uintptr_t **)data; 2154fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(*gtid, reduce_data, 0); 2155fe6060f1SDimitry Andric 2156fe6060f1SDimitry Andric #if OMPT_SUPPORT 2157fe6060f1SDimitry Andric ompt_frame_t *ompt_frame; 2158fe6060f1SDimitry Andric ompt_state_t enclosing_state; 2159fe6060f1SDimitry Andric 2160fe6060f1SDimitry Andric if (ompt_enabled.enabled) { 2161fe6060f1SDimitry Andric // save enclosing task state; set current state for task 2162fe6060f1SDimitry Andric enclosing_state = thr->th.ompt_thread_info.state; 2163fe6060f1SDimitry Andric thr->th.ompt_thread_info.state = ompt_state_work_parallel; 2164fe6060f1SDimitry Andric 2165fe6060f1SDimitry Andric // set task frame 2166fe6060f1SDimitry Andric __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL); 2167fe6060f1SDimitry Andric ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); 2168fe6060f1SDimitry Andric } 2169fe6060f1SDimitry Andric #endif 2170fe6060f1SDimitry Andric 2171fe6060f1SDimitry Andric task(data); 2172fe6060f1SDimitry Andric 2173fe6060f1SDimitry Andric #if OMPT_SUPPORT 2174fe6060f1SDimitry Andric if (ompt_enabled.enabled) { 2175fe6060f1SDimitry Andric // clear task frame 2176fe6060f1SDimitry Andric ompt_frame->exit_frame = ompt_data_none; 2177fe6060f1SDimitry Andric 2178fe6060f1SDimitry Andric // restore enclosing state 2179fe6060f1SDimitry Andric thr->th.ompt_thread_info.state = enclosing_state; 2180fe6060f1SDimitry Andric } 2181fe6060f1SDimitry Andric #endif 2182fe6060f1SDimitry Andric __kmpc_end_taskgroup(NULL, *gtid); 2183fe6060f1SDimitry Andric // if last thread out, then reset the team's reduce data 2184fe6060f1SDimitry Andric // the GOMP_taskgroup_reduction_unregister() function will deallocate 2185fe6060f1SDimitry Andric // private copies after reduction calculations take place. 2186fe6060f1SDimitry Andric int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[0]); 2187fe6060f1SDimitry Andric if (count == thr->th.th_team_nproc - 1) { 2188fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[0], NULL); 2189fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[0], 0); 2190fe6060f1SDimitry Andric } 2191fe6060f1SDimitry Andric return (unsigned)thr->th.th_team_nproc; 2192fe6060f1SDimitry Andric } 2193fe6060f1SDimitry Andric 2194fe6060f1SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS)( 2195fe6060f1SDimitry Andric void (*task)(void *), void *data, unsigned num_threads, 2196fe6060f1SDimitry Andric unsigned int flags) { 2197fe6060f1SDimitry Andric MKLOC(loc, "GOMP_parallel_reductions"); 2198fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2199fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_parallel_reductions: T#%d\n", gtid)); 2200fe6060f1SDimitry Andric __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task, 2201fe6060f1SDimitry Andric (microtask_t)__kmp_GOMP_par_reductions_microtask_wrapper, 2202fe6060f1SDimitry Andric 2, task, data); 2203fe6060f1SDimitry Andric unsigned retval = 2204fe6060f1SDimitry Andric __kmp_GOMP_par_reductions_microtask_wrapper(>id, NULL, task, data); 2205fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(); 2206fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_parallel_reductions exit: T#%d\n", gtid)); 2207fe6060f1SDimitry Andric return retval; 2208fe6060f1SDimitry Andric } 2209fe6060f1SDimitry Andric 2210fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_START)( 2211fe6060f1SDimitry Andric long start, long end, long incr, long sched, long chunk_size, long *istart, 2212fe6060f1SDimitry Andric long *iend, uintptr_t *reductions, void **mem) { 2213fe6060f1SDimitry Andric int status = 0; 2214fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2215fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_loop_start: T#%d, reductions: %p\n", gtid, reductions)); 2216fe6060f1SDimitry Andric if (reductions) 2217fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2218fe6060f1SDimitry Andric if (mem) 2219fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2220fe6060f1SDimitry Andric if (istart == NULL) 2221fe6060f1SDimitry Andric return true; 2222fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2223fe6060f1SDimitry Andric long monotonic = sched & MONOTONIC_FLAG; 2224fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2225fe6060f1SDimitry Andric if (sched == 0) { 2226fe6060f1SDimitry Andric if (monotonic) 2227fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START)( 2228fe6060f1SDimitry Andric start, end, incr, istart, iend); 2229fe6060f1SDimitry Andric else 2230fe6060f1SDimitry Andric status = KMP_EXPAND_NAME( 2231fe6060f1SDimitry Andric KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START)( 2232fe6060f1SDimitry Andric start, end, incr, istart, iend); 2233fe6060f1SDimitry Andric } else if (sched == 1) { 2234fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START)( 2235fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2236fe6060f1SDimitry Andric } else if (sched == 2) { 2237fe6060f1SDimitry Andric if (monotonic) 2238fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START)( 2239fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2240fe6060f1SDimitry Andric else 2241fe6060f1SDimitry Andric status = 2242fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START)( 2243fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2244fe6060f1SDimitry Andric } else if (sched == 3) { 2245fe6060f1SDimitry Andric if (monotonic) 2246fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START)( 2247fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2248fe6060f1SDimitry Andric else 2249fe6060f1SDimitry Andric status = 2250fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START)( 2251fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2252fe6060f1SDimitry Andric } else if (sched == 4) { 2253fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START)( 2254fe6060f1SDimitry Andric start, end, incr, istart, iend); 2255fe6060f1SDimitry Andric } else { 2256fe6060f1SDimitry Andric KMP_ASSERT(0); 2257fe6060f1SDimitry Andric } 2258fe6060f1SDimitry Andric return status; 2259fe6060f1SDimitry Andric } 2260fe6060f1SDimitry Andric 2261fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_START)( 2262fe6060f1SDimitry Andric bool up, unsigned long long start, unsigned long long end, 2263fe6060f1SDimitry Andric unsigned long long incr, long sched, unsigned long long chunk_size, 2264fe6060f1SDimitry Andric unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions, 2265fe6060f1SDimitry Andric void **mem) { 2266fe6060f1SDimitry Andric int status = 0; 2267fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2268fe6060f1SDimitry Andric KA_TRACE(20, 2269fe6060f1SDimitry Andric ("GOMP_loop_ull_start: T#%d, reductions: %p\n", gtid, reductions)); 2270fe6060f1SDimitry Andric if (reductions) 2271fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2272fe6060f1SDimitry Andric if (mem) 2273fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2274fe6060f1SDimitry Andric if (istart == NULL) 2275fe6060f1SDimitry Andric return true; 2276fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2277fe6060f1SDimitry Andric long monotonic = sched & MONOTONIC_FLAG; 2278fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2279fe6060f1SDimitry Andric if (sched == 0) { 2280fe6060f1SDimitry Andric if (monotonic) 2281fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START)( 2282fe6060f1SDimitry Andric up, start, end, incr, istart, iend); 2283fe6060f1SDimitry Andric else 2284fe6060f1SDimitry Andric status = KMP_EXPAND_NAME( 2285fe6060f1SDimitry Andric KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START)( 2286fe6060f1SDimitry Andric up, start, end, incr, istart, iend); 2287fe6060f1SDimitry Andric } else if (sched == 1) { 2288fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START)( 2289fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2290fe6060f1SDimitry Andric } else if (sched == 2) { 2291fe6060f1SDimitry Andric if (monotonic) 2292fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START)( 2293fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2294fe6060f1SDimitry Andric else 2295fe6060f1SDimitry Andric status = KMP_EXPAND_NAME( 2296fe6060f1SDimitry Andric KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START)( 2297fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2298fe6060f1SDimitry Andric } else if (sched == 3) { 2299fe6060f1SDimitry Andric if (monotonic) 2300fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START)( 2301fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2302fe6060f1SDimitry Andric else 2303fe6060f1SDimitry Andric status = 2304fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START)( 2305fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2306fe6060f1SDimitry Andric } else if (sched == 4) { 2307fe6060f1SDimitry Andric status = 2308fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START)( 2309fe6060f1SDimitry Andric up, start, end, incr, istart, iend); 2310fe6060f1SDimitry Andric } else { 2311fe6060f1SDimitry Andric KMP_ASSERT(0); 2312fe6060f1SDimitry Andric } 2313fe6060f1SDimitry Andric return status; 2314fe6060f1SDimitry Andric } 2315fe6060f1SDimitry Andric 2316fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_START)( 2317fe6060f1SDimitry Andric unsigned ncounts, long *counts, long sched, long chunk_size, long *istart, 2318fe6060f1SDimitry Andric long *iend, uintptr_t *reductions, void **mem) { 2319fe6060f1SDimitry Andric int status = 0; 2320fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2321fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_loop_doacross_start: T#%d, reductions: %p\n", gtid, 2322fe6060f1SDimitry Andric reductions)); 2323fe6060f1SDimitry Andric if (reductions) 2324fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2325fe6060f1SDimitry Andric if (mem) 2326fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2327fe6060f1SDimitry Andric if (istart == NULL) 2328fe6060f1SDimitry Andric return true; 2329fe6060f1SDimitry Andric // Ignore any monotonic flag 2330fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2331fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2332fe6060f1SDimitry Andric if (sched == 0) { 2333fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START)( 2334fe6060f1SDimitry Andric ncounts, counts, istart, iend); 2335fe6060f1SDimitry Andric } else if (sched == 1) { 2336fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START)( 2337fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2338fe6060f1SDimitry Andric } else if (sched == 2) { 2339fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START)( 2340fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2341fe6060f1SDimitry Andric } else if (sched == 3) { 2342fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START)( 2343fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2344fe6060f1SDimitry Andric } else { 2345fe6060f1SDimitry Andric KMP_ASSERT(0); 2346fe6060f1SDimitry Andric } 2347fe6060f1SDimitry Andric return status; 2348fe6060f1SDimitry Andric } 2349fe6060f1SDimitry Andric 2350fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START)( 2351fe6060f1SDimitry Andric unsigned ncounts, unsigned long long *counts, long sched, 2352fe6060f1SDimitry Andric unsigned long long chunk_size, unsigned long long *istart, 2353fe6060f1SDimitry Andric unsigned long long *iend, uintptr_t *reductions, void **mem) { 2354fe6060f1SDimitry Andric int status = 0; 2355fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2356fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_loop_ull_doacross_start: T#%d, reductions: %p\n", gtid, 2357fe6060f1SDimitry Andric reductions)); 2358fe6060f1SDimitry Andric if (reductions) 2359fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2360fe6060f1SDimitry Andric if (mem) 2361fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2362fe6060f1SDimitry Andric if (istart == NULL) 2363fe6060f1SDimitry Andric return true; 2364fe6060f1SDimitry Andric // Ignore any monotonic flag 2365fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2366fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2367fe6060f1SDimitry Andric if (sched == 0) { 2368fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START)( 2369fe6060f1SDimitry Andric ncounts, counts, istart, iend); 2370fe6060f1SDimitry Andric } else if (sched == 1) { 2371fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START)( 2372fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2373fe6060f1SDimitry Andric } else if (sched == 2) { 2374fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START)( 2375fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2376fe6060f1SDimitry Andric } else if (sched == 3) { 2377fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START)( 2378fe6060f1SDimitry Andric ncounts, counts, chunk_size, istart, iend); 2379fe6060f1SDimitry Andric } else { 2380fe6060f1SDimitry Andric KMP_ASSERT(0); 2381fe6060f1SDimitry Andric } 2382fe6060f1SDimitry Andric return status; 2383fe6060f1SDimitry Andric } 2384fe6060f1SDimitry Andric 2385fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_START)( 2386fe6060f1SDimitry Andric long start, long end, long incr, long sched, long chunk_size, long *istart, 2387fe6060f1SDimitry Andric long *iend, uintptr_t *reductions, void **mem) { 2388fe6060f1SDimitry Andric int status = 0; 2389fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2390fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_loop_ordered_start: T#%d, reductions: %p\n", gtid, 2391fe6060f1SDimitry Andric reductions)); 2392fe6060f1SDimitry Andric if (reductions) 2393fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2394fe6060f1SDimitry Andric if (mem) 2395fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2396fe6060f1SDimitry Andric if (istart == NULL) 2397fe6060f1SDimitry Andric return true; 2398fe6060f1SDimitry Andric // Ignore any monotonic flag 2399fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2400fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2401fe6060f1SDimitry Andric if (sched == 0) { 2402fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START)( 2403fe6060f1SDimitry Andric start, end, incr, istart, iend); 2404fe6060f1SDimitry Andric } else if (sched == 1) { 2405fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START)( 2406fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2407fe6060f1SDimitry Andric } else if (sched == 2) { 2408fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START)( 2409fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2410fe6060f1SDimitry Andric } else if (sched == 3) { 2411fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START)( 2412fe6060f1SDimitry Andric start, end, incr, chunk_size, istart, iend); 2413fe6060f1SDimitry Andric } else { 2414fe6060f1SDimitry Andric KMP_ASSERT(0); 2415fe6060f1SDimitry Andric } 2416fe6060f1SDimitry Andric return status; 2417fe6060f1SDimitry Andric } 2418fe6060f1SDimitry Andric 2419fe6060f1SDimitry Andric bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START)( 2420fe6060f1SDimitry Andric bool up, unsigned long long start, unsigned long long end, 2421fe6060f1SDimitry Andric unsigned long long incr, long sched, unsigned long long chunk_size, 2422fe6060f1SDimitry Andric unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions, 2423fe6060f1SDimitry Andric void **mem) { 2424fe6060f1SDimitry Andric int status = 0; 2425fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2426fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_loop_ull_ordered_start: T#%d, reductions: %p\n", gtid, 2427fe6060f1SDimitry Andric reductions)); 2428fe6060f1SDimitry Andric if (reductions) 2429fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2430fe6060f1SDimitry Andric if (mem) 2431fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2432fe6060f1SDimitry Andric if (istart == NULL) 2433fe6060f1SDimitry Andric return true; 2434fe6060f1SDimitry Andric // Ignore any monotonic flag 2435fe6060f1SDimitry Andric const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic); 2436fe6060f1SDimitry Andric sched &= ~MONOTONIC_FLAG; 2437fe6060f1SDimitry Andric if (sched == 0) { 2438fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START)( 2439fe6060f1SDimitry Andric up, start, end, incr, istart, iend); 2440fe6060f1SDimitry Andric } else if (sched == 1) { 2441fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START)( 2442fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2443fe6060f1SDimitry Andric } else if (sched == 2) { 2444fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START)( 2445fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2446fe6060f1SDimitry Andric } else if (sched == 3) { 2447fe6060f1SDimitry Andric status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START)( 2448fe6060f1SDimitry Andric up, start, end, incr, chunk_size, istart, iend); 2449fe6060f1SDimitry Andric } else { 2450fe6060f1SDimitry Andric KMP_ASSERT(0); 2451fe6060f1SDimitry Andric } 2452fe6060f1SDimitry Andric return status; 2453fe6060f1SDimitry Andric } 2454fe6060f1SDimitry Andric 2455fe6060f1SDimitry Andric unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS2_START)( 2456fe6060f1SDimitry Andric unsigned count, uintptr_t *reductions, void **mem) { 2457fe6060f1SDimitry Andric int gtid = __kmp_entry_gtid(); 2458fe6060f1SDimitry Andric KA_TRACE(20, 2459fe6060f1SDimitry Andric ("GOMP_sections2_start: T#%d, reductions: %p\n", gtid, reductions)); 2460fe6060f1SDimitry Andric if (reductions) 2461fe6060f1SDimitry Andric __kmp_GOMP_init_reductions(gtid, reductions, 1); 2462fe6060f1SDimitry Andric if (mem) 2463fe6060f1SDimitry Andric KMP_FATAL(GompFeatureNotSupported, "scan"); 2464fe6060f1SDimitry Andric return KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(count); 2465fe6060f1SDimitry Andric } 2466fe6060f1SDimitry Andric 2467fe6060f1SDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER)( 2468fe6060f1SDimitry Andric bool cancelled) { 2469fe6060f1SDimitry Andric int gtid = __kmp_get_gtid(); 2470fe6060f1SDimitry Andric MKLOC(loc, "GOMP_workshare_task_reduction_unregister"); 2471fe6060f1SDimitry Andric KA_TRACE(20, ("GOMP_workshare_task_reduction_unregister: T#%d\n", gtid)); 2472fe6060f1SDimitry Andric kmp_info_t *thr = __kmp_threads[gtid]; 2473fe6060f1SDimitry Andric kmp_team_t *team = thr->th.th_team; 2474fe6060f1SDimitry Andric __kmpc_end_taskgroup(NULL, gtid); 2475fe6060f1SDimitry Andric // If last thread out of workshare, then reset the team's reduce data 2476fe6060f1SDimitry Andric // the GOMP_taskgroup_reduction_unregister() function will deallocate 2477fe6060f1SDimitry Andric // private copies after reduction calculations take place. 2478fe6060f1SDimitry Andric int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[1]); 2479fe6060f1SDimitry Andric if (count == thr->th.th_team_nproc - 1) { 2480fe6060f1SDimitry Andric KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER) 2481fe6060f1SDimitry Andric ((uintptr_t *)KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[1])); 2482fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[1], NULL); 2483fe6060f1SDimitry Andric KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[1], 0); 2484fe6060f1SDimitry Andric } 2485fe6060f1SDimitry Andric if (!cancelled) { 2486fe6060f1SDimitry Andric __kmpc_barrier(&loc, gtid); 2487fe6060f1SDimitry Andric } 2488fe6060f1SDimitry Andric } 2489fe6060f1SDimitry Andric 2490349cc55cSDimitry Andric // allocator construct 2491349cc55cSDimitry Andric void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ALLOC)(size_t alignment, size_t size, 2492349cc55cSDimitry Andric uintptr_t allocator) { 2493349cc55cSDimitry Andric int gtid = __kmp_entry_gtid(); 2494349cc55cSDimitry Andric KA_TRACE(20, ("GOMP_alloc: T#%d\n", gtid)); 2495349cc55cSDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2496349cc55cSDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 2497349cc55cSDimitry Andric #endif 2498349cc55cSDimitry Andric return __kmp_alloc(gtid, alignment, size, (omp_allocator_handle_t)allocator); 2499349cc55cSDimitry Andric } 2500349cc55cSDimitry Andric 2501349cc55cSDimitry Andric void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_FREE)(void *ptr, uintptr_t allocator) { 2502349cc55cSDimitry Andric int gtid = __kmp_entry_gtid(); 2503349cc55cSDimitry Andric KA_TRACE(20, ("GOMP_free: T#%d\n", gtid)); 2504349cc55cSDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 2505349cc55cSDimitry Andric OMPT_STORE_RETURN_ADDRESS(gtid); 2506349cc55cSDimitry Andric #endif 2507349cc55cSDimitry Andric return ___kmpc_free(gtid, ptr, (omp_allocator_handle_t)allocator); 2508349cc55cSDimitry Andric } 2509349cc55cSDimitry Andric 25100b57cec5SDimitry Andric /* The following sections of code create aliases for the GOMP_* functions, then 25110b57cec5SDimitry Andric create versioned symbols using the assembler directive .symver. This is only 25120b57cec5SDimitry Andric pertinent for ELF .so library. The KMP_VERSION_SYMBOL macro is defined in 25130b57cec5SDimitry Andric kmp_os.h */ 25140b57cec5SDimitry Andric 25150b57cec5SDimitry Andric #ifdef KMP_USE_VERSION_SYMBOLS 25160b57cec5SDimitry Andric // GOMP_1.0 versioned symbols 25170b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_END, 10, "GOMP_1.0"); 25180b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_START, 10, "GOMP_1.0"); 25190b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER, 10, "GOMP_1.0"); 25200b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_END, 10, "GOMP_1.0"); 25210b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10, "GOMP_1.0"); 25220b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10, "GOMP_1.0"); 25230b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_START, 10, "GOMP_1.0"); 25240b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10, "GOMP_1.0"); 25250b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10, "GOMP_1.0"); 25260b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END, 10, "GOMP_1.0"); 25270b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10, "GOMP_1.0"); 25280b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10, "GOMP_1.0"); 25290b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10, "GOMP_1.0"); 25300b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10, "GOMP_1.0"); 25310b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10, 25320b57cec5SDimitry Andric "GOMP_1.0"); 25330b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10, "GOMP_1.0"); 25340b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10, "GOMP_1.0"); 25350b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10, "GOMP_1.0"); 25360b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10, 25370b57cec5SDimitry Andric "GOMP_1.0"); 25380b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10, "GOMP_1.0"); 25390b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10, "GOMP_1.0"); 25400b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10, "GOMP_1.0"); 25410b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10, "GOMP_1.0"); 25420b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10, "GOMP_1.0"); 25430b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10, "GOMP_1.0"); 25440b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_END, 10, "GOMP_1.0"); 25450b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_START, 10, "GOMP_1.0"); 25460b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_END, 10, "GOMP_1.0"); 25470b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10, 25480b57cec5SDimitry Andric "GOMP_1.0"); 25490b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10, 25500b57cec5SDimitry Andric "GOMP_1.0"); 25510b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10, 25520b57cec5SDimitry Andric "GOMP_1.0"); 25530b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10, 25540b57cec5SDimitry Andric "GOMP_1.0"); 25550b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10, "GOMP_1.0"); 25560b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_START, 10, "GOMP_1.0"); 25570b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END, 10, "GOMP_1.0"); 25580b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10, "GOMP_1.0"); 25590b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10, "GOMP_1.0"); 25600b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_START, 10, "GOMP_1.0"); 25610b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10, "GOMP_1.0"); 25620b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10, "GOMP_1.0"); 25630b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_START, 10, "GOMP_1.0"); 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric // GOMP_2.0 versioned symbols 25660b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK, 20, "GOMP_2.0"); 25670b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT, 20, "GOMP_2.0"); 25680b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20, "GOMP_2.0"); 25690b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20, "GOMP_2.0"); 25700b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20, "GOMP_2.0"); 25710b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20, "GOMP_2.0"); 25720b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20, 25730b57cec5SDimitry Andric "GOMP_2.0"); 25740b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20, 25750b57cec5SDimitry Andric "GOMP_2.0"); 25760b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20, 25770b57cec5SDimitry Andric "GOMP_2.0"); 25780b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20, 25790b57cec5SDimitry Andric "GOMP_2.0"); 25800b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20, 25810b57cec5SDimitry Andric "GOMP_2.0"); 25820b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20, 25830b57cec5SDimitry Andric "GOMP_2.0"); 25840b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20, 25850b57cec5SDimitry Andric "GOMP_2.0"); 25860b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20, 25870b57cec5SDimitry Andric "GOMP_2.0"); 25880b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20, "GOMP_2.0"); 25890b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20, "GOMP_2.0"); 25900b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20, "GOMP_2.0"); 25910b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20, "GOMP_2.0"); 25920b57cec5SDimitry Andric 25930b57cec5SDimitry Andric // GOMP_3.0 versioned symbols 25940b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKYIELD, 30, "GOMP_3.0"); 25950b57cec5SDimitry Andric 25960b57cec5SDimitry Andric // GOMP_4.0 versioned symbols 25970b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL, 40, "GOMP_4.0"); 25980b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40, "GOMP_4.0"); 25990b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40, "GOMP_4.0"); 26000b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40, "GOMP_4.0"); 26010b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40, "GOMP_4.0"); 26020b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40, "GOMP_4.0"); 26030b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_START, 40, "GOMP_4.0"); 26040b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_END, 40, "GOMP_4.0"); 26050b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40, "GOMP_4.0"); 26060b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCEL, 40, "GOMP_4.0"); 26070b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40, "GOMP_4.0"); 26080b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40, "GOMP_4.0"); 26090b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40, "GOMP_4.0"); 26100b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET, 40, "GOMP_4.0"); 26110b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_DATA, 40, "GOMP_4.0"); 26120b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_END_DATA, 40, "GOMP_4.0"); 26130b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0"); 26140b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0"); 26150b57cec5SDimitry Andric 26160b57cec5SDimitry Andric // GOMP_4.5 versioned symbols 26170b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP, 45, "GOMP_4.5"); 26180b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP_ULL, 45, "GOMP_4.5"); 26190b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_POST, 45, "GOMP_4.5"); 26200b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_WAIT, 45, "GOMP_4.5"); 26210b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START, 45, 26220b57cec5SDimitry Andric "GOMP_4.5"); 26230b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START, 45, 26240b57cec5SDimitry Andric "GOMP_4.5"); 26250b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START, 45, 26260b57cec5SDimitry Andric "GOMP_4.5"); 26270b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START, 45, 26280b57cec5SDimitry Andric "GOMP_4.5"); 26290b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_POST, 45, "GOMP_4.5"); 26300b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT, 45, "GOMP_4.5"); 26310b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START, 45, 26320b57cec5SDimitry Andric "GOMP_4.5"); 26330b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START, 45, 26340b57cec5SDimitry Andric "GOMP_4.5"); 26350b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START, 45, 26360b57cec5SDimitry Andric "GOMP_4.5"); 26370b57cec5SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START, 45, 26380b57cec5SDimitry Andric "GOMP_4.5"); 2639489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START, 45, 2640489b1cf2SDimitry Andric "GOMP_4.5"); 2641489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT, 45, 2642489b1cf2SDimitry Andric "GOMP_4.5"); 2643489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START, 45, 2644489b1cf2SDimitry Andric "GOMP_4.5"); 2645489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT, 45, 2646489b1cf2SDimitry Andric "GOMP_4.5"); 2647489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START, 45, 2648489b1cf2SDimitry Andric "GOMP_4.5"); 2649489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT, 45, 2650489b1cf2SDimitry Andric "GOMP_4.5"); 2651489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START, 45, 2652489b1cf2SDimitry Andric "GOMP_4.5"); 2653489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT, 45, 2654489b1cf2SDimitry Andric "GOMP_4.5"); 2655489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC, 45, 2656489b1cf2SDimitry Andric "GOMP_4.5"); 2657489b1cf2SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED, 45, 2658489b1cf2SDimitry Andric "GOMP_4.5"); 26590b57cec5SDimitry Andric 26605ffd83dbSDimitry Andric // GOMP_5.0 versioned symbols 26615ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT, 50, 26625ffd83dbSDimitry Andric "GOMP_5.0"); 26635ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START, 50, 26645ffd83dbSDimitry Andric "GOMP_5.0"); 26655ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT, 50, 26665ffd83dbSDimitry Andric "GOMP_5.0"); 26675ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START, 50, 26685ffd83dbSDimitry Andric "GOMP_5.0"); 26695ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT, 26705ffd83dbSDimitry Andric 50, "GOMP_5.0"); 26715ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START, 26725ffd83dbSDimitry Andric 50, "GOMP_5.0"); 26735ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT, 50, 26745ffd83dbSDimitry Andric "GOMP_5.0"); 26755ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START, 50, 26765ffd83dbSDimitry Andric "GOMP_5.0"); 26775ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME, 50, 26785ffd83dbSDimitry Andric "GOMP_5.0"); 26795ffd83dbSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME, 26805ffd83dbSDimitry Andric 50, "GOMP_5.0"); 2681e8d8bef9SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS_REG, 50, "GOMP_5.0"); 2682e8d8bef9SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT_DEPEND, 50, "GOMP_5.0"); 2683fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER, 50, 2684fe6060f1SDimitry Andric "GOMP_5.0"); 2685fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER, 50, 2686fe6060f1SDimitry Andric "GOMP_5.0"); 2687fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP, 50, "GOMP_5.0"); 2688fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS, 50, "GOMP_5.0"); 2689fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_START, 50, "GOMP_5.0"); 2690fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_START, 50, "GOMP_5.0"); 2691fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_START, 50, "GOMP_5.0"); 2692fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START, 50, "GOMP_5.0"); 2693fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_START, 50, "GOMP_5.0"); 2694fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START, 50, "GOMP_5.0"); 2695fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS2_START, 50, "GOMP_5.0"); 2696fe6060f1SDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER, 50, 2697fe6060f1SDimitry Andric "GOMP_5.0"); 2698349cc55cSDimitry Andric 2699349cc55cSDimitry Andric // GOMP_5.0.1 versioned symbols 2700349cc55cSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ALLOC, 501, "GOMP_5.0.1"); 2701349cc55cSDimitry Andric KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_FREE, 501, "GOMP_5.0.1"); 27020b57cec5SDimitry Andric #endif // KMP_USE_VERSION_SYMBOLS 27030b57cec5SDimitry Andric 27040b57cec5SDimitry Andric #ifdef __cplusplus 27050b57cec5SDimitry Andric } // extern "C" 27060b57cec5SDimitry Andric #endif // __cplusplus 2707