kmp_gsupport.cpp 116 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704
  1. /*
  2. * kmp_gsupport.cpp
  3. */
  4. //===----------------------------------------------------------------------===//
  5. //
  6. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  7. // See https://llvm.org/LICENSE.txt for license information.
  8. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #include "kmp.h"
  12. #include "kmp_atomic.h"
  13. #if OMPT_SUPPORT
  14. #include "ompt-specific.h"
  15. #endif
  16. enum {
  17. KMP_GOMP_TASK_UNTIED_FLAG = 1,
  18. KMP_GOMP_TASK_FINAL_FLAG = 2,
  19. KMP_GOMP_TASK_DEPENDS_FLAG = 8
  20. };
  21. enum {
  22. KMP_GOMP_DEPOBJ_IN = 1,
  23. KMP_GOMP_DEPOBJ_OUT = 2,
  24. KMP_GOMP_DEPOBJ_INOUT = 3,
  25. KMP_GOMP_DEPOBJ_MTXINOUTSET = 4
  26. };
  27. // This class helps convert gomp dependency info into
  28. // kmp_depend_info_t structures
  29. class kmp_gomp_depends_info_t {
  30. void **depend;
  31. kmp_int32 num_deps;
  32. size_t num_out, num_mutexinout, num_in, num_depobj;
  33. size_t offset;
  34. public:
  35. kmp_gomp_depends_info_t(void **depend) : depend(depend) {
  36. size_t ndeps = (kmp_intptr_t)depend[0];
  37. // GOMP taskdep structure:
  38. // if depend[0] != 0:
  39. // depend = [ ndeps | nout | &out | ... | &out | &in | ... | &in ]
  40. //
  41. // if depend[0] == 0:
  42. // depend = [ 0 | ndeps | nout | nmtx | nin | &out | ... | &out | &mtx |
  43. // ... | &mtx | &in | ... | &in | &depobj | ... | &depobj ]
  44. if (ndeps) {
  45. num_out = (kmp_intptr_t)depend[1];
  46. num_in = ndeps - num_out;
  47. num_mutexinout = num_depobj = 0;
  48. offset = 2;
  49. } else {
  50. ndeps = (kmp_intptr_t)depend[1];
  51. num_out = (kmp_intptr_t)depend[2];
  52. num_mutexinout = (kmp_intptr_t)depend[3];
  53. num_in = (kmp_intptr_t)depend[4];
  54. num_depobj = ndeps - num_out - num_mutexinout - num_in;
  55. KMP_ASSERT(num_depobj <= ndeps);
  56. offset = 5;
  57. }
  58. num_deps = static_cast<kmp_int32>(ndeps);
  59. }
  60. kmp_int32 get_num_deps() const { return num_deps; }
  61. kmp_depend_info_t get_kmp_depend(size_t index) const {
  62. kmp_depend_info_t retval;
  63. memset(&retval, '\0', sizeof(retval));
  64. KMP_ASSERT(index < (size_t)num_deps);
  65. retval.len = 0;
  66. // Because inout and out are logically equivalent,
  67. // use inout and in dependency flags. GOMP does not provide a
  68. // way to distinguish if user specified out vs. inout.
  69. if (index < num_out) {
  70. retval.flags.in = 1;
  71. retval.flags.out = 1;
  72. retval.base_addr = (kmp_intptr_t)depend[offset + index];
  73. } else if (index >= num_out && index < (num_out + num_mutexinout)) {
  74. retval.flags.mtx = 1;
  75. retval.base_addr = (kmp_intptr_t)depend[offset + index];
  76. } else if (index >= (num_out + num_mutexinout) &&
  77. index < (num_out + num_mutexinout + num_in)) {
  78. retval.flags.in = 1;
  79. retval.base_addr = (kmp_intptr_t)depend[offset + index];
  80. } else {
  81. // depobj is a two element array (size of elements are size of pointer)
  82. // depobj[0] = base_addr
  83. // depobj[1] = type (in, out, inout, mutexinoutset, etc.)
  84. kmp_intptr_t *depobj = (kmp_intptr_t *)depend[offset + index];
  85. retval.base_addr = depobj[0];
  86. switch (depobj[1]) {
  87. case KMP_GOMP_DEPOBJ_IN:
  88. retval.flags.in = 1;
  89. break;
  90. case KMP_GOMP_DEPOBJ_OUT:
  91. retval.flags.out = 1;
  92. break;
  93. case KMP_GOMP_DEPOBJ_INOUT:
  94. retval.flags.in = 1;
  95. retval.flags.out = 1;
  96. break;
  97. case KMP_GOMP_DEPOBJ_MTXINOUTSET:
  98. retval.flags.mtx = 1;
  99. break;
  100. default:
  101. KMP_FATAL(GompFeatureNotSupported, "Unknown depobj type");
  102. }
  103. }
  104. return retval;
  105. }
  106. };
  107. #ifdef __cplusplus
  108. extern "C" {
  109. #endif // __cplusplus
  110. #define MKLOC(loc, routine) \
  111. static ident_t loc = {0, KMP_IDENT_KMPC, 0, 0, ";unknown;unknown;0;0;;"};
  112. #include "kmp_ftn_os.h"
  113. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER)(void) {
  114. int gtid = __kmp_entry_gtid();
  115. MKLOC(loc, "GOMP_barrier");
  116. KA_TRACE(20, ("GOMP_barrier: T#%d\n", gtid));
  117. #if OMPT_SUPPORT && OMPT_OPTIONAL
  118. ompt_frame_t *ompt_frame;
  119. if (ompt_enabled.enabled) {
  120. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  121. ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  122. }
  123. OMPT_STORE_RETURN_ADDRESS(gtid);
  124. #endif
  125. __kmpc_barrier(&loc, gtid);
  126. #if OMPT_SUPPORT && OMPT_OPTIONAL
  127. if (ompt_enabled.enabled) {
  128. ompt_frame->enter_frame = ompt_data_none;
  129. }
  130. #endif
  131. }
  132. // Mutual exclusion
  133. // The symbol that icc/ifort generates for unnamed for unnamed critical sections
  134. // - .gomp_critical_user_ - is defined using .comm in any objects reference it.
  135. // We can't reference it directly here in C code, as the symbol contains a ".".
  136. //
  137. // The RTL contains an assembly language definition of .gomp_critical_user_
  138. // with another symbol __kmp_unnamed_critical_addr initialized with it's
  139. // address.
  140. extern kmp_critical_name *__kmp_unnamed_critical_addr;
  141. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_START)(void) {
  142. int gtid = __kmp_entry_gtid();
  143. MKLOC(loc, "GOMP_critical_start");
  144. KA_TRACE(20, ("GOMP_critical_start: T#%d\n", gtid));
  145. #if OMPT_SUPPORT && OMPT_OPTIONAL
  146. OMPT_STORE_RETURN_ADDRESS(gtid);
  147. #endif
  148. __kmpc_critical(&loc, gtid, __kmp_unnamed_critical_addr);
  149. }
  150. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_END)(void) {
  151. int gtid = __kmp_get_gtid();
  152. MKLOC(loc, "GOMP_critical_end");
  153. KA_TRACE(20, ("GOMP_critical_end: T#%d\n", gtid));
  154. #if OMPT_SUPPORT && OMPT_OPTIONAL
  155. OMPT_STORE_RETURN_ADDRESS(gtid);
  156. #endif
  157. __kmpc_end_critical(&loc, gtid, __kmp_unnamed_critical_addr);
  158. }
  159. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_START)(void **pptr) {
  160. int gtid = __kmp_entry_gtid();
  161. MKLOC(loc, "GOMP_critical_name_start");
  162. KA_TRACE(20, ("GOMP_critical_name_start: T#%d\n", gtid));
  163. __kmpc_critical(&loc, gtid, (kmp_critical_name *)pptr);
  164. }
  165. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CRITICAL_NAME_END)(void **pptr) {
  166. int gtid = __kmp_get_gtid();
  167. MKLOC(loc, "GOMP_critical_name_end");
  168. KA_TRACE(20, ("GOMP_critical_name_end: T#%d\n", gtid));
  169. __kmpc_end_critical(&loc, gtid, (kmp_critical_name *)pptr);
  170. }
  171. // The Gnu codegen tries to use locked operations to perform atomic updates
  172. // inline. If it can't, then it calls GOMP_atomic_start() before performing
  173. // the update and GOMP_atomic_end() afterward, regardless of the data type.
  174. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_START)(void) {
  175. int gtid = __kmp_entry_gtid();
  176. KA_TRACE(20, ("GOMP_atomic_start: T#%d\n", gtid));
  177. #if OMPT_SUPPORT
  178. __ompt_thread_assign_wait_id(0);
  179. #endif
  180. __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
  181. }
  182. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ATOMIC_END)(void) {
  183. int gtid = __kmp_get_gtid();
  184. KA_TRACE(20, ("GOMP_atomic_end: T#%d\n", gtid));
  185. __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
  186. }
  187. int KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_START)(void) {
  188. int gtid = __kmp_entry_gtid();
  189. MKLOC(loc, "GOMP_single_start");
  190. KA_TRACE(20, ("GOMP_single_start: T#%d\n", gtid));
  191. if (!TCR_4(__kmp_init_parallel))
  192. __kmp_parallel_initialize();
  193. __kmp_resume_if_soft_paused();
  194. // 3rd parameter == FALSE prevents kmp_enter_single from pushing a
  195. // workshare when USE_CHECKS is defined. We need to avoid the push,
  196. // as there is no corresponding GOMP_single_end() call.
  197. kmp_int32 rc = __kmp_enter_single(gtid, &loc, FALSE);
  198. #if OMPT_SUPPORT && OMPT_OPTIONAL
  199. kmp_info_t *this_thr = __kmp_threads[gtid];
  200. kmp_team_t *team = this_thr->th.th_team;
  201. int tid = __kmp_tid_from_gtid(gtid);
  202. if (ompt_enabled.enabled) {
  203. if (rc) {
  204. if (ompt_enabled.ompt_callback_work) {
  205. ompt_callbacks.ompt_callback(ompt_callback_work)(
  206. ompt_work_single_executor, ompt_scope_begin,
  207. &(team->t.ompt_team_info.parallel_data),
  208. &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
  209. 1, OMPT_GET_RETURN_ADDRESS(0));
  210. }
  211. } else {
  212. if (ompt_enabled.ompt_callback_work) {
  213. ompt_callbacks.ompt_callback(ompt_callback_work)(
  214. ompt_work_single_other, ompt_scope_begin,
  215. &(team->t.ompt_team_info.parallel_data),
  216. &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
  217. 1, OMPT_GET_RETURN_ADDRESS(0));
  218. ompt_callbacks.ompt_callback(ompt_callback_work)(
  219. ompt_work_single_other, ompt_scope_end,
  220. &(team->t.ompt_team_info.parallel_data),
  221. &(team->t.t_implicit_task_taskdata[tid].ompt_task_info.task_data),
  222. 1, OMPT_GET_RETURN_ADDRESS(0));
  223. }
  224. }
  225. }
  226. #endif
  227. return rc;
  228. }
  229. void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_START)(void) {
  230. void *retval;
  231. int gtid = __kmp_entry_gtid();
  232. MKLOC(loc, "GOMP_single_copy_start");
  233. KA_TRACE(20, ("GOMP_single_copy_start: T#%d\n", gtid));
  234. if (!TCR_4(__kmp_init_parallel))
  235. __kmp_parallel_initialize();
  236. __kmp_resume_if_soft_paused();
  237. // If this is the first thread to enter, return NULL. The generated code will
  238. // then call GOMP_single_copy_end() for this thread only, with the
  239. // copyprivate data pointer as an argument.
  240. if (__kmp_enter_single(gtid, &loc, FALSE))
  241. return NULL;
  242. // Wait for the first thread to set the copyprivate data pointer,
  243. // and for all other threads to reach this point.
  244. #if OMPT_SUPPORT && OMPT_OPTIONAL
  245. ompt_frame_t *ompt_frame;
  246. if (ompt_enabled.enabled) {
  247. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  248. ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  249. }
  250. OMPT_STORE_RETURN_ADDRESS(gtid);
  251. #endif
  252. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  253. // Retrieve the value of the copyprivate data point, and wait for all
  254. // threads to do likewise, then return.
  255. retval = __kmp_team_from_gtid(gtid)->t.t_copypriv_data;
  256. {
  257. #if OMPT_SUPPORT && OMPT_OPTIONAL
  258. OMPT_STORE_RETURN_ADDRESS(gtid);
  259. #endif
  260. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  261. }
  262. #if OMPT_SUPPORT && OMPT_OPTIONAL
  263. if (ompt_enabled.enabled) {
  264. ompt_frame->enter_frame = ompt_data_none;
  265. }
  266. #endif
  267. return retval;
  268. }
  269. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SINGLE_COPY_END)(void *data) {
  270. int gtid = __kmp_get_gtid();
  271. KA_TRACE(20, ("GOMP_single_copy_end: T#%d\n", gtid));
  272. // Set the copyprivate data pointer fo the team, then hit the barrier so that
  273. // the other threads will continue on and read it. Hit another barrier before
  274. // continuing, so that the know that the copyprivate data pointer has been
  275. // propagated to all threads before trying to reuse the t_copypriv_data field.
  276. __kmp_team_from_gtid(gtid)->t.t_copypriv_data = data;
  277. #if OMPT_SUPPORT && OMPT_OPTIONAL
  278. ompt_frame_t *ompt_frame;
  279. if (ompt_enabled.enabled) {
  280. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  281. ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  282. }
  283. OMPT_STORE_RETURN_ADDRESS(gtid);
  284. #endif
  285. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  286. {
  287. #if OMPT_SUPPORT && OMPT_OPTIONAL
  288. OMPT_STORE_RETURN_ADDRESS(gtid);
  289. #endif
  290. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  291. }
  292. #if OMPT_SUPPORT && OMPT_OPTIONAL
  293. if (ompt_enabled.enabled) {
  294. ompt_frame->enter_frame = ompt_data_none;
  295. }
  296. #endif
  297. }
  298. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_START)(void) {
  299. int gtid = __kmp_entry_gtid();
  300. MKLOC(loc, "GOMP_ordered_start");
  301. KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
  302. #if OMPT_SUPPORT && OMPT_OPTIONAL
  303. OMPT_STORE_RETURN_ADDRESS(gtid);
  304. #endif
  305. __kmpc_ordered(&loc, gtid);
  306. }
  307. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_END)(void) {
  308. int gtid = __kmp_get_gtid();
  309. MKLOC(loc, "GOMP_ordered_end");
  310. KA_TRACE(20, ("GOMP_ordered_start: T#%d\n", gtid));
  311. #if OMPT_SUPPORT && OMPT_OPTIONAL
  312. OMPT_STORE_RETURN_ADDRESS(gtid);
  313. #endif
  314. __kmpc_end_ordered(&loc, gtid);
  315. }
  316. // Dispatch macro defs
  317. //
  318. // They come in two flavors: 64-bit unsigned, and either 32-bit signed
  319. // (IA-32 architecture) or 64-bit signed (Intel(R) 64).
  320. #if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
  321. #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4
  322. #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4
  323. #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4
  324. #else
  325. #define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_8
  326. #define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_8
  327. #define KMP_DISPATCH_NEXT __kmpc_dispatch_next_8
  328. #endif /* KMP_ARCH_X86 */
  329. #define KMP_DISPATCH_INIT_ULL __kmp_aux_dispatch_init_8u
  330. #define KMP_DISPATCH_FINI_CHUNK_ULL __kmp_aux_dispatch_fini_chunk_8u
  331. #define KMP_DISPATCH_NEXT_ULL __kmpc_dispatch_next_8u
  332. // The parallel construct
  333. #ifndef KMP_DEBUG
  334. static
  335. #endif /* KMP_DEBUG */
  336. void
  337. __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *),
  338. void *data) {
  339. #if OMPT_SUPPORT
  340. kmp_info_t *thr;
  341. ompt_frame_t *ompt_frame;
  342. ompt_state_t enclosing_state;
  343. if (ompt_enabled.enabled) {
  344. // get pointer to thread data structure
  345. thr = __kmp_threads[*gtid];
  346. // save enclosing task state; set current state for task
  347. enclosing_state = thr->th.ompt_thread_info.state;
  348. thr->th.ompt_thread_info.state = ompt_state_work_parallel;
  349. // set task frame
  350. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  351. ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  352. }
  353. #endif
  354. task(data);
  355. #if OMPT_SUPPORT
  356. if (ompt_enabled.enabled) {
  357. // clear task frame
  358. ompt_frame->exit_frame = ompt_data_none;
  359. // restore enclosing state
  360. thr->th.ompt_thread_info.state = enclosing_state;
  361. }
  362. #endif
  363. }
  364. #ifndef KMP_DEBUG
  365. static
  366. #endif /* KMP_DEBUG */
  367. void
  368. __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr,
  369. void (*task)(void *), void *data,
  370. unsigned num_threads, ident_t *loc,
  371. enum sched_type schedule, long start,
  372. long end, long incr,
  373. long chunk_size) {
  374. // Initialize the loop worksharing construct.
  375. KMP_DISPATCH_INIT(loc, *gtid, schedule, start, end, incr, chunk_size,
  376. schedule != kmp_sch_static);
  377. #if OMPT_SUPPORT
  378. kmp_info_t *thr;
  379. ompt_frame_t *ompt_frame;
  380. ompt_state_t enclosing_state;
  381. if (ompt_enabled.enabled) {
  382. thr = __kmp_threads[*gtid];
  383. // save enclosing task state; set current state for task
  384. enclosing_state = thr->th.ompt_thread_info.state;
  385. thr->th.ompt_thread_info.state = ompt_state_work_parallel;
  386. // set task frame
  387. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  388. ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  389. }
  390. #endif
  391. // Now invoke the microtask.
  392. task(data);
  393. #if OMPT_SUPPORT
  394. if (ompt_enabled.enabled) {
  395. // clear task frame
  396. ompt_frame->exit_frame = ompt_data_none;
  397. // reset enclosing state
  398. thr->th.ompt_thread_info.state = enclosing_state;
  399. }
  400. #endif
  401. }
  402. static void __kmp_GOMP_fork_call(ident_t *loc, int gtid, unsigned num_threads,
  403. unsigned flags, void (*unwrapped_task)(void *),
  404. microtask_t wrapper, int argc, ...) {
  405. int rc;
  406. kmp_info_t *thr = __kmp_threads[gtid];
  407. kmp_team_t *team = thr->th.th_team;
  408. int tid = __kmp_tid_from_gtid(gtid);
  409. va_list ap;
  410. va_start(ap, argc);
  411. if (num_threads != 0)
  412. __kmp_push_num_threads(loc, gtid, num_threads);
  413. if (flags != 0)
  414. __kmp_push_proc_bind(loc, gtid, (kmp_proc_bind_t)flags);
  415. rc = __kmp_fork_call(loc, gtid, fork_context_gnu, argc, wrapper,
  416. __kmp_invoke_task_func, kmp_va_addr_of(ap));
  417. va_end(ap);
  418. if (rc) {
  419. __kmp_run_before_invoked_task(gtid, tid, thr, team);
  420. }
  421. #if OMPT_SUPPORT
  422. int ompt_team_size;
  423. if (ompt_enabled.enabled) {
  424. ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL);
  425. ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
  426. // implicit task callback
  427. if (ompt_enabled.ompt_callback_implicit_task) {
  428. ompt_team_size = __kmp_team_from_gtid(gtid)->t.t_nproc;
  429. ompt_callbacks.ompt_callback(ompt_callback_implicit_task)(
  430. ompt_scope_begin, &(team_info->parallel_data),
  431. &(task_info->task_data), ompt_team_size, __kmp_tid_from_gtid(gtid),
  432. ompt_task_implicit); // TODO: Can this be ompt_task_initial?
  433. task_info->thread_num = __kmp_tid_from_gtid(gtid);
  434. }
  435. thr->th.ompt_thread_info.state = ompt_state_work_parallel;
  436. }
  437. #endif
  438. }
  439. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *),
  440. void *data,
  441. unsigned num_threads) {
  442. int gtid = __kmp_entry_gtid();
  443. #if OMPT_SUPPORT
  444. ompt_frame_t *parent_frame, *frame;
  445. if (ompt_enabled.enabled) {
  446. __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL);
  447. parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  448. }
  449. OMPT_STORE_RETURN_ADDRESS(gtid);
  450. #endif
  451. MKLOC(loc, "GOMP_parallel_start");
  452. KA_TRACE(20, ("GOMP_parallel_start: T#%d\n", gtid));
  453. __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task,
  454. (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task,
  455. data);
  456. #if OMPT_SUPPORT
  457. if (ompt_enabled.enabled) {
  458. __ompt_get_task_info_internal(0, NULL, NULL, &frame, NULL, NULL);
  459. frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  460. }
  461. #endif
  462. #if OMPD_SUPPORT
  463. if (ompd_state & OMPD_ENABLE_BP)
  464. ompd_bp_parallel_begin();
  465. #endif
  466. }
  467. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(void) {
  468. int gtid = __kmp_get_gtid();
  469. kmp_info_t *thr;
  470. thr = __kmp_threads[gtid];
  471. MKLOC(loc, "GOMP_parallel_end");
  472. KA_TRACE(20, ("GOMP_parallel_end: T#%d\n", gtid));
  473. if (!thr->th.th_team->t.t_serialized) {
  474. __kmp_run_after_invoked_task(gtid, __kmp_tid_from_gtid(gtid), thr,
  475. thr->th.th_team);
  476. }
  477. #if OMPT_SUPPORT
  478. if (ompt_enabled.enabled) {
  479. // Implicit task is finished here, in the barrier we might schedule
  480. // deferred tasks,
  481. // these don't see the implicit task on the stack
  482. OMPT_CUR_TASK_INFO(thr)->frame.exit_frame = ompt_data_none;
  483. }
  484. #endif
  485. __kmp_join_call(&loc, gtid
  486. #if OMPT_SUPPORT
  487. ,
  488. fork_context_gnu
  489. #endif
  490. );
  491. #if OMPD_SUPPORT
  492. if (ompd_state & OMPD_ENABLE_BP)
  493. ompd_bp_parallel_end();
  494. #endif
  495. }
  496. // Loop worksharing constructs
  497. // The Gnu codegen passes in an exclusive upper bound for the overall range,
  498. // but the libguide dispatch code expects an inclusive upper bound, hence the
  499. // "end - incr" 5th argument to KMP_DISPATCH_INIT (and the " ub - str" 11th
  500. // argument to __kmp_GOMP_fork_call).
  501. //
  502. // Conversely, KMP_DISPATCH_NEXT returns and inclusive upper bound in *p_ub,
  503. // but the Gnu codegen expects an exclusive upper bound, so the adjustment
  504. // "*p_ub += stride" compensates for the discrepancy.
  505. //
  506. // Correction: the gnu codegen always adjusts the upper bound by +-1, not the
  507. // stride value. We adjust the dispatch parameters accordingly (by +-1), but
  508. // we still adjust p_ub by the actual stride value.
  509. //
  510. // The "runtime" versions do not take a chunk_sz parameter.
  511. //
  512. // The profile lib cannot support construct checking of unordered loops that
  513. // are predetermined by the compiler to be statically scheduled, as the gcc
  514. // codegen will not always emit calls to GOMP_loop_static_next() to get the
  515. // next iteration. Instead, it emits inline code to call omp_get_thread_num()
  516. // num and calculate the iteration space using the result. It doesn't do this
  517. // with ordered static loop, so they can be checked.
  518. #if OMPT_SUPPORT
  519. #define IF_OMPT_SUPPORT(code) code
  520. #else
  521. #define IF_OMPT_SUPPORT(code)
  522. #endif
  523. #define LOOP_START(func, schedule) \
  524. int func(long lb, long ub, long str, long chunk_sz, long *p_lb, \
  525. long *p_ub) { \
  526. int status; \
  527. long stride; \
  528. int gtid = __kmp_entry_gtid(); \
  529. MKLOC(loc, KMP_STR(func)); \
  530. KA_TRACE( \
  531. 20, \
  532. (KMP_STR( \
  533. func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
  534. gtid, lb, ub, str, chunk_sz)); \
  535. \
  536. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  537. { \
  538. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  539. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  540. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  541. (schedule) != kmp_sch_static); \
  542. } \
  543. { \
  544. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  545. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
  546. (kmp_int *)p_ub, (kmp_int *)&stride); \
  547. } \
  548. if (status) { \
  549. KMP_DEBUG_ASSERT(stride == str); \
  550. *p_ub += (str > 0) ? 1 : -1; \
  551. } \
  552. } else { \
  553. status = 0; \
  554. } \
  555. \
  556. KA_TRACE( \
  557. 20, \
  558. (KMP_STR( \
  559. func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
  560. gtid, *p_lb, *p_ub, status)); \
  561. return status; \
  562. }
  563. #define LOOP_RUNTIME_START(func, schedule) \
  564. int func(long lb, long ub, long str, long *p_lb, long *p_ub) { \
  565. int status; \
  566. long stride; \
  567. long chunk_sz = 0; \
  568. int gtid = __kmp_entry_gtid(); \
  569. MKLOC(loc, KMP_STR(func)); \
  570. KA_TRACE( \
  571. 20, \
  572. (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \
  573. gtid, lb, ub, str, chunk_sz)); \
  574. \
  575. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  576. { \
  577. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  578. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  579. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  580. TRUE); \
  581. } \
  582. { \
  583. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  584. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
  585. (kmp_int *)p_ub, (kmp_int *)&stride); \
  586. } \
  587. if (status) { \
  588. KMP_DEBUG_ASSERT(stride == str); \
  589. *p_ub += (str > 0) ? 1 : -1; \
  590. } \
  591. } else { \
  592. status = 0; \
  593. } \
  594. \
  595. KA_TRACE( \
  596. 20, \
  597. (KMP_STR( \
  598. func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
  599. gtid, *p_lb, *p_ub, status)); \
  600. return status; \
  601. }
  602. #define KMP_DOACROSS_FINI(status, gtid) \
  603. if (!status && __kmp_threads[gtid]->th.th_dispatch->th_doacross_flags) { \
  604. __kmpc_doacross_fini(NULL, gtid); \
  605. }
  606. #define LOOP_NEXT(func, fini_code) \
  607. int func(long *p_lb, long *p_ub) { \
  608. int status; \
  609. long stride; \
  610. int gtid = __kmp_get_gtid(); \
  611. MKLOC(loc, KMP_STR(func)); \
  612. KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid)); \
  613. \
  614. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  615. fini_code status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
  616. (kmp_int *)p_ub, (kmp_int *)&stride); \
  617. if (status) { \
  618. *p_ub += (stride > 0) ? 1 : -1; \
  619. } \
  620. KMP_DOACROSS_FINI(status, gtid) \
  621. \
  622. KA_TRACE( \
  623. 20, \
  624. (KMP_STR(func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, stride 0x%lx, " \
  625. "returning %d\n", \
  626. gtid, *p_lb, *p_ub, stride, status)); \
  627. return status; \
  628. }
  629. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START), kmp_sch_static)
  630. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT), {})
  631. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START),
  632. kmp_sch_dynamic_chunked)
  633. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START),
  634. kmp_sch_dynamic_chunked)
  635. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT), {})
  636. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT), {})
  637. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START),
  638. kmp_sch_guided_chunked)
  639. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START),
  640. kmp_sch_guided_chunked)
  641. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT), {})
  642. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT), {})
  643. LOOP_RUNTIME_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START),
  644. kmp_sch_runtime)
  645. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT), {})
  646. LOOP_RUNTIME_START(
  647. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START),
  648. kmp_sch_runtime)
  649. LOOP_RUNTIME_START(
  650. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START),
  651. kmp_sch_runtime)
  652. LOOP_NEXT(
  653. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT), {})
  654. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT), {})
  655. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START),
  656. kmp_ord_static)
  657. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT),
  658. { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
  659. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START),
  660. kmp_ord_dynamic_chunked)
  661. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT),
  662. { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
  663. LOOP_START(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START),
  664. kmp_ord_guided_chunked)
  665. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT),
  666. { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
  667. LOOP_RUNTIME_START(
  668. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START),
  669. kmp_ord_runtime)
  670. LOOP_NEXT(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT),
  671. { KMP_DISPATCH_FINI_CHUNK(&loc, gtid); })
  672. #define LOOP_DOACROSS_START(func, schedule) \
  673. bool func(unsigned ncounts, long *counts, long chunk_sz, long *p_lb, \
  674. long *p_ub) { \
  675. int status; \
  676. long stride, lb, ub, str; \
  677. int gtid = __kmp_entry_gtid(); \
  678. struct kmp_dim *dims = \
  679. (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \
  680. MKLOC(loc, KMP_STR(func)); \
  681. for (unsigned i = 0; i < ncounts; ++i) { \
  682. dims[i].lo = 0; \
  683. dims[i].up = counts[i] - 1; \
  684. dims[i].st = 1; \
  685. } \
  686. __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \
  687. lb = 0; \
  688. ub = counts[0]; \
  689. str = 1; \
  690. KA_TRACE(20, (KMP_STR(func) ": T#%d, ncounts %u, lb 0x%lx, ub 0x%lx, str " \
  691. "0x%lx, chunk_sz " \
  692. "0x%lx\n", \
  693. gtid, ncounts, lb, ub, str, chunk_sz)); \
  694. \
  695. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  696. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  697. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  698. (schedule) != kmp_sch_static); \
  699. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
  700. (kmp_int *)p_ub, (kmp_int *)&stride); \
  701. if (status) { \
  702. KMP_DEBUG_ASSERT(stride == str); \
  703. *p_ub += (str > 0) ? 1 : -1; \
  704. } \
  705. } else { \
  706. status = 0; \
  707. } \
  708. KMP_DOACROSS_FINI(status, gtid); \
  709. \
  710. KA_TRACE( \
  711. 20, \
  712. (KMP_STR( \
  713. func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
  714. gtid, *p_lb, *p_ub, status)); \
  715. __kmp_free(dims); \
  716. return status; \
  717. }
  718. #define LOOP_DOACROSS_RUNTIME_START(func, schedule) \
  719. int func(unsigned ncounts, long *counts, long *p_lb, long *p_ub) { \
  720. int status; \
  721. long stride, lb, ub, str; \
  722. long chunk_sz = 0; \
  723. int gtid = __kmp_entry_gtid(); \
  724. struct kmp_dim *dims = \
  725. (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \
  726. MKLOC(loc, KMP_STR(func)); \
  727. for (unsigned i = 0; i < ncounts; ++i) { \
  728. dims[i].lo = 0; \
  729. dims[i].up = counts[i] - 1; \
  730. dims[i].st = 1; \
  731. } \
  732. __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \
  733. lb = 0; \
  734. ub = counts[0]; \
  735. str = 1; \
  736. KA_TRACE( \
  737. 20, \
  738. (KMP_STR(func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz %d\n", \
  739. gtid, lb, ub, str, chunk_sz)); \
  740. \
  741. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  742. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  743. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, TRUE); \
  744. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, (kmp_int *)p_lb, \
  745. (kmp_int *)p_ub, (kmp_int *)&stride); \
  746. if (status) { \
  747. KMP_DEBUG_ASSERT(stride == str); \
  748. *p_ub += (str > 0) ? 1 : -1; \
  749. } \
  750. } else { \
  751. status = 0; \
  752. } \
  753. KMP_DOACROSS_FINI(status, gtid); \
  754. \
  755. KA_TRACE( \
  756. 20, \
  757. (KMP_STR( \
  758. func) " exit: T#%d, *p_lb 0x%lx, *p_ub 0x%lx, returning %d\n", \
  759. gtid, *p_lb, *p_ub, status)); \
  760. __kmp_free(dims); \
  761. return status; \
  762. }
  763. LOOP_DOACROSS_START(
  764. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START),
  765. kmp_sch_static)
  766. LOOP_DOACROSS_START(
  767. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START),
  768. kmp_sch_dynamic_chunked)
  769. LOOP_DOACROSS_START(
  770. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START),
  771. kmp_sch_guided_chunked)
  772. LOOP_DOACROSS_RUNTIME_START(
  773. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START),
  774. kmp_sch_runtime)
  775. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END)(void) {
  776. int gtid = __kmp_get_gtid();
  777. KA_TRACE(20, ("GOMP_loop_end: T#%d\n", gtid))
  778. #if OMPT_SUPPORT && OMPT_OPTIONAL
  779. ompt_frame_t *ompt_frame;
  780. if (ompt_enabled.enabled) {
  781. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  782. ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  783. OMPT_STORE_RETURN_ADDRESS(gtid);
  784. }
  785. #endif
  786. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  787. #if OMPT_SUPPORT && OMPT_OPTIONAL
  788. if (ompt_enabled.enabled) {
  789. ompt_frame->enter_frame = ompt_data_none;
  790. }
  791. #endif
  792. KA_TRACE(20, ("GOMP_loop_end exit: T#%d\n", gtid))
  793. }
  794. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_NOWAIT)(void) {
  795. KA_TRACE(20, ("GOMP_loop_end_nowait: T#%d\n", __kmp_get_gtid()))
  796. }
  797. // Unsigned long long loop worksharing constructs
  798. //
  799. // These are new with gcc 4.4
  800. #define LOOP_START_ULL(func, schedule) \
  801. int func(int up, unsigned long long lb, unsigned long long ub, \
  802. unsigned long long str, unsigned long long chunk_sz, \
  803. unsigned long long *p_lb, unsigned long long *p_ub) { \
  804. int status; \
  805. long long str2 = up ? ((long long)str) : -((long long)str); \
  806. long long stride; \
  807. int gtid = __kmp_entry_gtid(); \
  808. MKLOC(loc, KMP_STR(func)); \
  809. \
  810. KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str " \
  811. "0x%llx, chunk_sz 0x%llx\n", \
  812. gtid, up, lb, ub, str, chunk_sz)); \
  813. \
  814. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  815. KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
  816. (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \
  817. (schedule) != kmp_sch_static); \
  818. status = \
  819. KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
  820. (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
  821. if (status) { \
  822. KMP_DEBUG_ASSERT(stride == str2); \
  823. *p_ub += (str > 0) ? 1 : -1; \
  824. } \
  825. } else { \
  826. status = 0; \
  827. } \
  828. \
  829. KA_TRACE( \
  830. 20, \
  831. (KMP_STR( \
  832. func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
  833. gtid, *p_lb, *p_ub, status)); \
  834. return status; \
  835. }
  836. #define LOOP_RUNTIME_START_ULL(func, schedule) \
  837. int func(int up, unsigned long long lb, unsigned long long ub, \
  838. unsigned long long str, unsigned long long *p_lb, \
  839. unsigned long long *p_ub) { \
  840. int status; \
  841. long long str2 = up ? ((long long)str) : -((long long)str); \
  842. unsigned long long stride; \
  843. unsigned long long chunk_sz = 0; \
  844. int gtid = __kmp_entry_gtid(); \
  845. MKLOC(loc, KMP_STR(func)); \
  846. \
  847. KA_TRACE(20, (KMP_STR(func) ": T#%d, up %d, lb 0x%llx, ub 0x%llx, str " \
  848. "0x%llx, chunk_sz 0x%llx\n", \
  849. gtid, up, lb, ub, str, chunk_sz)); \
  850. \
  851. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  852. KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
  853. (str2 > 0) ? (ub - 1) : (ub + 1), str2, chunk_sz, \
  854. TRUE); \
  855. status = \
  856. KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
  857. (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
  858. if (status) { \
  859. KMP_DEBUG_ASSERT((long long)stride == str2); \
  860. *p_ub += (str > 0) ? 1 : -1; \
  861. } \
  862. } else { \
  863. status = 0; \
  864. } \
  865. \
  866. KA_TRACE( \
  867. 20, \
  868. (KMP_STR( \
  869. func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
  870. gtid, *p_lb, *p_ub, status)); \
  871. return status; \
  872. }
  873. #define LOOP_NEXT_ULL(func, fini_code) \
  874. int func(unsigned long long *p_lb, unsigned long long *p_ub) { \
  875. int status; \
  876. long long stride; \
  877. int gtid = __kmp_get_gtid(); \
  878. MKLOC(loc, KMP_STR(func)); \
  879. KA_TRACE(20, (KMP_STR(func) ": T#%d\n", gtid)); \
  880. \
  881. fini_code status = \
  882. KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
  883. (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
  884. if (status) { \
  885. *p_ub += (stride > 0) ? 1 : -1; \
  886. } \
  887. \
  888. KA_TRACE( \
  889. 20, \
  890. (KMP_STR( \
  891. func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, stride 0x%llx, " \
  892. "returning %d\n", \
  893. gtid, *p_lb, *p_ub, stride, status)); \
  894. return status; \
  895. }
  896. LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START),
  897. kmp_sch_static)
  898. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT), {})
  899. LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START),
  900. kmp_sch_dynamic_chunked)
  901. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT), {})
  902. LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START),
  903. kmp_sch_guided_chunked)
  904. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT), {})
  905. LOOP_START_ULL(
  906. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START),
  907. kmp_sch_dynamic_chunked)
  908. LOOP_NEXT_ULL(
  909. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT), {})
  910. LOOP_START_ULL(
  911. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START),
  912. kmp_sch_guided_chunked)
  913. LOOP_NEXT_ULL(
  914. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT), {})
  915. LOOP_RUNTIME_START_ULL(
  916. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START), kmp_sch_runtime)
  917. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT), {})
  918. LOOP_RUNTIME_START_ULL(
  919. KMP_EXPAND_NAME(
  920. KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START),
  921. kmp_sch_runtime)
  922. LOOP_RUNTIME_START_ULL(
  923. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START),
  924. kmp_sch_runtime)
  925. LOOP_NEXT_ULL(
  926. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT),
  927. {})
  928. LOOP_NEXT_ULL(
  929. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT), {})
  930. LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START),
  931. kmp_ord_static)
  932. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT),
  933. { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
  934. LOOP_START_ULL(
  935. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START),
  936. kmp_ord_dynamic_chunked)
  937. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT),
  938. { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
  939. LOOP_START_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START),
  940. kmp_ord_guided_chunked)
  941. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT),
  942. { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
  943. LOOP_RUNTIME_START_ULL(
  944. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START),
  945. kmp_ord_runtime)
  946. LOOP_NEXT_ULL(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT),
  947. { KMP_DISPATCH_FINI_CHUNK_ULL(&loc, gtid); })
  948. #define LOOP_DOACROSS_START_ULL(func, schedule) \
  949. int func(unsigned ncounts, unsigned long long *counts, \
  950. unsigned long long chunk_sz, unsigned long long *p_lb, \
  951. unsigned long long *p_ub) { \
  952. int status; \
  953. long long stride, str, lb, ub; \
  954. int gtid = __kmp_entry_gtid(); \
  955. struct kmp_dim *dims = \
  956. (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \
  957. MKLOC(loc, KMP_STR(func)); \
  958. for (unsigned i = 0; i < ncounts; ++i) { \
  959. dims[i].lo = 0; \
  960. dims[i].up = counts[i] - 1; \
  961. dims[i].st = 1; \
  962. } \
  963. __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \
  964. lb = 0; \
  965. ub = counts[0]; \
  966. str = 1; \
  967. \
  968. KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str " \
  969. "0x%llx, chunk_sz 0x%llx\n", \
  970. gtid, lb, ub, str, chunk_sz)); \
  971. \
  972. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  973. KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
  974. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  975. (schedule) != kmp_sch_static); \
  976. status = \
  977. KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
  978. (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
  979. if (status) { \
  980. KMP_DEBUG_ASSERT(stride == str); \
  981. *p_ub += (str > 0) ? 1 : -1; \
  982. } \
  983. } else { \
  984. status = 0; \
  985. } \
  986. KMP_DOACROSS_FINI(status, gtid); \
  987. \
  988. KA_TRACE( \
  989. 20, \
  990. (KMP_STR( \
  991. func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
  992. gtid, *p_lb, *p_ub, status)); \
  993. __kmp_free(dims); \
  994. return status; \
  995. }
  996. #define LOOP_DOACROSS_RUNTIME_START_ULL(func, schedule) \
  997. int func(unsigned ncounts, unsigned long long *counts, \
  998. unsigned long long *p_lb, unsigned long long *p_ub) { \
  999. int status; \
  1000. unsigned long long stride, str, lb, ub; \
  1001. unsigned long long chunk_sz = 0; \
  1002. int gtid = __kmp_entry_gtid(); \
  1003. struct kmp_dim *dims = \
  1004. (struct kmp_dim *)__kmp_allocate(sizeof(struct kmp_dim) * ncounts); \
  1005. MKLOC(loc, KMP_STR(func)); \
  1006. for (unsigned i = 0; i < ncounts; ++i) { \
  1007. dims[i].lo = 0; \
  1008. dims[i].up = counts[i] - 1; \
  1009. dims[i].st = 1; \
  1010. } \
  1011. __kmpc_doacross_init(&loc, gtid, (int)ncounts, dims); \
  1012. lb = 0; \
  1013. ub = counts[0]; \
  1014. str = 1; \
  1015. KA_TRACE(20, (KMP_STR(func) ": T#%d, lb 0x%llx, ub 0x%llx, str " \
  1016. "0x%llx, chunk_sz 0x%llx\n", \
  1017. gtid, lb, ub, str, chunk_sz)); \
  1018. \
  1019. if ((str > 0) ? (lb < ub) : (lb > ub)) { \
  1020. KMP_DISPATCH_INIT_ULL(&loc, gtid, (schedule), lb, \
  1021. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  1022. TRUE); \
  1023. status = \
  1024. KMP_DISPATCH_NEXT_ULL(&loc, gtid, NULL, (kmp_uint64 *)p_lb, \
  1025. (kmp_uint64 *)p_ub, (kmp_int64 *)&stride); \
  1026. if (status) { \
  1027. KMP_DEBUG_ASSERT(stride == str); \
  1028. *p_ub += (str > 0) ? 1 : -1; \
  1029. } \
  1030. } else { \
  1031. status = 0; \
  1032. } \
  1033. KMP_DOACROSS_FINI(status, gtid); \
  1034. \
  1035. KA_TRACE( \
  1036. 20, \
  1037. (KMP_STR( \
  1038. func) " exit: T#%d, *p_lb 0x%llx, *p_ub 0x%llx, returning %d\n", \
  1039. gtid, *p_lb, *p_ub, status)); \
  1040. __kmp_free(dims); \
  1041. return status; \
  1042. }
  1043. LOOP_DOACROSS_START_ULL(
  1044. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START),
  1045. kmp_sch_static)
  1046. LOOP_DOACROSS_START_ULL(
  1047. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START),
  1048. kmp_sch_dynamic_chunked)
  1049. LOOP_DOACROSS_START_ULL(
  1050. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START),
  1051. kmp_sch_guided_chunked)
  1052. LOOP_DOACROSS_RUNTIME_START_ULL(
  1053. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START),
  1054. kmp_sch_runtime)
  1055. // Combined parallel / loop worksharing constructs
  1056. //
  1057. // There are no ull versions (yet).
  1058. #define PARALLEL_LOOP_START(func, schedule, ompt_pre, ompt_post) \
  1059. void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \
  1060. long ub, long str, long chunk_sz) { \
  1061. int gtid = __kmp_entry_gtid(); \
  1062. MKLOC(loc, KMP_STR(func)); \
  1063. KA_TRACE( \
  1064. 20, \
  1065. (KMP_STR( \
  1066. func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
  1067. gtid, lb, ub, str, chunk_sz)); \
  1068. \
  1069. ompt_pre(); \
  1070. \
  1071. __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task, \
  1072. (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \
  1073. 9, task, data, num_threads, &loc, (schedule), lb, \
  1074. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \
  1075. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid)); \
  1076. \
  1077. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  1078. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  1079. (schedule) != kmp_sch_static); \
  1080. \
  1081. ompt_post(); \
  1082. \
  1083. KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid)); \
  1084. }
  1085. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1086. #define OMPT_LOOP_PRE() \
  1087. ompt_frame_t *parent_frame; \
  1088. if (ompt_enabled.enabled) { \
  1089. __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL); \
  1090. parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0); \
  1091. OMPT_STORE_RETURN_ADDRESS(gtid); \
  1092. }
  1093. #define OMPT_LOOP_POST() \
  1094. if (ompt_enabled.enabled) { \
  1095. parent_frame->enter_frame = ompt_data_none; \
  1096. }
  1097. #else
  1098. #define OMPT_LOOP_PRE()
  1099. #define OMPT_LOOP_POST()
  1100. #endif
  1101. PARALLEL_LOOP_START(
  1102. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START),
  1103. kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1104. PARALLEL_LOOP_START(
  1105. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START),
  1106. kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1107. PARALLEL_LOOP_START(
  1108. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START),
  1109. kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1110. PARALLEL_LOOP_START(
  1111. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START),
  1112. kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1113. // Tasking constructs
  1114. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data,
  1115. void (*copy_func)(void *, void *),
  1116. long arg_size, long arg_align,
  1117. bool if_cond, unsigned gomp_flags,
  1118. void **depend) {
  1119. MKLOC(loc, "GOMP_task");
  1120. int gtid = __kmp_entry_gtid();
  1121. kmp_int32 flags = 0;
  1122. kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
  1123. KA_TRACE(20, ("GOMP_task: T#%d\n", gtid));
  1124. // The low-order bit is the "untied" flag
  1125. if (!(gomp_flags & KMP_GOMP_TASK_UNTIED_FLAG)) {
  1126. input_flags->tiedness = TASK_TIED;
  1127. }
  1128. // The second low-order bit is the "final" flag
  1129. if (gomp_flags & KMP_GOMP_TASK_FINAL_FLAG) {
  1130. input_flags->final = 1;
  1131. }
  1132. input_flags->native = 1;
  1133. // __kmp_task_alloc() sets up all other flags
  1134. if (!if_cond) {
  1135. arg_size = 0;
  1136. }
  1137. kmp_task_t *task = __kmp_task_alloc(
  1138. &loc, gtid, input_flags, sizeof(kmp_task_t),
  1139. arg_size ? arg_size + arg_align - 1 : 0, (kmp_routine_entry_t)func);
  1140. if (arg_size > 0) {
  1141. if (arg_align > 0) {
  1142. task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) /
  1143. arg_align * arg_align);
  1144. }
  1145. // else error??
  1146. if (copy_func) {
  1147. (*copy_func)(task->shareds, data);
  1148. } else {
  1149. KMP_MEMCPY(task->shareds, data, arg_size);
  1150. }
  1151. }
  1152. #if OMPT_SUPPORT
  1153. kmp_taskdata_t *current_task;
  1154. if (ompt_enabled.enabled) {
  1155. current_task = __kmp_threads[gtid]->th.th_current_task;
  1156. current_task->ompt_task_info.frame.enter_frame.ptr =
  1157. OMPT_GET_FRAME_ADDRESS(0);
  1158. }
  1159. OMPT_STORE_RETURN_ADDRESS(gtid);
  1160. #endif
  1161. if (if_cond) {
  1162. if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) {
  1163. KMP_ASSERT(depend);
  1164. kmp_gomp_depends_info_t gomp_depends(depend);
  1165. kmp_int32 ndeps = gomp_depends.get_num_deps();
  1166. kmp_depend_info_t dep_list[ndeps];
  1167. for (kmp_int32 i = 0; i < ndeps; i++)
  1168. dep_list[i] = gomp_depends.get_kmp_depend(i);
  1169. kmp_int32 ndeps_cnv;
  1170. __kmp_type_convert(ndeps, &ndeps_cnv);
  1171. __kmpc_omp_task_with_deps(&loc, gtid, task, ndeps_cnv, dep_list, 0, NULL);
  1172. } else {
  1173. __kmpc_omp_task(&loc, gtid, task);
  1174. }
  1175. } else {
  1176. #if OMPT_SUPPORT
  1177. ompt_thread_info_t oldInfo;
  1178. kmp_info_t *thread;
  1179. kmp_taskdata_t *taskdata;
  1180. if (ompt_enabled.enabled) {
  1181. // Store the threads states and restore them after the task
  1182. thread = __kmp_threads[gtid];
  1183. taskdata = KMP_TASK_TO_TASKDATA(task);
  1184. oldInfo = thread->th.ompt_thread_info;
  1185. thread->th.ompt_thread_info.wait_id = 0;
  1186. thread->th.ompt_thread_info.state = ompt_state_work_parallel;
  1187. taskdata->ompt_task_info.frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1188. }
  1189. OMPT_STORE_RETURN_ADDRESS(gtid);
  1190. #endif
  1191. if (gomp_flags & KMP_GOMP_TASK_DEPENDS_FLAG) {
  1192. KMP_ASSERT(depend);
  1193. kmp_gomp_depends_info_t gomp_depends(depend);
  1194. kmp_int32 ndeps = gomp_depends.get_num_deps();
  1195. kmp_depend_info_t dep_list[ndeps];
  1196. for (kmp_int32 i = 0; i < ndeps; i++)
  1197. dep_list[i] = gomp_depends.get_kmp_depend(i);
  1198. __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL);
  1199. }
  1200. __kmpc_omp_task_begin_if0(&loc, gtid, task);
  1201. func(data);
  1202. __kmpc_omp_task_complete_if0(&loc, gtid, task);
  1203. #if OMPT_SUPPORT
  1204. if (ompt_enabled.enabled) {
  1205. thread->th.ompt_thread_info = oldInfo;
  1206. taskdata->ompt_task_info.frame.exit_frame = ompt_data_none;
  1207. }
  1208. #endif
  1209. }
  1210. #if OMPT_SUPPORT
  1211. if (ompt_enabled.enabled) {
  1212. current_task->ompt_task_info.frame.enter_frame = ompt_data_none;
  1213. }
  1214. #endif
  1215. KA_TRACE(20, ("GOMP_task exit: T#%d\n", gtid));
  1216. }
  1217. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT)(void) {
  1218. MKLOC(loc, "GOMP_taskwait");
  1219. int gtid = __kmp_entry_gtid();
  1220. #if OMPT_SUPPORT
  1221. OMPT_STORE_RETURN_ADDRESS(gtid);
  1222. #endif
  1223. KA_TRACE(20, ("GOMP_taskwait: T#%d\n", gtid));
  1224. __kmpc_omp_taskwait(&loc, gtid);
  1225. KA_TRACE(20, ("GOMP_taskwait exit: T#%d\n", gtid));
  1226. }
  1227. // Sections worksharing constructs
  1228. //
  1229. // For the sections construct, we initialize a dynamically scheduled loop
  1230. // worksharing construct with lb 1 and stride 1, and use the iteration #'s
  1231. // that its returns as sections ids.
  1232. //
  1233. // There are no special entry points for ordered sections, so we always use
  1234. // the dynamically scheduled workshare, even if the sections aren't ordered.
  1235. unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(unsigned count) {
  1236. int status;
  1237. kmp_int lb, ub, stride;
  1238. int gtid = __kmp_entry_gtid();
  1239. MKLOC(loc, "GOMP_sections_start");
  1240. KA_TRACE(20, ("GOMP_sections_start: T#%d\n", gtid));
  1241. KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
  1242. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
  1243. if (status) {
  1244. KMP_DEBUG_ASSERT(stride == 1);
  1245. KMP_DEBUG_ASSERT(lb > 0);
  1246. KMP_ASSERT(lb == ub);
  1247. } else {
  1248. lb = 0;
  1249. }
  1250. KA_TRACE(20, ("GOMP_sections_start exit: T#%d returning %u\n", gtid,
  1251. (unsigned)lb));
  1252. return (unsigned)lb;
  1253. }
  1254. unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_NEXT)(void) {
  1255. int status;
  1256. kmp_int lb, ub, stride;
  1257. int gtid = __kmp_get_gtid();
  1258. MKLOC(loc, "GOMP_sections_next");
  1259. KA_TRACE(20, ("GOMP_sections_next: T#%d\n", gtid));
  1260. #if OMPT_SUPPORT
  1261. OMPT_STORE_RETURN_ADDRESS(gtid);
  1262. #endif
  1263. status = KMP_DISPATCH_NEXT(&loc, gtid, NULL, &lb, &ub, &stride);
  1264. if (status) {
  1265. KMP_DEBUG_ASSERT(stride == 1);
  1266. KMP_DEBUG_ASSERT(lb > 0);
  1267. KMP_ASSERT(lb == ub);
  1268. } else {
  1269. lb = 0;
  1270. }
  1271. KA_TRACE(
  1272. 20, ("GOMP_sections_next exit: T#%d returning %u\n", gtid, (unsigned)lb));
  1273. return (unsigned)lb;
  1274. }
  1275. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(
  1276. void (*task)(void *), void *data, unsigned num_threads, unsigned count) {
  1277. int gtid = __kmp_entry_gtid();
  1278. #if OMPT_SUPPORT
  1279. ompt_frame_t *parent_frame;
  1280. if (ompt_enabled.enabled) {
  1281. __ompt_get_task_info_internal(0, NULL, NULL, &parent_frame, NULL, NULL);
  1282. parent_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1283. }
  1284. OMPT_STORE_RETURN_ADDRESS(gtid);
  1285. #endif
  1286. MKLOC(loc, "GOMP_parallel_sections_start");
  1287. KA_TRACE(20, ("GOMP_parallel_sections_start: T#%d\n", gtid));
  1288. __kmp_GOMP_fork_call(&loc, gtid, num_threads, 0u, task,
  1289. (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9,
  1290. task, data, num_threads, &loc, kmp_nm_dynamic_chunked,
  1291. (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1);
  1292. #if OMPT_SUPPORT
  1293. if (ompt_enabled.enabled) {
  1294. parent_frame->enter_frame = ompt_data_none;
  1295. }
  1296. #endif
  1297. KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
  1298. KA_TRACE(20, ("GOMP_parallel_sections_start exit: T#%d\n", gtid));
  1299. }
  1300. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END)(void) {
  1301. int gtid = __kmp_get_gtid();
  1302. KA_TRACE(20, ("GOMP_sections_end: T#%d\n", gtid))
  1303. #if OMPT_SUPPORT
  1304. ompt_frame_t *ompt_frame;
  1305. if (ompt_enabled.enabled) {
  1306. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  1307. ompt_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1308. }
  1309. OMPT_STORE_RETURN_ADDRESS(gtid);
  1310. #endif
  1311. __kmp_barrier(bs_plain_barrier, gtid, FALSE, 0, NULL, NULL);
  1312. #if OMPT_SUPPORT
  1313. if (ompt_enabled.enabled) {
  1314. ompt_frame->enter_frame = ompt_data_none;
  1315. }
  1316. #endif
  1317. KA_TRACE(20, ("GOMP_sections_end exit: T#%d\n", gtid))
  1318. }
  1319. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT)(void) {
  1320. KA_TRACE(20, ("GOMP_sections_end_nowait: T#%d\n", __kmp_get_gtid()))
  1321. }
  1322. // libgomp has an empty function for GOMP_taskyield as of 2013-10-10
  1323. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKYIELD)(void) {
  1324. KA_TRACE(20, ("GOMP_taskyield: T#%d\n", __kmp_get_gtid()))
  1325. return;
  1326. }
  1327. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL)(void (*task)(void *),
  1328. void *data,
  1329. unsigned num_threads,
  1330. unsigned int flags) {
  1331. int gtid = __kmp_entry_gtid();
  1332. MKLOC(loc, "GOMP_parallel");
  1333. KA_TRACE(20, ("GOMP_parallel: T#%d\n", gtid));
  1334. #if OMPT_SUPPORT
  1335. ompt_task_info_t *parent_task_info, *task_info;
  1336. if (ompt_enabled.enabled) {
  1337. parent_task_info = __ompt_get_task_info_object(0);
  1338. parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1339. }
  1340. OMPT_STORE_RETURN_ADDRESS(gtid);
  1341. #endif
  1342. __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
  1343. (microtask_t)__kmp_GOMP_microtask_wrapper, 2, task,
  1344. data);
  1345. #if OMPT_SUPPORT
  1346. if (ompt_enabled.enabled) {
  1347. task_info = __ompt_get_task_info_object(0);
  1348. task_info->frame.exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1349. }
  1350. #endif
  1351. task(data);
  1352. {
  1353. #if OMPT_SUPPORT
  1354. OMPT_STORE_RETURN_ADDRESS(gtid);
  1355. #endif
  1356. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
  1357. }
  1358. #if OMPT_SUPPORT
  1359. if (ompt_enabled.enabled) {
  1360. task_info->frame.exit_frame = ompt_data_none;
  1361. parent_task_info->frame.enter_frame = ompt_data_none;
  1362. }
  1363. #endif
  1364. }
  1365. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_SECTIONS)(void (*task)(void *),
  1366. void *data,
  1367. unsigned num_threads,
  1368. unsigned count,
  1369. unsigned flags) {
  1370. int gtid = __kmp_entry_gtid();
  1371. MKLOC(loc, "GOMP_parallel_sections");
  1372. KA_TRACE(20, ("GOMP_parallel_sections: T#%d\n", gtid));
  1373. #if OMPT_SUPPORT
  1374. ompt_frame_t *task_frame;
  1375. kmp_info_t *thr;
  1376. if (ompt_enabled.enabled) {
  1377. thr = __kmp_threads[gtid];
  1378. task_frame = &(thr->th.th_current_task->ompt_task_info.frame);
  1379. task_frame->enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1380. }
  1381. OMPT_STORE_RETURN_ADDRESS(gtid);
  1382. #endif
  1383. __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
  1384. (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, 9,
  1385. task, data, num_threads, &loc, kmp_nm_dynamic_chunked,
  1386. (kmp_int)1, (kmp_int)count, (kmp_int)1, (kmp_int)1);
  1387. {
  1388. #if OMPT_SUPPORT
  1389. OMPT_STORE_RETURN_ADDRESS(gtid);
  1390. #endif
  1391. KMP_DISPATCH_INIT(&loc, gtid, kmp_nm_dynamic_chunked, 1, count, 1, 1, TRUE);
  1392. }
  1393. #if OMPT_SUPPORT
  1394. ompt_frame_t *child_frame;
  1395. if (ompt_enabled.enabled) {
  1396. child_frame = &(thr->th.th_current_task->ompt_task_info.frame);
  1397. child_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1398. }
  1399. #endif
  1400. task(data);
  1401. #if OMPT_SUPPORT
  1402. if (ompt_enabled.enabled) {
  1403. child_frame->exit_frame = ompt_data_none;
  1404. }
  1405. #endif
  1406. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
  1407. KA_TRACE(20, ("GOMP_parallel_sections exit: T#%d\n", gtid));
  1408. #if OMPT_SUPPORT
  1409. if (ompt_enabled.enabled) {
  1410. task_frame->enter_frame = ompt_data_none;
  1411. }
  1412. #endif
  1413. }
  1414. #define PARALLEL_LOOP(func, schedule, ompt_pre, ompt_post) \
  1415. void func(void (*task)(void *), void *data, unsigned num_threads, long lb, \
  1416. long ub, long str, long chunk_sz, unsigned flags) { \
  1417. int gtid = __kmp_entry_gtid(); \
  1418. MKLOC(loc, KMP_STR(func)); \
  1419. KA_TRACE( \
  1420. 20, \
  1421. (KMP_STR( \
  1422. func) ": T#%d, lb 0x%lx, ub 0x%lx, str 0x%lx, chunk_sz 0x%lx\n", \
  1423. gtid, lb, ub, str, chunk_sz)); \
  1424. \
  1425. ompt_pre(); \
  1426. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  1427. __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task, \
  1428. (microtask_t)__kmp_GOMP_parallel_microtask_wrapper, \
  1429. 9, task, data, num_threads, &loc, (schedule), lb, \
  1430. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz); \
  1431. \
  1432. { \
  1433. IF_OMPT_SUPPORT(OMPT_STORE_RETURN_ADDRESS(gtid);) \
  1434. KMP_DISPATCH_INIT(&loc, gtid, (schedule), lb, \
  1435. (str > 0) ? (ub - 1) : (ub + 1), str, chunk_sz, \
  1436. (schedule) != kmp_sch_static); \
  1437. } \
  1438. task(data); \
  1439. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)(); \
  1440. ompt_post(); \
  1441. \
  1442. KA_TRACE(20, (KMP_STR(func) " exit: T#%d\n", gtid)); \
  1443. }
  1444. PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC),
  1445. kmp_sch_static, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1446. PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC),
  1447. kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1448. PARALLEL_LOOP(
  1449. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED),
  1450. kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1451. PARALLEL_LOOP(
  1452. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC),
  1453. kmp_sch_dynamic_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1454. PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED),
  1455. kmp_sch_guided_chunked, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1456. PARALLEL_LOOP(KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME),
  1457. kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1458. PARALLEL_LOOP(
  1459. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME),
  1460. kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1461. PARALLEL_LOOP(
  1462. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME),
  1463. kmp_sch_runtime, OMPT_LOOP_PRE, OMPT_LOOP_POST)
  1464. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_START)(void) {
  1465. int gtid = __kmp_entry_gtid();
  1466. MKLOC(loc, "GOMP_taskgroup_start");
  1467. KA_TRACE(20, ("GOMP_taskgroup_start: T#%d\n", gtid));
  1468. #if OMPT_SUPPORT
  1469. OMPT_STORE_RETURN_ADDRESS(gtid);
  1470. #endif
  1471. __kmpc_taskgroup(&loc, gtid);
  1472. return;
  1473. }
  1474. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_END)(void) {
  1475. int gtid = __kmp_get_gtid();
  1476. MKLOC(loc, "GOMP_taskgroup_end");
  1477. KA_TRACE(20, ("GOMP_taskgroup_end: T#%d\n", gtid));
  1478. #if OMPT_SUPPORT
  1479. OMPT_STORE_RETURN_ADDRESS(gtid);
  1480. #endif
  1481. __kmpc_end_taskgroup(&loc, gtid);
  1482. return;
  1483. }
  1484. static kmp_int32 __kmp_gomp_to_omp_cancellation_kind(int gomp_kind) {
  1485. kmp_int32 cncl_kind = 0;
  1486. switch (gomp_kind) {
  1487. case 1:
  1488. cncl_kind = cancel_parallel;
  1489. break;
  1490. case 2:
  1491. cncl_kind = cancel_loop;
  1492. break;
  1493. case 4:
  1494. cncl_kind = cancel_sections;
  1495. break;
  1496. case 8:
  1497. cncl_kind = cancel_taskgroup;
  1498. break;
  1499. }
  1500. return cncl_kind;
  1501. }
  1502. // Return true if cancellation should take place, false otherwise
  1503. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCELLATION_POINT)(int which) {
  1504. int gtid = __kmp_get_gtid();
  1505. MKLOC(loc, "GOMP_cancellation_point");
  1506. KA_TRACE(20, ("GOMP_cancellation_point: T#%d which:%d\n", gtid, which));
  1507. kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which);
  1508. return __kmpc_cancellationpoint(&loc, gtid, cncl_kind);
  1509. }
  1510. // Return true if cancellation should take place, false otherwise
  1511. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_CANCEL)(int which, bool do_cancel) {
  1512. int gtid = __kmp_get_gtid();
  1513. MKLOC(loc, "GOMP_cancel");
  1514. KA_TRACE(20, ("GOMP_cancel: T#%d which:%d do_cancel:%d\n", gtid, which,
  1515. (int)do_cancel));
  1516. kmp_int32 cncl_kind = __kmp_gomp_to_omp_cancellation_kind(which);
  1517. if (do_cancel == FALSE) {
  1518. return __kmpc_cancellationpoint(&loc, gtid, cncl_kind);
  1519. } else {
  1520. return __kmpc_cancel(&loc, gtid, cncl_kind);
  1521. }
  1522. }
  1523. // Return true if cancellation should take place, false otherwise
  1524. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_BARRIER_CANCEL)(void) {
  1525. int gtid = __kmp_get_gtid();
  1526. KA_TRACE(20, ("GOMP_barrier_cancel: T#%d\n", gtid));
  1527. return __kmp_barrier_gomp_cancel(gtid);
  1528. }
  1529. // Return true if cancellation should take place, false otherwise
  1530. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL)(void) {
  1531. int gtid = __kmp_get_gtid();
  1532. KA_TRACE(20, ("GOMP_sections_end_cancel: T#%d\n", gtid));
  1533. return __kmp_barrier_gomp_cancel(gtid);
  1534. }
  1535. // Return true if cancellation should take place, false otherwise
  1536. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_END_CANCEL)(void) {
  1537. int gtid = __kmp_get_gtid();
  1538. KA_TRACE(20, ("GOMP_loop_end_cancel: T#%d\n", gtid));
  1539. return __kmp_barrier_gomp_cancel(gtid);
  1540. }
  1541. // All target functions are empty as of 2014-05-29
  1542. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET)(int device, void (*fn)(void *),
  1543. const void *openmp_target,
  1544. size_t mapnum, void **hostaddrs,
  1545. size_t *sizes,
  1546. unsigned char *kinds) {
  1547. return;
  1548. }
  1549. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_DATA)(
  1550. int device, const void *openmp_target, size_t mapnum, void **hostaddrs,
  1551. size_t *sizes, unsigned char *kinds) {
  1552. return;
  1553. }
  1554. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_END_DATA)(void) { return; }
  1555. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TARGET_UPDATE)(
  1556. int device, const void *openmp_target, size_t mapnum, void **hostaddrs,
  1557. size_t *sizes, unsigned char *kinds) {
  1558. return;
  1559. }
  1560. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams,
  1561. unsigned int thread_limit) {
  1562. return;
  1563. }
  1564. // Task duplication function which copies src to dest (both are
  1565. // preallocated task structures)
  1566. static void __kmp_gomp_task_dup(kmp_task_t *dest, kmp_task_t *src,
  1567. kmp_int32 last_private) {
  1568. kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(src);
  1569. if (taskdata->td_copy_func) {
  1570. (taskdata->td_copy_func)(dest->shareds, src->shareds);
  1571. }
  1572. }
  1573. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(
  1574. uintptr_t *);
  1575. #ifdef __cplusplus
  1576. } // extern "C"
  1577. #endif
  1578. template <typename T>
  1579. void __GOMP_taskloop(void (*func)(void *), void *data,
  1580. void (*copy_func)(void *, void *), long arg_size,
  1581. long arg_align, unsigned gomp_flags,
  1582. unsigned long num_tasks, int priority, T start, T end,
  1583. T step) {
  1584. typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
  1585. MKLOC(loc, "GOMP_taskloop");
  1586. int sched;
  1587. T *loop_bounds;
  1588. int gtid = __kmp_entry_gtid();
  1589. kmp_int32 flags = 0;
  1590. int if_val = gomp_flags & (1u << 10);
  1591. int nogroup = gomp_flags & (1u << 11);
  1592. int up = gomp_flags & (1u << 8);
  1593. int reductions = gomp_flags & (1u << 12);
  1594. p_task_dup_t task_dup = NULL;
  1595. kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
  1596. #ifdef KMP_DEBUG
  1597. {
  1598. char *buff;
  1599. buff = __kmp_str_format(
  1600. "GOMP_taskloop: T#%%d: func:%%p data:%%p copy_func:%%p "
  1601. "arg_size:%%ld arg_align:%%ld gomp_flags:0x%%x num_tasks:%%lu "
  1602. "priority:%%d start:%%%s end:%%%s step:%%%s\n",
  1603. traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec);
  1604. KA_TRACE(20, (buff, gtid, func, data, copy_func, arg_size, arg_align,
  1605. gomp_flags, num_tasks, priority, start, end, step));
  1606. __kmp_str_free(&buff);
  1607. }
  1608. #endif
  1609. KMP_ASSERT((size_t)arg_size >= 2 * sizeof(T));
  1610. KMP_ASSERT(arg_align > 0);
  1611. // The low-order bit is the "untied" flag
  1612. if (!(gomp_flags & 1)) {
  1613. input_flags->tiedness = TASK_TIED;
  1614. }
  1615. // The second low-order bit is the "final" flag
  1616. if (gomp_flags & 2) {
  1617. input_flags->final = 1;
  1618. }
  1619. // Negative step flag
  1620. if (!up) {
  1621. // If step is flagged as negative, but isn't properly sign extended
  1622. // Then manually sign extend it. Could be a short, int, char embedded
  1623. // in a long. So cannot assume any cast.
  1624. if (step > 0) {
  1625. for (int i = sizeof(T) * CHAR_BIT - 1; i >= 0L; --i) {
  1626. // break at the first 1 bit
  1627. if (step & ((T)1 << i))
  1628. break;
  1629. step |= ((T)1 << i);
  1630. }
  1631. }
  1632. }
  1633. input_flags->native = 1;
  1634. // Figure out if none/grainsize/num_tasks clause specified
  1635. if (num_tasks > 0) {
  1636. if (gomp_flags & (1u << 9))
  1637. sched = 1; // grainsize specified
  1638. else
  1639. sched = 2; // num_tasks specified
  1640. // neither grainsize nor num_tasks specified
  1641. } else {
  1642. sched = 0;
  1643. }
  1644. // __kmp_task_alloc() sets up all other flags
  1645. kmp_task_t *task =
  1646. __kmp_task_alloc(&loc, gtid, input_flags, sizeof(kmp_task_t),
  1647. arg_size + arg_align - 1, (kmp_routine_entry_t)func);
  1648. kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
  1649. taskdata->td_copy_func = copy_func;
  1650. taskdata->td_size_loop_bounds = sizeof(T);
  1651. // re-align shareds if needed and setup firstprivate copy constructors
  1652. // through the task_dup mechanism
  1653. task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) /
  1654. arg_align * arg_align);
  1655. if (copy_func) {
  1656. task_dup = __kmp_gomp_task_dup;
  1657. }
  1658. KMP_MEMCPY(task->shareds, data, arg_size);
  1659. loop_bounds = (T *)task->shareds;
  1660. loop_bounds[0] = start;
  1661. loop_bounds[1] = end + (up ? -1 : 1);
  1662. if (!nogroup) {
  1663. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1664. OMPT_STORE_RETURN_ADDRESS(gtid);
  1665. #endif
  1666. __kmpc_taskgroup(&loc, gtid);
  1667. if (reductions) {
  1668. // The data pointer points to lb, ub, then reduction data
  1669. struct data_t {
  1670. T a, b;
  1671. uintptr_t *d;
  1672. };
  1673. uintptr_t *d = ((data_t *)data)->d;
  1674. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(d);
  1675. }
  1676. }
  1677. __kmpc_taskloop(&loc, gtid, task, if_val, (kmp_uint64 *)&(loop_bounds[0]),
  1678. (kmp_uint64 *)&(loop_bounds[1]), (kmp_int64)step, 1, sched,
  1679. (kmp_uint64)num_tasks, (void *)task_dup);
  1680. if (!nogroup) {
  1681. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1682. OMPT_STORE_RETURN_ADDRESS(gtid);
  1683. #endif
  1684. __kmpc_end_taskgroup(&loc, gtid);
  1685. }
  1686. }
  1687. // 4 byte version of GOMP_doacross_post
  1688. // This verison needs to create a temporary array which converts 4 byte
  1689. // integers into 8 byte integers
  1690. template <typename T, bool need_conversion = (sizeof(long) == 4)>
  1691. void __kmp_GOMP_doacross_post(T *count);
  1692. template <> void __kmp_GOMP_doacross_post<long, true>(long *count) {
  1693. int gtid = __kmp_entry_gtid();
  1694. kmp_info_t *th = __kmp_threads[gtid];
  1695. MKLOC(loc, "GOMP_doacross_post");
  1696. kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0];
  1697. kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc(
  1698. th, (size_t)(sizeof(kmp_int64) * num_dims));
  1699. for (kmp_int64 i = 0; i < num_dims; ++i) {
  1700. vec[i] = (kmp_int64)count[i];
  1701. }
  1702. __kmpc_doacross_post(&loc, gtid, vec);
  1703. __kmp_thread_free(th, vec);
  1704. }
  1705. // 8 byte versions of GOMP_doacross_post
  1706. // This version can just pass in the count array directly instead of creating
  1707. // a temporary array
  1708. template <> void __kmp_GOMP_doacross_post<long, false>(long *count) {
  1709. int gtid = __kmp_entry_gtid();
  1710. MKLOC(loc, "GOMP_doacross_post");
  1711. __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count));
  1712. }
  1713. template <typename T> void __kmp_GOMP_doacross_wait(T first, va_list args) {
  1714. int gtid = __kmp_entry_gtid();
  1715. kmp_info_t *th = __kmp_threads[gtid];
  1716. MKLOC(loc, "GOMP_doacross_wait");
  1717. kmp_int64 num_dims = th->th.th_dispatch->th_doacross_info[0];
  1718. kmp_int64 *vec = (kmp_int64 *)__kmp_thread_malloc(
  1719. th, (size_t)(sizeof(kmp_int64) * num_dims));
  1720. vec[0] = (kmp_int64)first;
  1721. for (kmp_int64 i = 1; i < num_dims; ++i) {
  1722. T item = va_arg(args, T);
  1723. vec[i] = (kmp_int64)item;
  1724. }
  1725. __kmpc_doacross_wait(&loc, gtid, vec);
  1726. __kmp_thread_free(th, vec);
  1727. return;
  1728. }
  1729. #ifdef __cplusplus
  1730. extern "C" {
  1731. #endif // __cplusplus
  1732. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP)(
  1733. void (*func)(void *), void *data, void (*copy_func)(void *, void *),
  1734. long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
  1735. int priority, long start, long end, long step) {
  1736. __GOMP_taskloop<long>(func, data, copy_func, arg_size, arg_align, gomp_flags,
  1737. num_tasks, priority, start, end, step);
  1738. }
  1739. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP_ULL)(
  1740. void (*func)(void *), void *data, void (*copy_func)(void *, void *),
  1741. long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
  1742. int priority, unsigned long long start, unsigned long long end,
  1743. unsigned long long step) {
  1744. __GOMP_taskloop<unsigned long long>(func, data, copy_func, arg_size,
  1745. arg_align, gomp_flags, num_tasks,
  1746. priority, start, end, step);
  1747. }
  1748. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_POST)(long *count) {
  1749. __kmp_GOMP_doacross_post(count);
  1750. }
  1751. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_WAIT)(long first, ...) {
  1752. va_list args;
  1753. va_start(args, first);
  1754. __kmp_GOMP_doacross_wait<long>(first, args);
  1755. va_end(args);
  1756. }
  1757. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_POST)(
  1758. unsigned long long *count) {
  1759. int gtid = __kmp_entry_gtid();
  1760. MKLOC(loc, "GOMP_doacross_ull_post");
  1761. __kmpc_doacross_post(&loc, gtid, RCAST(kmp_int64 *, count));
  1762. }
  1763. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT)(
  1764. unsigned long long first, ...) {
  1765. va_list args;
  1766. va_start(args, first);
  1767. __kmp_GOMP_doacross_wait<unsigned long long>(first, args);
  1768. va_end(args);
  1769. }
  1770. // fn: the function each primary thread of new team will call
  1771. // data: argument to fn
  1772. // num_teams, thread_limit: max bounds on respective ICV
  1773. // flags: unused
  1774. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS_REG)(void (*fn)(void *),
  1775. void *data,
  1776. unsigned num_teams,
  1777. unsigned thread_limit,
  1778. unsigned flags) {
  1779. MKLOC(loc, "GOMP_teams_reg");
  1780. int gtid = __kmp_entry_gtid();
  1781. KA_TRACE(20, ("GOMP_teams_reg: T#%d num_teams=%u thread_limit=%u flag=%u\n",
  1782. gtid, num_teams, thread_limit, flags));
  1783. __kmpc_push_num_teams(&loc, gtid, num_teams, thread_limit);
  1784. __kmpc_fork_teams(&loc, 2, (microtask_t)__kmp_GOMP_microtask_wrapper, fn,
  1785. data);
  1786. KA_TRACE(20, ("GOMP_teams_reg exit: T#%d\n", gtid));
  1787. }
  1788. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT_DEPEND)(void **depend) {
  1789. MKLOC(loc, "GOMP_taskwait_depend");
  1790. int gtid = __kmp_entry_gtid();
  1791. KA_TRACE(20, ("GOMP_taskwait_depend: T#%d\n", gtid));
  1792. kmp_gomp_depends_info_t gomp_depends(depend);
  1793. kmp_int32 ndeps = gomp_depends.get_num_deps();
  1794. kmp_depend_info_t dep_list[ndeps];
  1795. for (kmp_int32 i = 0; i < ndeps; i++)
  1796. dep_list[i] = gomp_depends.get_kmp_depend(i);
  1797. #if OMPT_SUPPORT
  1798. OMPT_STORE_RETURN_ADDRESS(gtid);
  1799. #endif
  1800. __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL);
  1801. KA_TRACE(20, ("GOMP_taskwait_depend exit: T#%d\n", gtid));
  1802. }
  1803. static inline void
  1804. __kmp_GOMP_taskgroup_reduction_register(uintptr_t *data, kmp_taskgroup_t *tg,
  1805. int nthreads,
  1806. uintptr_t *allocated = nullptr) {
  1807. KMP_ASSERT(data);
  1808. KMP_ASSERT(nthreads > 0);
  1809. // Have private copy pointers point to previously allocated
  1810. // reduction data or allocate new data here
  1811. if (allocated) {
  1812. data[2] = allocated[2];
  1813. data[6] = allocated[6];
  1814. } else {
  1815. data[2] = (uintptr_t)__kmp_allocate(nthreads * data[1]);
  1816. data[6] = data[2] + (nthreads * data[1]);
  1817. }
  1818. if (tg)
  1819. tg->gomp_data = data;
  1820. }
  1821. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER)(
  1822. uintptr_t *data) {
  1823. int gtid = __kmp_entry_gtid();
  1824. KA_TRACE(20, ("GOMP_taskgroup_reduction_register: T#%d\n", gtid));
  1825. kmp_info_t *thread = __kmp_threads[gtid];
  1826. kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
  1827. int nthreads = thread->th.th_team_nproc;
  1828. __kmp_GOMP_taskgroup_reduction_register(data, tg, nthreads);
  1829. }
  1830. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER)(
  1831. uintptr_t *data) {
  1832. KA_TRACE(20,
  1833. ("GOMP_taskgroup_reduction_unregister: T#%d\n", __kmp_get_gtid()));
  1834. KMP_ASSERT(data && data[2]);
  1835. __kmp_free((void *)data[2]);
  1836. }
  1837. // Search through reduction data and set ptrs[] elements
  1838. // to proper privatized copy address
  1839. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP)(size_t cnt,
  1840. size_t cntorig,
  1841. void **ptrs) {
  1842. int gtid = __kmp_entry_gtid();
  1843. KA_TRACE(20, ("GOMP_task_reduction_remap: T#%d\n", gtid));
  1844. kmp_info_t *thread = __kmp_threads[gtid];
  1845. kmp_int32 tid = __kmp_get_tid();
  1846. for (size_t i = 0; i < cnt; ++i) {
  1847. uintptr_t address = (uintptr_t)ptrs[i];
  1848. void *propagated_address = NULL;
  1849. void *mapped_address = NULL;
  1850. // Check taskgroups reduce data
  1851. kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
  1852. while (tg) {
  1853. uintptr_t *gomp_data = tg->gomp_data;
  1854. if (!gomp_data) {
  1855. tg = tg->parent;
  1856. continue;
  1857. }
  1858. // Check the shared addresses list
  1859. size_t num_vars = (size_t)gomp_data[0];
  1860. uintptr_t per_thread_size = gomp_data[1];
  1861. uintptr_t reduce_data = gomp_data[2];
  1862. uintptr_t end_reduce_data = gomp_data[6];
  1863. for (size_t j = 0; j < num_vars; ++j) {
  1864. uintptr_t *entry = gomp_data + 7 + 3 * j;
  1865. if (entry[0] == address) {
  1866. uintptr_t offset = entry[1];
  1867. mapped_address =
  1868. (void *)(reduce_data + tid * per_thread_size + offset);
  1869. if (i < cntorig)
  1870. propagated_address = (void *)entry[0];
  1871. break;
  1872. }
  1873. }
  1874. if (mapped_address)
  1875. break;
  1876. // Check if address is within privatized copies range
  1877. if (!mapped_address && address >= reduce_data &&
  1878. address < end_reduce_data) {
  1879. uintptr_t offset = (address - reduce_data) % per_thread_size;
  1880. mapped_address = (void *)(reduce_data + tid * per_thread_size + offset);
  1881. if (i < cntorig) {
  1882. for (size_t j = 0; j < num_vars; ++j) {
  1883. uintptr_t *entry = gomp_data + 7 + 3 * j;
  1884. if (entry[1] == offset) {
  1885. propagated_address = (void *)entry[0];
  1886. break;
  1887. }
  1888. }
  1889. }
  1890. }
  1891. if (mapped_address)
  1892. break;
  1893. tg = tg->parent;
  1894. }
  1895. KMP_ASSERT(mapped_address);
  1896. ptrs[i] = mapped_address;
  1897. if (i < cntorig) {
  1898. KMP_ASSERT(propagated_address);
  1899. ptrs[cnt + i] = propagated_address;
  1900. }
  1901. }
  1902. }
  1903. static void __kmp_GOMP_init_reductions(int gtid, uintptr_t *data, int is_ws) {
  1904. kmp_info_t *thr = __kmp_threads[gtid];
  1905. kmp_team_t *team = thr->th.th_team;
  1906. // First start a taskgroup
  1907. __kmpc_taskgroup(NULL, gtid);
  1908. // Then setup reduction data
  1909. void *reduce_data = KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[is_ws]);
  1910. if (reduce_data == NULL &&
  1911. __kmp_atomic_compare_store(&team->t.t_tg_reduce_data[is_ws], reduce_data,
  1912. (void *)1)) {
  1913. // Single thread enters this block to initialize common reduction data
  1914. KMP_DEBUG_ASSERT(reduce_data == NULL);
  1915. __kmp_GOMP_taskgroup_reduction_register(data, NULL, thr->th.th_team_nproc);
  1916. KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[is_ws], 0);
  1917. KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[is_ws], (void *)data);
  1918. } else {
  1919. // Wait for task reduction initialization
  1920. while ((reduce_data = KMP_ATOMIC_LD_ACQ(
  1921. &team->t.t_tg_reduce_data[is_ws])) == (void *)1) {
  1922. KMP_CPU_PAUSE();
  1923. }
  1924. KMP_DEBUG_ASSERT(reduce_data > (void *)1); // should be valid pointer here
  1925. }
  1926. // For worksharing constructs, each thread has its own reduction structure.
  1927. // Have each reduction structure point to same privatized copies of vars.
  1928. // For parallel, each thread points to same reduction structure and privatized
  1929. // copies of vars
  1930. if (is_ws) {
  1931. __kmp_GOMP_taskgroup_reduction_register(
  1932. data, NULL, thr->th.th_team_nproc,
  1933. (uintptr_t *)KMP_ATOMIC_LD_ACQ(&team->t.t_tg_reduce_data[is_ws]));
  1934. }
  1935. kmp_taskgroup_t *tg = thr->th.th_current_task->td_taskgroup;
  1936. tg->gomp_data = data;
  1937. }
  1938. static unsigned
  1939. __kmp_GOMP_par_reductions_microtask_wrapper(int *gtid, int *npr,
  1940. void (*task)(void *), void *data) {
  1941. kmp_info_t *thr = __kmp_threads[*gtid];
  1942. kmp_team_t *team = thr->th.th_team;
  1943. uintptr_t *reduce_data = *(uintptr_t **)data;
  1944. __kmp_GOMP_init_reductions(*gtid, reduce_data, 0);
  1945. #if OMPT_SUPPORT
  1946. ompt_frame_t *ompt_frame;
  1947. ompt_state_t enclosing_state;
  1948. if (ompt_enabled.enabled) {
  1949. // save enclosing task state; set current state for task
  1950. enclosing_state = thr->th.ompt_thread_info.state;
  1951. thr->th.ompt_thread_info.state = ompt_state_work_parallel;
  1952. // set task frame
  1953. __ompt_get_task_info_internal(0, NULL, NULL, &ompt_frame, NULL, NULL);
  1954. ompt_frame->exit_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  1955. }
  1956. #endif
  1957. task(data);
  1958. #if OMPT_SUPPORT
  1959. if (ompt_enabled.enabled) {
  1960. // clear task frame
  1961. ompt_frame->exit_frame = ompt_data_none;
  1962. // restore enclosing state
  1963. thr->th.ompt_thread_info.state = enclosing_state;
  1964. }
  1965. #endif
  1966. __kmpc_end_taskgroup(NULL, *gtid);
  1967. // if last thread out, then reset the team's reduce data
  1968. // the GOMP_taskgroup_reduction_unregister() function will deallocate
  1969. // private copies after reduction calculations take place.
  1970. int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[0]);
  1971. if (count == thr->th.th_team_nproc - 1) {
  1972. KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[0], NULL);
  1973. KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[0], 0);
  1974. }
  1975. return (unsigned)thr->th.th_team_nproc;
  1976. }
  1977. unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS)(
  1978. void (*task)(void *), void *data, unsigned num_threads,
  1979. unsigned int flags) {
  1980. MKLOC(loc, "GOMP_parallel_reductions");
  1981. int gtid = __kmp_entry_gtid();
  1982. KA_TRACE(20, ("GOMP_parallel_reductions: T#%d\n", gtid));
  1983. __kmp_GOMP_fork_call(&loc, gtid, num_threads, flags, task,
  1984. (microtask_t)__kmp_GOMP_par_reductions_microtask_wrapper,
  1985. 2, task, data);
  1986. unsigned retval =
  1987. __kmp_GOMP_par_reductions_microtask_wrapper(&gtid, NULL, task, data);
  1988. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_PARALLEL_END)();
  1989. KA_TRACE(20, ("GOMP_parallel_reductions exit: T#%d\n", gtid));
  1990. return retval;
  1991. }
  1992. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_START)(
  1993. long start, long end, long incr, long sched, long chunk_size, long *istart,
  1994. long *iend, uintptr_t *reductions, void **mem) {
  1995. int status = 0;
  1996. int gtid = __kmp_entry_gtid();
  1997. KA_TRACE(20, ("GOMP_loop_start: T#%d, reductions: %p\n", gtid, reductions));
  1998. if (reductions)
  1999. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2000. if (mem)
  2001. KMP_FATAL(GompFeatureNotSupported, "scan");
  2002. if (istart == NULL)
  2003. return true;
  2004. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2005. long monotonic = sched & MONOTONIC_FLAG;
  2006. sched &= ~MONOTONIC_FLAG;
  2007. if (sched == 0) {
  2008. if (monotonic)
  2009. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_RUNTIME_START)(
  2010. start, end, incr, istart, iend);
  2011. else
  2012. status = KMP_EXPAND_NAME(
  2013. KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START)(
  2014. start, end, incr, istart, iend);
  2015. } else if (sched == 1) {
  2016. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_STATIC_START)(
  2017. start, end, incr, chunk_size, istart, iend);
  2018. } else if (sched == 2) {
  2019. if (monotonic)
  2020. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START)(
  2021. start, end, incr, chunk_size, istart, iend);
  2022. else
  2023. status =
  2024. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START)(
  2025. start, end, incr, chunk_size, istart, iend);
  2026. } else if (sched == 3) {
  2027. if (monotonic)
  2028. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_GUIDED_START)(
  2029. start, end, incr, chunk_size, istart, iend);
  2030. else
  2031. status =
  2032. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START)(
  2033. start, end, incr, chunk_size, istart, iend);
  2034. } else if (sched == 4) {
  2035. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START)(
  2036. start, end, incr, istart, iend);
  2037. } else {
  2038. KMP_ASSERT(0);
  2039. }
  2040. return status;
  2041. }
  2042. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_START)(
  2043. bool up, unsigned long long start, unsigned long long end,
  2044. unsigned long long incr, long sched, unsigned long long chunk_size,
  2045. unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions,
  2046. void **mem) {
  2047. int status = 0;
  2048. int gtid = __kmp_entry_gtid();
  2049. KA_TRACE(20,
  2050. ("GOMP_loop_ull_start: T#%d, reductions: %p\n", gtid, reductions));
  2051. if (reductions)
  2052. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2053. if (mem)
  2054. KMP_FATAL(GompFeatureNotSupported, "scan");
  2055. if (istart == NULL)
  2056. return true;
  2057. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2058. long monotonic = sched & MONOTONIC_FLAG;
  2059. sched &= ~MONOTONIC_FLAG;
  2060. if (sched == 0) {
  2061. if (monotonic)
  2062. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START)(
  2063. up, start, end, incr, istart, iend);
  2064. else
  2065. status = KMP_EXPAND_NAME(
  2066. KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START)(
  2067. up, start, end, incr, istart, iend);
  2068. } else if (sched == 1) {
  2069. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START)(
  2070. up, start, end, incr, chunk_size, istart, iend);
  2071. } else if (sched == 2) {
  2072. if (monotonic)
  2073. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START)(
  2074. up, start, end, incr, chunk_size, istart, iend);
  2075. else
  2076. status = KMP_EXPAND_NAME(
  2077. KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START)(
  2078. up, start, end, incr, chunk_size, istart, iend);
  2079. } else if (sched == 3) {
  2080. if (monotonic)
  2081. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START)(
  2082. up, start, end, incr, chunk_size, istart, iend);
  2083. else
  2084. status =
  2085. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START)(
  2086. up, start, end, incr, chunk_size, istart, iend);
  2087. } else if (sched == 4) {
  2088. status =
  2089. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START)(
  2090. up, start, end, incr, istart, iend);
  2091. } else {
  2092. KMP_ASSERT(0);
  2093. }
  2094. return status;
  2095. }
  2096. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_START)(
  2097. unsigned ncounts, long *counts, long sched, long chunk_size, long *istart,
  2098. long *iend, uintptr_t *reductions, void **mem) {
  2099. int status = 0;
  2100. int gtid = __kmp_entry_gtid();
  2101. KA_TRACE(20, ("GOMP_loop_doacross_start: T#%d, reductions: %p\n", gtid,
  2102. reductions));
  2103. if (reductions)
  2104. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2105. if (mem)
  2106. KMP_FATAL(GompFeatureNotSupported, "scan");
  2107. if (istart == NULL)
  2108. return true;
  2109. // Ignore any monotonic flag
  2110. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2111. sched &= ~MONOTONIC_FLAG;
  2112. if (sched == 0) {
  2113. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START)(
  2114. ncounts, counts, istart, iend);
  2115. } else if (sched == 1) {
  2116. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START)(
  2117. ncounts, counts, chunk_size, istart, iend);
  2118. } else if (sched == 2) {
  2119. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START)(
  2120. ncounts, counts, chunk_size, istart, iend);
  2121. } else if (sched == 3) {
  2122. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START)(
  2123. ncounts, counts, chunk_size, istart, iend);
  2124. } else {
  2125. KMP_ASSERT(0);
  2126. }
  2127. return status;
  2128. }
  2129. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START)(
  2130. unsigned ncounts, unsigned long long *counts, long sched,
  2131. unsigned long long chunk_size, unsigned long long *istart,
  2132. unsigned long long *iend, uintptr_t *reductions, void **mem) {
  2133. int status = 0;
  2134. int gtid = __kmp_entry_gtid();
  2135. KA_TRACE(20, ("GOMP_loop_ull_doacross_start: T#%d, reductions: %p\n", gtid,
  2136. reductions));
  2137. if (reductions)
  2138. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2139. if (mem)
  2140. KMP_FATAL(GompFeatureNotSupported, "scan");
  2141. if (istart == NULL)
  2142. return true;
  2143. // Ignore any monotonic flag
  2144. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2145. sched &= ~MONOTONIC_FLAG;
  2146. if (sched == 0) {
  2147. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START)(
  2148. ncounts, counts, istart, iend);
  2149. } else if (sched == 1) {
  2150. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START)(
  2151. ncounts, counts, chunk_size, istart, iend);
  2152. } else if (sched == 2) {
  2153. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START)(
  2154. ncounts, counts, chunk_size, istart, iend);
  2155. } else if (sched == 3) {
  2156. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START)(
  2157. ncounts, counts, chunk_size, istart, iend);
  2158. } else {
  2159. KMP_ASSERT(0);
  2160. }
  2161. return status;
  2162. }
  2163. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_START)(
  2164. long start, long end, long incr, long sched, long chunk_size, long *istart,
  2165. long *iend, uintptr_t *reductions, void **mem) {
  2166. int status = 0;
  2167. int gtid = __kmp_entry_gtid();
  2168. KA_TRACE(20, ("GOMP_loop_ordered_start: T#%d, reductions: %p\n", gtid,
  2169. reductions));
  2170. if (reductions)
  2171. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2172. if (mem)
  2173. KMP_FATAL(GompFeatureNotSupported, "scan");
  2174. if (istart == NULL)
  2175. return true;
  2176. // Ignore any monotonic flag
  2177. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2178. sched &= ~MONOTONIC_FLAG;
  2179. if (sched == 0) {
  2180. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START)(
  2181. start, end, incr, istart, iend);
  2182. } else if (sched == 1) {
  2183. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START)(
  2184. start, end, incr, chunk_size, istart, iend);
  2185. } else if (sched == 2) {
  2186. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START)(
  2187. start, end, incr, chunk_size, istart, iend);
  2188. } else if (sched == 3) {
  2189. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START)(
  2190. start, end, incr, chunk_size, istart, iend);
  2191. } else {
  2192. KMP_ASSERT(0);
  2193. }
  2194. return status;
  2195. }
  2196. bool KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START)(
  2197. bool up, unsigned long long start, unsigned long long end,
  2198. unsigned long long incr, long sched, unsigned long long chunk_size,
  2199. unsigned long long *istart, unsigned long long *iend, uintptr_t *reductions,
  2200. void **mem) {
  2201. int status = 0;
  2202. int gtid = __kmp_entry_gtid();
  2203. KA_TRACE(20, ("GOMP_loop_ull_ordered_start: T#%d, reductions: %p\n", gtid,
  2204. reductions));
  2205. if (reductions)
  2206. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2207. if (mem)
  2208. KMP_FATAL(GompFeatureNotSupported, "scan");
  2209. if (istart == NULL)
  2210. return true;
  2211. // Ignore any monotonic flag
  2212. const long MONOTONIC_FLAG = (long)(kmp_sched_monotonic);
  2213. sched &= ~MONOTONIC_FLAG;
  2214. if (sched == 0) {
  2215. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START)(
  2216. up, start, end, incr, istart, iend);
  2217. } else if (sched == 1) {
  2218. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START)(
  2219. up, start, end, incr, chunk_size, istart, iend);
  2220. } else if (sched == 2) {
  2221. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START)(
  2222. up, start, end, incr, chunk_size, istart, iend);
  2223. } else if (sched == 3) {
  2224. status = KMP_EXPAND_NAME(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START)(
  2225. up, start, end, incr, chunk_size, istart, iend);
  2226. } else {
  2227. KMP_ASSERT(0);
  2228. }
  2229. return status;
  2230. }
  2231. unsigned KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS2_START)(
  2232. unsigned count, uintptr_t *reductions, void **mem) {
  2233. int gtid = __kmp_entry_gtid();
  2234. KA_TRACE(20,
  2235. ("GOMP_sections2_start: T#%d, reductions: %p\n", gtid, reductions));
  2236. if (reductions)
  2237. __kmp_GOMP_init_reductions(gtid, reductions, 1);
  2238. if (mem)
  2239. KMP_FATAL(GompFeatureNotSupported, "scan");
  2240. return KMP_EXPAND_NAME(KMP_API_NAME_GOMP_SECTIONS_START)(count);
  2241. }
  2242. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER)(
  2243. bool cancelled) {
  2244. int gtid = __kmp_get_gtid();
  2245. MKLOC(loc, "GOMP_workshare_task_reduction_unregister");
  2246. KA_TRACE(20, ("GOMP_workshare_task_reduction_unregister: T#%d\n", gtid));
  2247. kmp_info_t *thr = __kmp_threads[gtid];
  2248. kmp_team_t *team = thr->th.th_team;
  2249. __kmpc_end_taskgroup(NULL, gtid);
  2250. // If last thread out of workshare, then reset the team's reduce data
  2251. // the GOMP_taskgroup_reduction_unregister() function will deallocate
  2252. // private copies after reduction calculations take place.
  2253. int count = KMP_ATOMIC_INC(&team->t.t_tg_fini_counter[1]);
  2254. if (count == thr->th.th_team_nproc - 1) {
  2255. KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER)
  2256. ((uintptr_t *)KMP_ATOMIC_LD_RLX(&team->t.t_tg_reduce_data[1]));
  2257. KMP_ATOMIC_ST_REL(&team->t.t_tg_reduce_data[1], NULL);
  2258. KMP_ATOMIC_ST_REL(&team->t.t_tg_fini_counter[1], 0);
  2259. }
  2260. if (!cancelled) {
  2261. __kmpc_barrier(&loc, gtid);
  2262. }
  2263. }
  2264. // allocator construct
  2265. void *KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ALLOC)(size_t alignment, size_t size,
  2266. uintptr_t allocator) {
  2267. int gtid = __kmp_entry_gtid();
  2268. KA_TRACE(20, ("GOMP_alloc: T#%d\n", gtid));
  2269. #if OMPT_SUPPORT && OMPT_OPTIONAL
  2270. OMPT_STORE_RETURN_ADDRESS(gtid);
  2271. #endif
  2272. return __kmp_alloc(gtid, alignment, size, (omp_allocator_handle_t)allocator);
  2273. }
  2274. void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_FREE)(void *ptr, uintptr_t allocator) {
  2275. int gtid = __kmp_entry_gtid();
  2276. KA_TRACE(20, ("GOMP_free: T#%d\n", gtid));
  2277. #if OMPT_SUPPORT && OMPT_OPTIONAL
  2278. OMPT_STORE_RETURN_ADDRESS(gtid);
  2279. #endif
  2280. return ___kmpc_free(gtid, ptr, (omp_allocator_handle_t)allocator);
  2281. }
  2282. /* The following sections of code create aliases for the GOMP_* functions, then
  2283. create versioned symbols using the assembler directive .symver. This is only
  2284. pertinent for ELF .so library. The KMP_VERSION_SYMBOL macro is defined in
  2285. kmp_os.h */
  2286. #ifdef KMP_USE_VERSION_SYMBOLS
  2287. // GOMP_1.0 versioned symbols
  2288. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_END, 10, "GOMP_1.0");
  2289. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ATOMIC_START, 10, "GOMP_1.0");
  2290. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER, 10, "GOMP_1.0");
  2291. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_END, 10, "GOMP_1.0");
  2292. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_END, 10, "GOMP_1.0");
  2293. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_NAME_START, 10, "GOMP_1.0");
  2294. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CRITICAL_START, 10, "GOMP_1.0");
  2295. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT, 10, "GOMP_1.0");
  2296. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DYNAMIC_START, 10, "GOMP_1.0");
  2297. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END, 10, "GOMP_1.0");
  2298. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_NOWAIT, 10, "GOMP_1.0");
  2299. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT, 10, "GOMP_1.0");
  2300. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_GUIDED_START, 10, "GOMP_1.0");
  2301. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT, 10, "GOMP_1.0");
  2302. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START, 10,
  2303. "GOMP_1.0");
  2304. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT, 10, "GOMP_1.0");
  2305. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START, 10, "GOMP_1.0");
  2306. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT, 10, "GOMP_1.0");
  2307. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START, 10,
  2308. "GOMP_1.0");
  2309. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT, 10, "GOMP_1.0");
  2310. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START, 10, "GOMP_1.0");
  2311. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT, 10, "GOMP_1.0");
  2312. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_RUNTIME_START, 10, "GOMP_1.0");
  2313. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_NEXT, 10, "GOMP_1.0");
  2314. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_STATIC_START, 10, "GOMP_1.0");
  2315. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_END, 10, "GOMP_1.0");
  2316. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ORDERED_START, 10, "GOMP_1.0");
  2317. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_END, 10, "GOMP_1.0");
  2318. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START, 10,
  2319. "GOMP_1.0");
  2320. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START, 10,
  2321. "GOMP_1.0");
  2322. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START, 10,
  2323. "GOMP_1.0");
  2324. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START, 10,
  2325. "GOMP_1.0");
  2326. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START, 10, "GOMP_1.0");
  2327. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_START, 10, "GOMP_1.0");
  2328. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END, 10, "GOMP_1.0");
  2329. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT, 10, "GOMP_1.0");
  2330. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_NEXT, 10, "GOMP_1.0");
  2331. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_START, 10, "GOMP_1.0");
  2332. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_END, 10, "GOMP_1.0");
  2333. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_COPY_START, 10, "GOMP_1.0");
  2334. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SINGLE_START, 10, "GOMP_1.0");
  2335. // GOMP_2.0 versioned symbols
  2336. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK, 20, "GOMP_2.0");
  2337. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT, 20, "GOMP_2.0");
  2338. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT, 20, "GOMP_2.0");
  2339. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START, 20, "GOMP_2.0");
  2340. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT, 20, "GOMP_2.0");
  2341. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START, 20, "GOMP_2.0");
  2342. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT, 20,
  2343. "GOMP_2.0");
  2344. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START, 20,
  2345. "GOMP_2.0");
  2346. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT, 20,
  2347. "GOMP_2.0");
  2348. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START, 20,
  2349. "GOMP_2.0");
  2350. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT, 20,
  2351. "GOMP_2.0");
  2352. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START, 20,
  2353. "GOMP_2.0");
  2354. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT, 20,
  2355. "GOMP_2.0");
  2356. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START, 20,
  2357. "GOMP_2.0");
  2358. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT, 20, "GOMP_2.0");
  2359. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START, 20, "GOMP_2.0");
  2360. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT, 20, "GOMP_2.0");
  2361. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START, 20, "GOMP_2.0");
  2362. // GOMP_3.0 versioned symbols
  2363. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKYIELD, 30, "GOMP_3.0");
  2364. // GOMP_4.0 versioned symbols
  2365. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL, 40, "GOMP_4.0");
  2366. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_SECTIONS, 40, "GOMP_4.0");
  2367. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC, 40, "GOMP_4.0");
  2368. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED, 40, "GOMP_4.0");
  2369. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME, 40, "GOMP_4.0");
  2370. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC, 40, "GOMP_4.0");
  2371. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_START, 40, "GOMP_4.0");
  2372. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_END, 40, "GOMP_4.0");
  2373. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_BARRIER_CANCEL, 40, "GOMP_4.0");
  2374. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCEL, 40, "GOMP_4.0");
  2375. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_CANCELLATION_POINT, 40, "GOMP_4.0");
  2376. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_END_CANCEL, 40, "GOMP_4.0");
  2377. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS_END_CANCEL, 40, "GOMP_4.0");
  2378. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET, 40, "GOMP_4.0");
  2379. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_DATA, 40, "GOMP_4.0");
  2380. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_END_DATA, 40, "GOMP_4.0");
  2381. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0");
  2382. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0");
  2383. // GOMP_4.5 versioned symbols
  2384. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP, 45, "GOMP_4.5");
  2385. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP_ULL, 45, "GOMP_4.5");
  2386. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_POST, 45, "GOMP_4.5");
  2387. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_WAIT, 45, "GOMP_4.5");
  2388. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START, 45,
  2389. "GOMP_4.5");
  2390. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START, 45,
  2391. "GOMP_4.5");
  2392. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START, 45,
  2393. "GOMP_4.5");
  2394. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START, 45,
  2395. "GOMP_4.5");
  2396. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_POST, 45, "GOMP_4.5");
  2397. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT, 45, "GOMP_4.5");
  2398. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START, 45,
  2399. "GOMP_4.5");
  2400. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START, 45,
  2401. "GOMP_4.5");
  2402. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START, 45,
  2403. "GOMP_4.5");
  2404. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START, 45,
  2405. "GOMP_4.5");
  2406. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START, 45,
  2407. "GOMP_4.5");
  2408. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT, 45,
  2409. "GOMP_4.5");
  2410. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START, 45,
  2411. "GOMP_4.5");
  2412. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT, 45,
  2413. "GOMP_4.5");
  2414. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START, 45,
  2415. "GOMP_4.5");
  2416. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT, 45,
  2417. "GOMP_4.5");
  2418. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START, 45,
  2419. "GOMP_4.5");
  2420. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT, 45,
  2421. "GOMP_4.5");
  2422. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC, 45,
  2423. "GOMP_4.5");
  2424. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED, 45,
  2425. "GOMP_4.5");
  2426. // GOMP_5.0 versioned symbols
  2427. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT, 50,
  2428. "GOMP_5.0");
  2429. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START, 50,
  2430. "GOMP_5.0");
  2431. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT, 50,
  2432. "GOMP_5.0");
  2433. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START, 50,
  2434. "GOMP_5.0");
  2435. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
  2436. 50, "GOMP_5.0");
  2437. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
  2438. 50, "GOMP_5.0");
  2439. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT, 50,
  2440. "GOMP_5.0");
  2441. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START, 50,
  2442. "GOMP_5.0");
  2443. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME, 50,
  2444. "GOMP_5.0");
  2445. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME,
  2446. 50, "GOMP_5.0");
  2447. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS_REG, 50, "GOMP_5.0");
  2448. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT_DEPEND, 50, "GOMP_5.0");
  2449. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER, 50,
  2450. "GOMP_5.0");
  2451. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER, 50,
  2452. "GOMP_5.0");
  2453. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP, 50, "GOMP_5.0");
  2454. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS, 50, "GOMP_5.0");
  2455. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_START, 50, "GOMP_5.0");
  2456. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_START, 50, "GOMP_5.0");
  2457. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_DOACROSS_START, 50, "GOMP_5.0");
  2458. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START, 50, "GOMP_5.0");
  2459. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ORDERED_START, 50, "GOMP_5.0");
  2460. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START, 50, "GOMP_5.0");
  2461. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_SECTIONS2_START, 50, "GOMP_5.0");
  2462. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER, 50,
  2463. "GOMP_5.0");
  2464. // GOMP_5.0.1 versioned symbols
  2465. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_ALLOC, 501, "GOMP_5.0.1");
  2466. KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_FREE, 501, "GOMP_5.0.1");
  2467. #endif // KMP_USE_VERSION_SYMBOLS
  2468. #ifdef __cplusplus
  2469. } // extern "C"
  2470. #endif // __cplusplus