kmp_ftn_entry.h 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747
  1. /*
  2. * kmp_ftn_entry.h -- Fortran entry linkage support for OpenMP.
  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. #ifndef FTN_STDCALL
  12. #error The support file kmp_ftn_entry.h should not be compiled by itself.
  13. #endif
  14. #ifdef KMP_STUB
  15. #error #include "kmp_stub.h"
  16. #endif
  17. #include "kmp_i18n.h"
  18. // For affinity format functions
  19. #include "kmp_io.h"
  20. #include "kmp_str.h"
  21. #if OMPT_SUPPORT
  22. #include "ompt-specific.h"
  23. #endif
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif // __cplusplus
  27. /* For compatibility with the Gnu/MS Open MP codegen, omp_set_num_threads(),
  28. * omp_set_nested(), and omp_set_dynamic() [in lowercase on MS, and w/o
  29. * a trailing underscore on Linux* OS] take call by value integer arguments.
  30. * + omp_set_max_active_levels()
  31. * + omp_set_schedule()
  32. *
  33. * For backward compatibility with 9.1 and previous Intel compiler, these
  34. * entry points take call by reference integer arguments. */
  35. #ifdef KMP_GOMP_COMPAT
  36. #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_UPPER)
  37. #define PASS_ARGS_BY_VALUE 1
  38. #endif
  39. #endif
  40. #if KMP_OS_WINDOWS
  41. #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_APPEND)
  42. #define PASS_ARGS_BY_VALUE 1
  43. #endif
  44. #endif
  45. // This macro helps to reduce code duplication.
  46. #ifdef PASS_ARGS_BY_VALUE
  47. #define KMP_DEREF
  48. #else
  49. #define KMP_DEREF *
  50. #endif
  51. // For API with specific C vs. Fortran interfaces (ompc_* exists in
  52. // kmp_csupport.cpp), only create GOMP versioned symbols of the API for the
  53. // APPEND Fortran entries in this file. The GOMP versioned symbols of the C API
  54. // will take place where the ompc_* functions are defined.
  55. #if KMP_FTN_ENTRIES == KMP_FTN_APPEND
  56. #define KMP_EXPAND_NAME_IF_APPEND(name) KMP_EXPAND_NAME(name)
  57. #else
  58. #define KMP_EXPAND_NAME_IF_APPEND(name) name
  59. #endif
  60. void FTN_STDCALL FTN_SET_STACKSIZE(int KMP_DEREF arg) {
  61. #ifdef KMP_STUB
  62. __kmps_set_stacksize(KMP_DEREF arg);
  63. #else
  64. // __kmp_aux_set_stacksize initializes the library if needed
  65. __kmp_aux_set_stacksize((size_t)KMP_DEREF arg);
  66. #endif
  67. }
  68. void FTN_STDCALL FTN_SET_STACKSIZE_S(size_t KMP_DEREF arg) {
  69. #ifdef KMP_STUB
  70. __kmps_set_stacksize(KMP_DEREF arg);
  71. #else
  72. // __kmp_aux_set_stacksize initializes the library if needed
  73. __kmp_aux_set_stacksize(KMP_DEREF arg);
  74. #endif
  75. }
  76. int FTN_STDCALL FTN_GET_STACKSIZE(void) {
  77. #ifdef KMP_STUB
  78. return (int)__kmps_get_stacksize();
  79. #else
  80. if (!__kmp_init_serial) {
  81. __kmp_serial_initialize();
  82. }
  83. return (int)__kmp_stksize;
  84. #endif
  85. }
  86. size_t FTN_STDCALL FTN_GET_STACKSIZE_S(void) {
  87. #ifdef KMP_STUB
  88. return __kmps_get_stacksize();
  89. #else
  90. if (!__kmp_init_serial) {
  91. __kmp_serial_initialize();
  92. }
  93. return __kmp_stksize;
  94. #endif
  95. }
  96. void FTN_STDCALL FTN_SET_BLOCKTIME(int KMP_DEREF arg) {
  97. #ifdef KMP_STUB
  98. __kmps_set_blocktime(KMP_DEREF arg);
  99. #else
  100. int gtid, tid;
  101. kmp_info_t *thread;
  102. gtid = __kmp_entry_gtid();
  103. tid = __kmp_tid_from_gtid(gtid);
  104. thread = __kmp_thread_from_gtid(gtid);
  105. __kmp_aux_set_blocktime(KMP_DEREF arg, thread, tid);
  106. #endif
  107. }
  108. int FTN_STDCALL FTN_GET_BLOCKTIME(void) {
  109. #ifdef KMP_STUB
  110. return __kmps_get_blocktime();
  111. #else
  112. int gtid, tid;
  113. kmp_team_p *team;
  114. gtid = __kmp_entry_gtid();
  115. tid = __kmp_tid_from_gtid(gtid);
  116. team = __kmp_threads[gtid]->th.th_team;
  117. /* These must match the settings used in __kmp_wait_sleep() */
  118. if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
  119. KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
  120. team->t.t_id, tid, KMP_MAX_BLOCKTIME));
  121. return KMP_MAX_BLOCKTIME;
  122. }
  123. #ifdef KMP_ADJUST_BLOCKTIME
  124. else if (__kmp_zero_bt && !get__bt_set(team, tid)) {
  125. KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
  126. team->t.t_id, tid, 0));
  127. return 0;
  128. }
  129. #endif /* KMP_ADJUST_BLOCKTIME */
  130. else {
  131. KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
  132. team->t.t_id, tid, get__blocktime(team, tid)));
  133. return get__blocktime(team, tid);
  134. }
  135. #endif
  136. }
  137. void FTN_STDCALL FTN_SET_LIBRARY_SERIAL(void) {
  138. #ifdef KMP_STUB
  139. __kmps_set_library(library_serial);
  140. #else
  141. // __kmp_user_set_library initializes the library if needed
  142. __kmp_user_set_library(library_serial);
  143. #endif
  144. }
  145. void FTN_STDCALL FTN_SET_LIBRARY_TURNAROUND(void) {
  146. #ifdef KMP_STUB
  147. __kmps_set_library(library_turnaround);
  148. #else
  149. // __kmp_user_set_library initializes the library if needed
  150. __kmp_user_set_library(library_turnaround);
  151. #endif
  152. }
  153. void FTN_STDCALL FTN_SET_LIBRARY_THROUGHPUT(void) {
  154. #ifdef KMP_STUB
  155. __kmps_set_library(library_throughput);
  156. #else
  157. // __kmp_user_set_library initializes the library if needed
  158. __kmp_user_set_library(library_throughput);
  159. #endif
  160. }
  161. void FTN_STDCALL FTN_SET_LIBRARY(int KMP_DEREF arg) {
  162. #ifdef KMP_STUB
  163. __kmps_set_library(KMP_DEREF arg);
  164. #else
  165. enum library_type lib;
  166. lib = (enum library_type)KMP_DEREF arg;
  167. // __kmp_user_set_library initializes the library if needed
  168. __kmp_user_set_library(lib);
  169. #endif
  170. }
  171. int FTN_STDCALL FTN_GET_LIBRARY(void) {
  172. #ifdef KMP_STUB
  173. return __kmps_get_library();
  174. #else
  175. if (!__kmp_init_serial) {
  176. __kmp_serial_initialize();
  177. }
  178. return ((int)__kmp_library);
  179. #endif
  180. }
  181. void FTN_STDCALL FTN_SET_DISP_NUM_BUFFERS(int KMP_DEREF arg) {
  182. #ifdef KMP_STUB
  183. ; // empty routine
  184. #else
  185. // ignore after initialization because some teams have already
  186. // allocated dispatch buffers
  187. int num_buffers = KMP_DEREF arg;
  188. if (__kmp_init_serial == FALSE && num_buffers >= KMP_MIN_DISP_NUM_BUFF &&
  189. num_buffers <= KMP_MAX_DISP_NUM_BUFF) {
  190. __kmp_dispatch_num_buffers = num_buffers;
  191. }
  192. #endif
  193. }
  194. int FTN_STDCALL FTN_SET_AFFINITY(void **mask) {
  195. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  196. return -1;
  197. #else
  198. if (!TCR_4(__kmp_init_middle)) {
  199. __kmp_middle_initialize();
  200. }
  201. __kmp_assign_root_init_mask();
  202. return __kmp_aux_set_affinity(mask);
  203. #endif
  204. }
  205. int FTN_STDCALL FTN_GET_AFFINITY(void **mask) {
  206. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  207. return -1;
  208. #else
  209. if (!TCR_4(__kmp_init_middle)) {
  210. __kmp_middle_initialize();
  211. }
  212. __kmp_assign_root_init_mask();
  213. int gtid = __kmp_get_gtid();
  214. if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 && __kmp_affin_reset) {
  215. __kmp_reset_root_init_mask(gtid);
  216. }
  217. return __kmp_aux_get_affinity(mask);
  218. #endif
  219. }
  220. int FTN_STDCALL FTN_GET_AFFINITY_MAX_PROC(void) {
  221. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  222. return 0;
  223. #else
  224. // We really only NEED serial initialization here.
  225. if (!TCR_4(__kmp_init_middle)) {
  226. __kmp_middle_initialize();
  227. }
  228. __kmp_assign_root_init_mask();
  229. return __kmp_aux_get_affinity_max_proc();
  230. #endif
  231. }
  232. void FTN_STDCALL FTN_CREATE_AFFINITY_MASK(void **mask) {
  233. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  234. *mask = NULL;
  235. #else
  236. // We really only NEED serial initialization here.
  237. kmp_affin_mask_t *mask_internals;
  238. if (!TCR_4(__kmp_init_middle)) {
  239. __kmp_middle_initialize();
  240. }
  241. __kmp_assign_root_init_mask();
  242. mask_internals = __kmp_affinity_dispatch->allocate_mask();
  243. KMP_CPU_ZERO(mask_internals);
  244. *mask = mask_internals;
  245. #endif
  246. }
  247. void FTN_STDCALL FTN_DESTROY_AFFINITY_MASK(void **mask) {
  248. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  249. // Nothing
  250. #else
  251. // We really only NEED serial initialization here.
  252. kmp_affin_mask_t *mask_internals;
  253. if (!TCR_4(__kmp_init_middle)) {
  254. __kmp_middle_initialize();
  255. }
  256. __kmp_assign_root_init_mask();
  257. if (__kmp_env_consistency_check) {
  258. if (*mask == NULL) {
  259. KMP_FATAL(AffinityInvalidMask, "kmp_destroy_affinity_mask");
  260. }
  261. }
  262. mask_internals = (kmp_affin_mask_t *)(*mask);
  263. __kmp_affinity_dispatch->deallocate_mask(mask_internals);
  264. *mask = NULL;
  265. #endif
  266. }
  267. int FTN_STDCALL FTN_SET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
  268. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  269. return -1;
  270. #else
  271. if (!TCR_4(__kmp_init_middle)) {
  272. __kmp_middle_initialize();
  273. }
  274. __kmp_assign_root_init_mask();
  275. return __kmp_aux_set_affinity_mask_proc(KMP_DEREF proc, mask);
  276. #endif
  277. }
  278. int FTN_STDCALL FTN_UNSET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
  279. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  280. return -1;
  281. #else
  282. if (!TCR_4(__kmp_init_middle)) {
  283. __kmp_middle_initialize();
  284. }
  285. __kmp_assign_root_init_mask();
  286. return __kmp_aux_unset_affinity_mask_proc(KMP_DEREF proc, mask);
  287. #endif
  288. }
  289. int FTN_STDCALL FTN_GET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
  290. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  291. return -1;
  292. #else
  293. if (!TCR_4(__kmp_init_middle)) {
  294. __kmp_middle_initialize();
  295. }
  296. __kmp_assign_root_init_mask();
  297. return __kmp_aux_get_affinity_mask_proc(KMP_DEREF proc, mask);
  298. #endif
  299. }
  300. /* ------------------------------------------------------------------------ */
  301. /* sets the requested number of threads for the next parallel region */
  302. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NUM_THREADS)(int KMP_DEREF arg) {
  303. #ifdef KMP_STUB
  304. // Nothing.
  305. #else
  306. __kmp_set_num_threads(KMP_DEREF arg, __kmp_entry_gtid());
  307. #endif
  308. }
  309. /* returns the number of threads in current team */
  310. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_THREADS)(void) {
  311. #ifdef KMP_STUB
  312. return 1;
  313. #else
  314. // __kmpc_bound_num_threads initializes the library if needed
  315. return __kmpc_bound_num_threads(NULL);
  316. #endif
  317. }
  318. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_THREADS)(void) {
  319. #ifdef KMP_STUB
  320. return 1;
  321. #else
  322. int gtid;
  323. kmp_info_t *thread;
  324. if (!TCR_4(__kmp_init_middle)) {
  325. __kmp_middle_initialize();
  326. }
  327. gtid = __kmp_entry_gtid();
  328. thread = __kmp_threads[gtid];
  329. #if KMP_AFFINITY_SUPPORTED
  330. if (thread->th.th_team->t.t_level == 0 && !__kmp_affin_reset) {
  331. __kmp_assign_root_init_mask();
  332. }
  333. #endif
  334. // return thread -> th.th_team -> t.t_current_task[
  335. // thread->th.th_info.ds.ds_tid ] -> icvs.nproc;
  336. return thread->th.th_current_task->td_icvs.nproc;
  337. #endif
  338. }
  339. int FTN_STDCALL FTN_CONTROL_TOOL(int command, int modifier, void *arg) {
  340. #if defined(KMP_STUB) || !OMPT_SUPPORT
  341. return -2;
  342. #else
  343. OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());
  344. if (!TCR_4(__kmp_init_middle)) {
  345. return -2;
  346. }
  347. kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];
  348. ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);
  349. parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);
  350. int ret = __kmp_control_tool(command, modifier, arg);
  351. parent_task_info->frame.enter_frame.ptr = 0;
  352. return ret;
  353. #endif
  354. }
  355. /* OpenMP 5.0 Memory Management support */
  356. omp_allocator_handle_t FTN_STDCALL
  357. FTN_INIT_ALLOCATOR(omp_memspace_handle_t KMP_DEREF m, int KMP_DEREF ntraits,
  358. omp_alloctrait_t tr[]) {
  359. #ifdef KMP_STUB
  360. return NULL;
  361. #else
  362. return __kmpc_init_allocator(__kmp_entry_gtid(), KMP_DEREF m,
  363. KMP_DEREF ntraits, tr);
  364. #endif
  365. }
  366. void FTN_STDCALL FTN_DESTROY_ALLOCATOR(omp_allocator_handle_t al) {
  367. #ifndef KMP_STUB
  368. __kmpc_destroy_allocator(__kmp_entry_gtid(), al);
  369. #endif
  370. }
  371. void FTN_STDCALL FTN_SET_DEFAULT_ALLOCATOR(omp_allocator_handle_t al) {
  372. #ifndef KMP_STUB
  373. __kmpc_set_default_allocator(__kmp_entry_gtid(), al);
  374. #endif
  375. }
  376. omp_allocator_handle_t FTN_STDCALL FTN_GET_DEFAULT_ALLOCATOR(void) {
  377. #ifdef KMP_STUB
  378. return NULL;
  379. #else
  380. return __kmpc_get_default_allocator(__kmp_entry_gtid());
  381. #endif
  382. }
  383. /* OpenMP 5.0 affinity format support */
  384. #ifndef KMP_STUB
  385. static void __kmp_fortran_strncpy_truncate(char *buffer, size_t buf_size,
  386. char const *csrc, size_t csrc_size) {
  387. size_t capped_src_size = csrc_size;
  388. if (csrc_size >= buf_size) {
  389. capped_src_size = buf_size - 1;
  390. }
  391. KMP_STRNCPY_S(buffer, buf_size, csrc, capped_src_size);
  392. if (csrc_size >= buf_size) {
  393. KMP_DEBUG_ASSERT(buffer[buf_size - 1] == '\0');
  394. buffer[buf_size - 1] = csrc[buf_size - 1];
  395. } else {
  396. for (size_t i = csrc_size; i < buf_size; ++i)
  397. buffer[i] = ' ';
  398. }
  399. }
  400. // Convert a Fortran string to a C string by adding null byte
  401. class ConvertedString {
  402. char *buf;
  403. kmp_info_t *th;
  404. public:
  405. ConvertedString(char const *fortran_str, size_t size) {
  406. th = __kmp_get_thread();
  407. buf = (char *)__kmp_thread_malloc(th, size + 1);
  408. KMP_STRNCPY_S(buf, size + 1, fortran_str, size);
  409. buf[size] = '\0';
  410. }
  411. ~ConvertedString() { __kmp_thread_free(th, buf); }
  412. const char *get() const { return buf; }
  413. };
  414. #endif // KMP_STUB
  415. /*
  416. * Set the value of the affinity-format-var ICV on the current device to the
  417. * format specified in the argument.
  418. */
  419. void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_SET_AFFINITY_FORMAT)(
  420. char const *format, size_t size) {
  421. #ifdef KMP_STUB
  422. return;
  423. #else
  424. if (!__kmp_init_serial) {
  425. __kmp_serial_initialize();
  426. }
  427. ConvertedString cformat(format, size);
  428. // Since the __kmp_affinity_format variable is a C string, do not
  429. // use the fortran strncpy function
  430. __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE,
  431. cformat.get(), KMP_STRLEN(cformat.get()));
  432. #endif
  433. }
  434. /*
  435. * Returns the number of characters required to hold the entire affinity format
  436. * specification (not including null byte character) and writes the value of the
  437. * affinity-format-var ICV on the current device to buffer. If the return value
  438. * is larger than size, the affinity format specification is truncated.
  439. */
  440. size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_GET_AFFINITY_FORMAT)(
  441. char *buffer, size_t size) {
  442. #ifdef KMP_STUB
  443. return 0;
  444. #else
  445. size_t format_size;
  446. if (!__kmp_init_serial) {
  447. __kmp_serial_initialize();
  448. }
  449. format_size = KMP_STRLEN(__kmp_affinity_format);
  450. if (buffer && size) {
  451. __kmp_fortran_strncpy_truncate(buffer, size, __kmp_affinity_format,
  452. format_size);
  453. }
  454. return format_size;
  455. #endif
  456. }
  457. /*
  458. * Prints the thread affinity information of the current thread in the format
  459. * specified by the format argument. If the format is NULL or a zero-length
  460. * string, the value of the affinity-format-var ICV is used.
  461. */
  462. void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_DISPLAY_AFFINITY)(
  463. char const *format, size_t size) {
  464. #ifdef KMP_STUB
  465. return;
  466. #else
  467. int gtid;
  468. if (!TCR_4(__kmp_init_middle)) {
  469. __kmp_middle_initialize();
  470. }
  471. __kmp_assign_root_init_mask();
  472. gtid = __kmp_get_gtid();
  473. #if KMP_AFFINITY_SUPPORTED
  474. if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 && __kmp_affin_reset) {
  475. __kmp_reset_root_init_mask(gtid);
  476. }
  477. #endif
  478. ConvertedString cformat(format, size);
  479. __kmp_aux_display_affinity(gtid, cformat.get());
  480. #endif
  481. }
  482. /*
  483. * Returns the number of characters required to hold the entire affinity format
  484. * specification (not including null byte) and prints the thread affinity
  485. * information of the current thread into the character string buffer with the
  486. * size of size in the format specified by the format argument. If the format is
  487. * NULL or a zero-length string, the value of the affinity-format-var ICV is
  488. * used. The buffer must be allocated prior to calling the routine. If the
  489. * return value is larger than size, the affinity format specification is
  490. * truncated.
  491. */
  492. size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_CAPTURE_AFFINITY)(
  493. char *buffer, char const *format, size_t buf_size, size_t for_size) {
  494. #if defined(KMP_STUB)
  495. return 0;
  496. #else
  497. int gtid;
  498. size_t num_required;
  499. kmp_str_buf_t capture_buf;
  500. if (!TCR_4(__kmp_init_middle)) {
  501. __kmp_middle_initialize();
  502. }
  503. __kmp_assign_root_init_mask();
  504. gtid = __kmp_get_gtid();
  505. #if KMP_AFFINITY_SUPPORTED
  506. if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 && __kmp_affin_reset) {
  507. __kmp_reset_root_init_mask(gtid);
  508. }
  509. #endif
  510. __kmp_str_buf_init(&capture_buf);
  511. ConvertedString cformat(format, for_size);
  512. num_required = __kmp_aux_capture_affinity(gtid, cformat.get(), &capture_buf);
  513. if (buffer && buf_size) {
  514. __kmp_fortran_strncpy_truncate(buffer, buf_size, capture_buf.str,
  515. capture_buf.used);
  516. }
  517. __kmp_str_buf_free(&capture_buf);
  518. return num_required;
  519. #endif
  520. }
  521. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
  522. #ifdef KMP_STUB
  523. return 0;
  524. #else
  525. int gtid;
  526. #if KMP_OS_DARWIN || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
  527. KMP_OS_HURD || KMP_OS_OPENBSD
  528. gtid = __kmp_entry_gtid();
  529. #elif KMP_OS_WINDOWS
  530. if (!__kmp_init_parallel ||
  531. (gtid = (int)((kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key))) ==
  532. 0) {
  533. // Either library isn't initialized or thread is not registered
  534. // 0 is the correct TID in this case
  535. return 0;
  536. }
  537. --gtid; // We keep (gtid+1) in TLS
  538. #elif KMP_OS_LINUX
  539. #ifdef KMP_TDATA_GTID
  540. if (__kmp_gtid_mode >= 3) {
  541. if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
  542. return 0;
  543. }
  544. } else {
  545. #endif
  546. if (!__kmp_init_parallel ||
  547. (gtid = (int)((kmp_intptr_t)(
  548. pthread_getspecific(__kmp_gtid_threadprivate_key)))) == 0) {
  549. return 0;
  550. }
  551. --gtid;
  552. #ifdef KMP_TDATA_GTID
  553. }
  554. #endif
  555. #else
  556. #error Unknown or unsupported OS
  557. #endif
  558. return __kmp_tid_from_gtid(gtid);
  559. #endif
  560. }
  561. int FTN_STDCALL FTN_GET_NUM_KNOWN_THREADS(void) {
  562. #ifdef KMP_STUB
  563. return 1;
  564. #else
  565. if (!__kmp_init_serial) {
  566. __kmp_serial_initialize();
  567. }
  568. /* NOTE: this is not syncronized, so it can change at any moment */
  569. /* NOTE: this number also includes threads preallocated in hot-teams */
  570. return TCR_4(__kmp_nth);
  571. #endif
  572. }
  573. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)(void) {
  574. #ifdef KMP_STUB
  575. return 1;
  576. #else
  577. if (!TCR_4(__kmp_init_middle)) {
  578. __kmp_middle_initialize();
  579. }
  580. #if KMP_AFFINITY_SUPPORTED
  581. if (!__kmp_affin_reset) {
  582. // only bind root here if its affinity reset is not requested
  583. int gtid = __kmp_entry_gtid();
  584. kmp_info_t *thread = __kmp_threads[gtid];
  585. if (thread->th.th_team->t.t_level == 0) {
  586. __kmp_assign_root_init_mask();
  587. }
  588. }
  589. #endif
  590. return __kmp_avail_proc;
  591. #endif
  592. }
  593. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NESTED)(int KMP_DEREF flag) {
  594. #ifdef KMP_STUB
  595. __kmps_set_nested(KMP_DEREF flag);
  596. #else
  597. kmp_info_t *thread;
  598. /* For the thread-private internal controls implementation */
  599. thread = __kmp_entry_thread();
  600. KMP_INFORM(APIDeprecated, "omp_set_nested", "omp_set_max_active_levels");
  601. __kmp_save_internal_controls(thread);
  602. // Somewhat arbitrarily decide where to get a value for max_active_levels
  603. int max_active_levels = get__max_active_levels(thread);
  604. if (max_active_levels == 1)
  605. max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;
  606. set__max_active_levels(thread, (KMP_DEREF flag) ? max_active_levels : 1);
  607. #endif
  608. }
  609. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NESTED)(void) {
  610. #ifdef KMP_STUB
  611. return __kmps_get_nested();
  612. #else
  613. kmp_info_t *thread;
  614. thread = __kmp_entry_thread();
  615. KMP_INFORM(APIDeprecated, "omp_get_nested", "omp_get_max_active_levels");
  616. return get__max_active_levels(thread) > 1;
  617. #endif
  618. }
  619. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DYNAMIC)(int KMP_DEREF flag) {
  620. #ifdef KMP_STUB
  621. __kmps_set_dynamic(KMP_DEREF flag ? TRUE : FALSE);
  622. #else
  623. kmp_info_t *thread;
  624. /* For the thread-private implementation of the internal controls */
  625. thread = __kmp_entry_thread();
  626. // !!! What if foreign thread calls it?
  627. __kmp_save_internal_controls(thread);
  628. set__dynamic(thread, KMP_DEREF flag ? true : false);
  629. #endif
  630. }
  631. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DYNAMIC)(void) {
  632. #ifdef KMP_STUB
  633. return __kmps_get_dynamic();
  634. #else
  635. kmp_info_t *thread;
  636. thread = __kmp_entry_thread();
  637. return get__dynamic(thread);
  638. #endif
  639. }
  640. int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_PARALLEL)(void) {
  641. #ifdef KMP_STUB
  642. return 0;
  643. #else
  644. kmp_info_t *th = __kmp_entry_thread();
  645. if (th->th.th_teams_microtask) {
  646. // AC: r_in_parallel does not work inside teams construct where real
  647. // parallel is inactive, but all threads have same root, so setting it in
  648. // one team affects other teams.
  649. // The solution is to use per-team nesting level
  650. return (th->th.th_team->t.t_active_level ? 1 : 0);
  651. } else
  652. return (th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE);
  653. #endif
  654. }
  655. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_SCHEDULE)(kmp_sched_t KMP_DEREF kind,
  656. int KMP_DEREF modifier) {
  657. #ifdef KMP_STUB
  658. __kmps_set_schedule(KMP_DEREF kind, KMP_DEREF modifier);
  659. #else
  660. /* TO DO: For the per-task implementation of the internal controls */
  661. __kmp_set_schedule(__kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier);
  662. #endif
  663. }
  664. void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_SCHEDULE)(kmp_sched_t *kind,
  665. int *modifier) {
  666. #ifdef KMP_STUB
  667. __kmps_get_schedule(kind, modifier);
  668. #else
  669. /* TO DO: For the per-task implementation of the internal controls */
  670. __kmp_get_schedule(__kmp_entry_gtid(), kind, modifier);
  671. #endif
  672. }
  673. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)(int KMP_DEREF arg) {
  674. #ifdef KMP_STUB
  675. // Nothing.
  676. #else
  677. /* TO DO: We want per-task implementation of this internal control */
  678. __kmp_set_max_active_levels(__kmp_entry_gtid(), KMP_DEREF arg);
  679. #endif
  680. }
  681. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)(void) {
  682. #ifdef KMP_STUB
  683. return 0;
  684. #else
  685. /* TO DO: We want per-task implementation of this internal control */
  686. if (!TCR_4(__kmp_init_middle)) {
  687. __kmp_middle_initialize();
  688. }
  689. return __kmp_get_max_active_levels(__kmp_entry_gtid());
  690. #endif
  691. }
  692. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)(void) {
  693. #ifdef KMP_STUB
  694. return 0; // returns 0 if it is called from the sequential part of the program
  695. #else
  696. /* TO DO: For the per-task implementation of the internal controls */
  697. return __kmp_entry_thread()->th.th_team->t.t_active_level;
  698. #endif
  699. }
  700. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_LEVEL)(void) {
  701. #ifdef KMP_STUB
  702. return 0; // returns 0 if it is called from the sequential part of the program
  703. #else
  704. /* TO DO: For the per-task implementation of the internal controls */
  705. return __kmp_entry_thread()->th.th_team->t.t_level;
  706. #endif
  707. }
  708. int FTN_STDCALL
  709. KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)(int KMP_DEREF level) {
  710. #ifdef KMP_STUB
  711. return (KMP_DEREF level) ? (-1) : (0);
  712. #else
  713. return __kmp_get_ancestor_thread_num(__kmp_entry_gtid(), KMP_DEREF level);
  714. #endif
  715. }
  716. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)(int KMP_DEREF level) {
  717. #ifdef KMP_STUB
  718. return (KMP_DEREF level) ? (-1) : (1);
  719. #else
  720. return __kmp_get_team_size(__kmp_entry_gtid(), KMP_DEREF level);
  721. #endif
  722. }
  723. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)(void) {
  724. #ifdef KMP_STUB
  725. return 1; // TO DO: clarify whether it returns 1 or 0?
  726. #else
  727. int gtid;
  728. kmp_info_t *thread;
  729. if (!__kmp_init_serial) {
  730. __kmp_serial_initialize();
  731. }
  732. gtid = __kmp_entry_gtid();
  733. thread = __kmp_threads[gtid];
  734. return thread->th.th_current_task->td_icvs.thread_limit;
  735. #endif
  736. }
  737. int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_FINAL)(void) {
  738. #ifdef KMP_STUB
  739. return 0; // TO DO: clarify whether it returns 1 or 0?
  740. #else
  741. if (!TCR_4(__kmp_init_parallel)) {
  742. return 0;
  743. }
  744. return __kmp_entry_thread()->th.th_current_task->td_flags.final;
  745. #endif
  746. }
  747. kmp_proc_bind_t FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PROC_BIND)(void) {
  748. #ifdef KMP_STUB
  749. return __kmps_get_proc_bind();
  750. #else
  751. return get__proc_bind(__kmp_entry_thread());
  752. #endif
  753. }
  754. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PLACES)(void) {
  755. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  756. return 0;
  757. #else
  758. if (!TCR_4(__kmp_init_middle)) {
  759. __kmp_middle_initialize();
  760. }
  761. if (!KMP_AFFINITY_CAPABLE())
  762. return 0;
  763. if (!__kmp_affin_reset) {
  764. // only bind root here if its affinity reset is not requested
  765. int gtid = __kmp_entry_gtid();
  766. kmp_info_t *thread = __kmp_threads[gtid];
  767. if (thread->th.th_team->t.t_level == 0) {
  768. __kmp_assign_root_init_mask();
  769. }
  770. }
  771. return __kmp_affinity_num_masks;
  772. #endif
  773. }
  774. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM_PROCS)(int place_num) {
  775. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  776. return 0;
  777. #else
  778. int i;
  779. int retval = 0;
  780. if (!TCR_4(__kmp_init_middle)) {
  781. __kmp_middle_initialize();
  782. }
  783. if (!KMP_AFFINITY_CAPABLE())
  784. return 0;
  785. if (!__kmp_affin_reset) {
  786. // only bind root here if its affinity reset is not requested
  787. int gtid = __kmp_entry_gtid();
  788. kmp_info_t *thread = __kmp_threads[gtid];
  789. if (thread->th.th_team->t.t_level == 0) {
  790. __kmp_assign_root_init_mask();
  791. }
  792. }
  793. if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
  794. return 0;
  795. kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
  796. KMP_CPU_SET_ITERATE(i, mask) {
  797. if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
  798. (!KMP_CPU_ISSET(i, mask))) {
  799. continue;
  800. }
  801. ++retval;
  802. }
  803. return retval;
  804. #endif
  805. }
  806. void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_PROC_IDS)(int place_num,
  807. int *ids) {
  808. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  809. // Nothing.
  810. #else
  811. int i, j;
  812. if (!TCR_4(__kmp_init_middle)) {
  813. __kmp_middle_initialize();
  814. }
  815. if (!KMP_AFFINITY_CAPABLE())
  816. return;
  817. if (!__kmp_affin_reset) {
  818. // only bind root here if its affinity reset is not requested
  819. int gtid = __kmp_entry_gtid();
  820. kmp_info_t *thread = __kmp_threads[gtid];
  821. if (thread->th.th_team->t.t_level == 0) {
  822. __kmp_assign_root_init_mask();
  823. }
  824. }
  825. if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
  826. return;
  827. kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
  828. j = 0;
  829. KMP_CPU_SET_ITERATE(i, mask) {
  830. if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
  831. (!KMP_CPU_ISSET(i, mask))) {
  832. continue;
  833. }
  834. ids[j++] = i;
  835. }
  836. #endif
  837. }
  838. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM)(void) {
  839. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  840. return -1;
  841. #else
  842. int gtid;
  843. kmp_info_t *thread;
  844. if (!TCR_4(__kmp_init_middle)) {
  845. __kmp_middle_initialize();
  846. }
  847. if (!KMP_AFFINITY_CAPABLE())
  848. return -1;
  849. gtid = __kmp_entry_gtid();
  850. thread = __kmp_thread_from_gtid(gtid);
  851. if (thread->th.th_team->t.t_level == 0 && !__kmp_affin_reset) {
  852. __kmp_assign_root_init_mask();
  853. }
  854. if (thread->th.th_current_place < 0)
  855. return -1;
  856. return thread->th.th_current_place;
  857. #endif
  858. }
  859. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PARTITION_NUM_PLACES)(void) {
  860. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  861. return 0;
  862. #else
  863. int gtid, num_places, first_place, last_place;
  864. kmp_info_t *thread;
  865. if (!TCR_4(__kmp_init_middle)) {
  866. __kmp_middle_initialize();
  867. }
  868. if (!KMP_AFFINITY_CAPABLE())
  869. return 0;
  870. gtid = __kmp_entry_gtid();
  871. thread = __kmp_thread_from_gtid(gtid);
  872. if (thread->th.th_team->t.t_level == 0 && !__kmp_affin_reset) {
  873. __kmp_assign_root_init_mask();
  874. }
  875. first_place = thread->th.th_first_place;
  876. last_place = thread->th.th_last_place;
  877. if (first_place < 0 || last_place < 0)
  878. return 0;
  879. if (first_place <= last_place)
  880. num_places = last_place - first_place + 1;
  881. else
  882. num_places = __kmp_affinity_num_masks - first_place + last_place + 1;
  883. return num_places;
  884. #endif
  885. }
  886. void FTN_STDCALL
  887. KMP_EXPAND_NAME(FTN_GET_PARTITION_PLACE_NUMS)(int *place_nums) {
  888. #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
  889. // Nothing.
  890. #else
  891. int i, gtid, place_num, first_place, last_place, start, end;
  892. kmp_info_t *thread;
  893. if (!TCR_4(__kmp_init_middle)) {
  894. __kmp_middle_initialize();
  895. }
  896. if (!KMP_AFFINITY_CAPABLE())
  897. return;
  898. gtid = __kmp_entry_gtid();
  899. thread = __kmp_thread_from_gtid(gtid);
  900. if (thread->th.th_team->t.t_level == 0 && !__kmp_affin_reset) {
  901. __kmp_assign_root_init_mask();
  902. }
  903. first_place = thread->th.th_first_place;
  904. last_place = thread->th.th_last_place;
  905. if (first_place < 0 || last_place < 0)
  906. return;
  907. if (first_place <= last_place) {
  908. start = first_place;
  909. end = last_place;
  910. } else {
  911. start = last_place;
  912. end = first_place;
  913. }
  914. for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
  915. place_nums[i] = place_num;
  916. }
  917. #endif
  918. }
  919. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {
  920. #ifdef KMP_STUB
  921. return 1;
  922. #else
  923. return __kmp_aux_get_num_teams();
  924. #endif
  925. }
  926. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {
  927. #ifdef KMP_STUB
  928. return 0;
  929. #else
  930. return __kmp_aux_get_team_num();
  931. #endif
  932. }
  933. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)(void) {
  934. #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
  935. return 0;
  936. #else
  937. return __kmp_entry_thread()->th.th_current_task->td_icvs.default_device;
  938. #endif
  939. }
  940. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
  941. #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
  942. // Nothing.
  943. #else
  944. __kmp_entry_thread()->th.th_current_task->td_icvs.default_device =
  945. KMP_DEREF arg;
  946. #endif
  947. }
  948. // Get number of NON-HOST devices.
  949. // libomptarget, if loaded, provides this function in api.cpp.
  950. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void)
  951. KMP_WEAK_ATTRIBUTE_EXTERNAL;
  952. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) {
  953. #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
  954. return 0;
  955. #else
  956. int (*fptr)();
  957. if ((*(void **)(&fptr) = KMP_DLSYM("__tgt_get_num_devices"))) {
  958. return (*fptr)();
  959. } else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) {
  960. return (*fptr)();
  961. } else if ((*(void **)(&fptr) = KMP_DLSYM("_Offload_number_of_devices"))) {
  962. return (*fptr)();
  963. } else { // liboffload & libomptarget don't exist
  964. return 0;
  965. }
  966. #endif // KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB)
  967. }
  968. // This function always returns true when called on host device.
  969. // Compiler/libomptarget should handle when it is called inside target region.
  970. int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void)
  971. KMP_WEAK_ATTRIBUTE_EXTERNAL;
  972. int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {
  973. return 1; // This is the host
  974. }
  975. // libomptarget, if loaded, provides this function
  976. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void)
  977. KMP_WEAK_ATTRIBUTE_EXTERNAL;
  978. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) {
  979. // same as omp_get_num_devices()
  980. return KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)();
  981. }
  982. #if defined(KMP_STUB)
  983. // Entries for stubs library
  984. // As all *target* functions are C-only parameters always passed by value
  985. void *FTN_STDCALL FTN_TARGET_ALLOC(size_t size, int device_num) { return 0; }
  986. void FTN_STDCALL FTN_TARGET_FREE(void *device_ptr, int device_num) {}
  987. int FTN_STDCALL FTN_TARGET_IS_PRESENT(void *ptr, int device_num) { return 0; }
  988. int FTN_STDCALL FTN_TARGET_MEMCPY(void *dst, void *src, size_t length,
  989. size_t dst_offset, size_t src_offset,
  990. int dst_device, int src_device) {
  991. return -1;
  992. }
  993. int FTN_STDCALL FTN_TARGET_MEMCPY_RECT(
  994. void *dst, void *src, size_t element_size, int num_dims,
  995. const size_t *volume, const size_t *dst_offsets, const size_t *src_offsets,
  996. const size_t *dst_dimensions, const size_t *src_dimensions, int dst_device,
  997. int src_device) {
  998. return -1;
  999. }
  1000. int FTN_STDCALL FTN_TARGET_ASSOCIATE_PTR(void *host_ptr, void *device_ptr,
  1001. size_t size, size_t device_offset,
  1002. int device_num) {
  1003. return -1;
  1004. }
  1005. int FTN_STDCALL FTN_TARGET_DISASSOCIATE_PTR(void *host_ptr, int device_num) {
  1006. return -1;
  1007. }
  1008. #endif // defined(KMP_STUB)
  1009. #ifdef KMP_STUB
  1010. typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;
  1011. #endif /* KMP_STUB */
  1012. #if KMP_USE_DYNAMIC_LOCK
  1013. void FTN_STDCALL FTN_INIT_LOCK_WITH_HINT(void **user_lock,
  1014. uintptr_t KMP_DEREF hint) {
  1015. #ifdef KMP_STUB
  1016. *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
  1017. #else
  1018. int gtid = __kmp_entry_gtid();
  1019. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1020. OMPT_STORE_RETURN_ADDRESS(gtid);
  1021. #endif
  1022. __kmpc_init_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
  1023. #endif
  1024. }
  1025. void FTN_STDCALL FTN_INIT_NEST_LOCK_WITH_HINT(void **user_lock,
  1026. uintptr_t KMP_DEREF hint) {
  1027. #ifdef KMP_STUB
  1028. *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
  1029. #else
  1030. int gtid = __kmp_entry_gtid();
  1031. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1032. OMPT_STORE_RETURN_ADDRESS(gtid);
  1033. #endif
  1034. __kmpc_init_nest_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
  1035. #endif
  1036. }
  1037. #endif
  1038. /* initialize the lock */
  1039. void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_LOCK)(void **user_lock) {
  1040. #ifdef KMP_STUB
  1041. *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
  1042. #else
  1043. int gtid = __kmp_entry_gtid();
  1044. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1045. OMPT_STORE_RETURN_ADDRESS(gtid);
  1046. #endif
  1047. __kmpc_init_lock(NULL, gtid, user_lock);
  1048. #endif
  1049. }
  1050. /* initialize the lock */
  1051. void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)(void **user_lock) {
  1052. #ifdef KMP_STUB
  1053. *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
  1054. #else
  1055. int gtid = __kmp_entry_gtid();
  1056. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1057. OMPT_STORE_RETURN_ADDRESS(gtid);
  1058. #endif
  1059. __kmpc_init_nest_lock(NULL, gtid, user_lock);
  1060. #endif
  1061. }
  1062. void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_LOCK)(void **user_lock) {
  1063. #ifdef KMP_STUB
  1064. *((kmp_stub_lock_t *)user_lock) = UNINIT;
  1065. #else
  1066. int gtid = __kmp_entry_gtid();
  1067. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1068. OMPT_STORE_RETURN_ADDRESS(gtid);
  1069. #endif
  1070. __kmpc_destroy_lock(NULL, gtid, user_lock);
  1071. #endif
  1072. }
  1073. void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)(void **user_lock) {
  1074. #ifdef KMP_STUB
  1075. *((kmp_stub_lock_t *)user_lock) = UNINIT;
  1076. #else
  1077. int gtid = __kmp_entry_gtid();
  1078. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1079. OMPT_STORE_RETURN_ADDRESS(gtid);
  1080. #endif
  1081. __kmpc_destroy_nest_lock(NULL, gtid, user_lock);
  1082. #endif
  1083. }
  1084. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_LOCK)(void **user_lock) {
  1085. #ifdef KMP_STUB
  1086. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1087. // TODO: Issue an error.
  1088. }
  1089. if (*((kmp_stub_lock_t *)user_lock) != UNLOCKED) {
  1090. // TODO: Issue an error.
  1091. }
  1092. *((kmp_stub_lock_t *)user_lock) = LOCKED;
  1093. #else
  1094. int gtid = __kmp_entry_gtid();
  1095. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1096. OMPT_STORE_RETURN_ADDRESS(gtid);
  1097. #endif
  1098. __kmpc_set_lock(NULL, gtid, user_lock);
  1099. #endif
  1100. }
  1101. void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)(void **user_lock) {
  1102. #ifdef KMP_STUB
  1103. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1104. // TODO: Issue an error.
  1105. }
  1106. (*((int *)user_lock))++;
  1107. #else
  1108. int gtid = __kmp_entry_gtid();
  1109. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1110. OMPT_STORE_RETURN_ADDRESS(gtid);
  1111. #endif
  1112. __kmpc_set_nest_lock(NULL, gtid, user_lock);
  1113. #endif
  1114. }
  1115. void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_LOCK)(void **user_lock) {
  1116. #ifdef KMP_STUB
  1117. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1118. // TODO: Issue an error.
  1119. }
  1120. if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
  1121. // TODO: Issue an error.
  1122. }
  1123. *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
  1124. #else
  1125. int gtid = __kmp_entry_gtid();
  1126. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1127. OMPT_STORE_RETURN_ADDRESS(gtid);
  1128. #endif
  1129. __kmpc_unset_lock(NULL, gtid, user_lock);
  1130. #endif
  1131. }
  1132. void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)(void **user_lock) {
  1133. #ifdef KMP_STUB
  1134. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1135. // TODO: Issue an error.
  1136. }
  1137. if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
  1138. // TODO: Issue an error.
  1139. }
  1140. (*((int *)user_lock))--;
  1141. #else
  1142. int gtid = __kmp_entry_gtid();
  1143. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1144. OMPT_STORE_RETURN_ADDRESS(gtid);
  1145. #endif
  1146. __kmpc_unset_nest_lock(NULL, gtid, user_lock);
  1147. #endif
  1148. }
  1149. int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_LOCK)(void **user_lock) {
  1150. #ifdef KMP_STUB
  1151. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1152. // TODO: Issue an error.
  1153. }
  1154. if (*((kmp_stub_lock_t *)user_lock) == LOCKED) {
  1155. return 0;
  1156. }
  1157. *((kmp_stub_lock_t *)user_lock) = LOCKED;
  1158. return 1;
  1159. #else
  1160. int gtid = __kmp_entry_gtid();
  1161. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1162. OMPT_STORE_RETURN_ADDRESS(gtid);
  1163. #endif
  1164. return __kmpc_test_lock(NULL, gtid, user_lock);
  1165. #endif
  1166. }
  1167. int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)(void **user_lock) {
  1168. #ifdef KMP_STUB
  1169. if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
  1170. // TODO: Issue an error.
  1171. }
  1172. return ++(*((int *)user_lock));
  1173. #else
  1174. int gtid = __kmp_entry_gtid();
  1175. #if OMPT_SUPPORT && OMPT_OPTIONAL
  1176. OMPT_STORE_RETURN_ADDRESS(gtid);
  1177. #endif
  1178. return __kmpc_test_nest_lock(NULL, gtid, user_lock);
  1179. #endif
  1180. }
  1181. double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTIME)(void) {
  1182. #ifdef KMP_STUB
  1183. return __kmps_get_wtime();
  1184. #else
  1185. double data;
  1186. #if !KMP_OS_LINUX
  1187. // We don't need library initialization to get the time on Linux* OS. The
  1188. // routine can be used to measure library initialization time on Linux* OS now
  1189. if (!__kmp_init_serial) {
  1190. __kmp_serial_initialize();
  1191. }
  1192. #endif
  1193. __kmp_elapsed(&data);
  1194. return data;
  1195. #endif
  1196. }
  1197. double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTICK)(void) {
  1198. #ifdef KMP_STUB
  1199. return __kmps_get_wtick();
  1200. #else
  1201. double data;
  1202. if (!__kmp_init_serial) {
  1203. __kmp_serial_initialize();
  1204. }
  1205. __kmp_elapsed_tick(&data);
  1206. return data;
  1207. #endif
  1208. }
  1209. /* ------------------------------------------------------------------------ */
  1210. void *FTN_STDCALL FTN_MALLOC(size_t KMP_DEREF size) {
  1211. // kmpc_malloc initializes the library if needed
  1212. return kmpc_malloc(KMP_DEREF size);
  1213. }
  1214. void *FTN_STDCALL FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,
  1215. size_t KMP_DEREF alignment) {
  1216. // kmpc_aligned_malloc initializes the library if needed
  1217. return kmpc_aligned_malloc(KMP_DEREF size, KMP_DEREF alignment);
  1218. }
  1219. void *FTN_STDCALL FTN_CALLOC(size_t KMP_DEREF nelem, size_t KMP_DEREF elsize) {
  1220. // kmpc_calloc initializes the library if needed
  1221. return kmpc_calloc(KMP_DEREF nelem, KMP_DEREF elsize);
  1222. }
  1223. void *FTN_STDCALL FTN_REALLOC(void *KMP_DEREF ptr, size_t KMP_DEREF size) {
  1224. // kmpc_realloc initializes the library if needed
  1225. return kmpc_realloc(KMP_DEREF ptr, KMP_DEREF size);
  1226. }
  1227. void FTN_STDCALL FTN_KFREE(void *KMP_DEREF ptr) {
  1228. // does nothing if the library is not initialized
  1229. kmpc_free(KMP_DEREF ptr);
  1230. }
  1231. void FTN_STDCALL FTN_SET_WARNINGS_ON(void) {
  1232. #ifndef KMP_STUB
  1233. __kmp_generate_warnings = kmp_warnings_explicit;
  1234. #endif
  1235. }
  1236. void FTN_STDCALL FTN_SET_WARNINGS_OFF(void) {
  1237. #ifndef KMP_STUB
  1238. __kmp_generate_warnings = FALSE;
  1239. #endif
  1240. }
  1241. void FTN_STDCALL FTN_SET_DEFAULTS(char const *str
  1242. #ifndef PASS_ARGS_BY_VALUE
  1243. ,
  1244. int len
  1245. #endif
  1246. ) {
  1247. #ifndef KMP_STUB
  1248. #ifdef PASS_ARGS_BY_VALUE
  1249. int len = (int)KMP_STRLEN(str);
  1250. #endif
  1251. __kmp_aux_set_defaults(str, len);
  1252. #endif
  1253. }
  1254. /* ------------------------------------------------------------------------ */
  1255. /* returns the status of cancellation */
  1256. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_CANCELLATION)(void) {
  1257. #ifdef KMP_STUB
  1258. return 0 /* false */;
  1259. #else
  1260. // initialize the library if needed
  1261. if (!__kmp_init_serial) {
  1262. __kmp_serial_initialize();
  1263. }
  1264. return __kmp_omp_cancellation;
  1265. #endif
  1266. }
  1267. int FTN_STDCALL FTN_GET_CANCELLATION_STATUS(int cancel_kind) {
  1268. #ifdef KMP_STUB
  1269. return 0 /* false */;
  1270. #else
  1271. return __kmp_get_cancellation_status(cancel_kind);
  1272. #endif
  1273. }
  1274. /* returns the maximum allowed task priority */
  1275. int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {
  1276. #ifdef KMP_STUB
  1277. return 0;
  1278. #else
  1279. if (!__kmp_init_serial) {
  1280. __kmp_serial_initialize();
  1281. }
  1282. return __kmp_max_task_priority;
  1283. #endif
  1284. }
  1285. // This function will be defined in libomptarget. When libomptarget is not
  1286. // loaded, we assume we are on the host and return KMP_HOST_DEVICE.
  1287. // Compiler/libomptarget will handle this if called inside target.
  1288. int FTN_STDCALL FTN_GET_DEVICE_NUM(void) KMP_WEAK_ATTRIBUTE_EXTERNAL;
  1289. int FTN_STDCALL FTN_GET_DEVICE_NUM(void) {
  1290. return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();
  1291. }
  1292. // Compiler will ensure that this is only called from host in sequential region
  1293. int FTN_STDCALL KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE)(kmp_pause_status_t kind,
  1294. int device_num) {
  1295. #ifdef KMP_STUB
  1296. return 1; // just fail
  1297. #else
  1298. if (device_num == KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)())
  1299. return __kmpc_pause_resource(kind);
  1300. else {
  1301. int (*fptr)(kmp_pause_status_t, int);
  1302. if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
  1303. return (*fptr)(kind, device_num);
  1304. else
  1305. return 1; // just fail if there is no libomptarget
  1306. }
  1307. #endif
  1308. }
  1309. // Compiler will ensure that this is only called from host in sequential region
  1310. int FTN_STDCALL
  1311. KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE_ALL)(kmp_pause_status_t kind) {
  1312. #ifdef KMP_STUB
  1313. return 1; // just fail
  1314. #else
  1315. int fails = 0;
  1316. int (*fptr)(kmp_pause_status_t, int);
  1317. if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
  1318. fails = (*fptr)(kind, KMP_DEVICE_ALL); // pause devices
  1319. fails += __kmpc_pause_resource(kind); // pause host
  1320. return fails;
  1321. #endif
  1322. }
  1323. // Returns the maximum number of nesting levels supported by implementation
  1324. int FTN_STDCALL FTN_GET_SUPPORTED_ACTIVE_LEVELS(void) {
  1325. #ifdef KMP_STUB
  1326. return 1;
  1327. #else
  1328. return KMP_MAX_ACTIVE_LEVELS_LIMIT;
  1329. #endif
  1330. }
  1331. void FTN_STDCALL FTN_FULFILL_EVENT(kmp_event_t *event) {
  1332. #ifndef KMP_STUB
  1333. __kmp_fulfill_event(event);
  1334. #endif
  1335. }
  1336. // nteams-var per-device ICV
  1337. void FTN_STDCALL FTN_SET_NUM_TEAMS(int KMP_DEREF num_teams) {
  1338. #ifdef KMP_STUB
  1339. // Nothing.
  1340. #else
  1341. if (!__kmp_init_serial) {
  1342. __kmp_serial_initialize();
  1343. }
  1344. __kmp_set_num_teams(KMP_DEREF num_teams);
  1345. #endif
  1346. }
  1347. int FTN_STDCALL FTN_GET_MAX_TEAMS(void) {
  1348. #ifdef KMP_STUB
  1349. return 1;
  1350. #else
  1351. if (!__kmp_init_serial) {
  1352. __kmp_serial_initialize();
  1353. }
  1354. return __kmp_get_max_teams();
  1355. #endif
  1356. }
  1357. // teams-thread-limit-var per-device ICV
  1358. void FTN_STDCALL FTN_SET_TEAMS_THREAD_LIMIT(int KMP_DEREF limit) {
  1359. #ifdef KMP_STUB
  1360. // Nothing.
  1361. #else
  1362. if (!__kmp_init_serial) {
  1363. __kmp_serial_initialize();
  1364. }
  1365. __kmp_set_teams_thread_limit(KMP_DEREF limit);
  1366. #endif
  1367. }
  1368. int FTN_STDCALL FTN_GET_TEAMS_THREAD_LIMIT(void) {
  1369. #ifdef KMP_STUB
  1370. return 1;
  1371. #else
  1372. if (!__kmp_init_serial) {
  1373. __kmp_serial_initialize();
  1374. }
  1375. return __kmp_get_teams_thread_limit();
  1376. #endif
  1377. }
  1378. /// TODO: Include the `omp.h` of the current build
  1379. /* OpenMP 5.1 interop */
  1380. typedef intptr_t omp_intptr_t;
  1381. /* 0..omp_get_num_interop_properties()-1 are reserved for implementation-defined
  1382. * properties */
  1383. typedef enum omp_interop_property {
  1384. omp_ipr_fr_id = -1,
  1385. omp_ipr_fr_name = -2,
  1386. omp_ipr_vendor = -3,
  1387. omp_ipr_vendor_name = -4,
  1388. omp_ipr_device_num = -5,
  1389. omp_ipr_platform = -6,
  1390. omp_ipr_device = -7,
  1391. omp_ipr_device_context = -8,
  1392. omp_ipr_targetsync = -9,
  1393. omp_ipr_first = -9
  1394. } omp_interop_property_t;
  1395. #define omp_interop_none 0
  1396. typedef enum omp_interop_rc {
  1397. omp_irc_no_value = 1,
  1398. omp_irc_success = 0,
  1399. omp_irc_empty = -1,
  1400. omp_irc_out_of_range = -2,
  1401. omp_irc_type_int = -3,
  1402. omp_irc_type_ptr = -4,
  1403. omp_irc_type_str = -5,
  1404. omp_irc_other = -6
  1405. } omp_interop_rc_t;
  1406. typedef enum omp_interop_fr {
  1407. omp_ifr_cuda = 1,
  1408. omp_ifr_cuda_driver = 2,
  1409. omp_ifr_opencl = 3,
  1410. omp_ifr_sycl = 4,
  1411. omp_ifr_hip = 5,
  1412. omp_ifr_level_zero = 6,
  1413. omp_ifr_last = 7
  1414. } omp_interop_fr_t;
  1415. typedef void *omp_interop_t;
  1416. // libomptarget, if loaded, provides this function
  1417. int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) {
  1418. #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
  1419. return 0;
  1420. #else
  1421. int (*fptr)(const omp_interop_t);
  1422. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_interop_properties")))
  1423. return (*fptr)(interop);
  1424. return 0;
  1425. #endif // KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB)
  1426. }
  1427. /// TODO Convert FTN_GET_INTEROP_XXX functions into a macro like interop.cpp
  1428. // libomptarget, if loaded, provides this function
  1429. intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop,
  1430. omp_interop_property_t property_id,
  1431. int *err) {
  1432. intptr_t (*fptr)(const omp_interop_t, omp_interop_property_t, int *);
  1433. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_int")))
  1434. return (*fptr)(interop, property_id, err);
  1435. return 0;
  1436. }
  1437. // libomptarget, if loaded, provides this function
  1438. void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop,
  1439. omp_interop_property_t property_id,
  1440. int *err) {
  1441. void *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
  1442. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_ptr")))
  1443. return (*fptr)(interop, property_id, err);
  1444. return nullptr;
  1445. }
  1446. // libomptarget, if loaded, provides this function
  1447. const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop,
  1448. omp_interop_property_t property_id,
  1449. int *err) {
  1450. const char *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
  1451. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_str")))
  1452. return (*fptr)(interop, property_id, err);
  1453. return nullptr;
  1454. }
  1455. // libomptarget, if loaded, provides this function
  1456. const char *FTN_STDCALL FTN_GET_INTEROP_NAME(
  1457. const omp_interop_t interop, omp_interop_property_t property_id) {
  1458. const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
  1459. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_name")))
  1460. return (*fptr)(interop, property_id);
  1461. return nullptr;
  1462. }
  1463. // libomptarget, if loaded, provides this function
  1464. const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC(
  1465. const omp_interop_t interop, omp_interop_property_t property_id) {
  1466. const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
  1467. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_type_desc")))
  1468. return (*fptr)(interop, property_id);
  1469. return nullptr;
  1470. }
  1471. // libomptarget, if loaded, provides this function
  1472. const char *FTN_STDCALL FTN_GET_INTEROP_RC_DESC(
  1473. const omp_interop_t interop, omp_interop_property_t property_id) {
  1474. const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
  1475. if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_rec_desc")))
  1476. return (*fptr)(interop, property_id);
  1477. return nullptr;
  1478. }
  1479. // display environment variables when requested
  1480. void FTN_STDCALL FTN_DISPLAY_ENV(int verbose) {
  1481. #ifndef KMP_STUB
  1482. __kmp_omp_display_env(verbose);
  1483. #endif
  1484. }
  1485. int FTN_STDCALL FTN_IN_EXPLICIT_TASK(void) {
  1486. #ifdef KMP_STUB
  1487. return 0;
  1488. #else
  1489. int gtid = __kmp_entry_gtid();
  1490. return __kmp_thread_from_gtid(gtid)->th.th_current_task->td_flags.tasktype;
  1491. #endif
  1492. }
  1493. // GCC compatibility (versioned symbols)
  1494. #ifdef KMP_USE_VERSION_SYMBOLS
  1495. /* These following sections create versioned symbols for the
  1496. omp_* routines. The KMP_VERSION_SYMBOL macro expands the API name and
  1497. then maps it to a versioned symbol.
  1498. libgomp ``versions'' its symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also
  1499. retaining the default version which libomp uses: VERSION (defined in
  1500. exports_so.txt). If you want to see the versioned symbols for libgomp.so.1
  1501. then just type:
  1502. objdump -T /path/to/libgomp.so.1 | grep omp_
  1503. Example:
  1504. Step 1) Create __kmp_api_omp_set_num_threads_10_alias which is alias of
  1505. __kmp_api_omp_set_num_threads
  1506. Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version:
  1507. omp_set_num_threads@OMP_1.0
  1508. Step 2B) Set __kmp_api_omp_set_num_threads to default version:
  1509. omp_set_num_threads@@VERSION
  1510. */
  1511. // OMP_1.0 versioned symbols
  1512. KMP_VERSION_SYMBOL(FTN_SET_NUM_THREADS, 10, "OMP_1.0");
  1513. KMP_VERSION_SYMBOL(FTN_GET_NUM_THREADS, 10, "OMP_1.0");
  1514. KMP_VERSION_SYMBOL(FTN_GET_MAX_THREADS, 10, "OMP_1.0");
  1515. KMP_VERSION_SYMBOL(FTN_GET_THREAD_NUM, 10, "OMP_1.0");
  1516. KMP_VERSION_SYMBOL(FTN_GET_NUM_PROCS, 10, "OMP_1.0");
  1517. KMP_VERSION_SYMBOL(FTN_IN_PARALLEL, 10, "OMP_1.0");
  1518. KMP_VERSION_SYMBOL(FTN_SET_DYNAMIC, 10, "OMP_1.0");
  1519. KMP_VERSION_SYMBOL(FTN_GET_DYNAMIC, 10, "OMP_1.0");
  1520. KMP_VERSION_SYMBOL(FTN_SET_NESTED, 10, "OMP_1.0");
  1521. KMP_VERSION_SYMBOL(FTN_GET_NESTED, 10, "OMP_1.0");
  1522. KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 10, "OMP_1.0");
  1523. KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");
  1524. KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 10, "OMP_1.0");
  1525. KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");
  1526. KMP_VERSION_SYMBOL(FTN_SET_LOCK, 10, "OMP_1.0");
  1527. KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 10, "OMP_1.0");
  1528. KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 10, "OMP_1.0");
  1529. KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");
  1530. KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 10, "OMP_1.0");
  1531. KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");
  1532. // OMP_2.0 versioned symbols
  1533. KMP_VERSION_SYMBOL(FTN_GET_WTICK, 20, "OMP_2.0");
  1534. KMP_VERSION_SYMBOL(FTN_GET_WTIME, 20, "OMP_2.0");
  1535. // OMP_3.0 versioned symbols
  1536. KMP_VERSION_SYMBOL(FTN_SET_SCHEDULE, 30, "OMP_3.0");
  1537. KMP_VERSION_SYMBOL(FTN_GET_SCHEDULE, 30, "OMP_3.0");
  1538. KMP_VERSION_SYMBOL(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");
  1539. KMP_VERSION_SYMBOL(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
  1540. KMP_VERSION_SYMBOL(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
  1541. KMP_VERSION_SYMBOL(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");
  1542. KMP_VERSION_SYMBOL(FTN_GET_LEVEL, 30, "OMP_3.0");
  1543. KMP_VERSION_SYMBOL(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");
  1544. KMP_VERSION_SYMBOL(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");
  1545. // the lock routines have a 1.0 and 3.0 version
  1546. KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 30, "OMP_3.0");
  1547. KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");
  1548. KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 30, "OMP_3.0");
  1549. KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");
  1550. KMP_VERSION_SYMBOL(FTN_SET_LOCK, 30, "OMP_3.0");
  1551. KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 30, "OMP_3.0");
  1552. KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 30, "OMP_3.0");
  1553. KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");
  1554. KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 30, "OMP_3.0");
  1555. KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");
  1556. // OMP_3.1 versioned symbol
  1557. KMP_VERSION_SYMBOL(FTN_IN_FINAL, 31, "OMP_3.1");
  1558. // OMP_4.0 versioned symbols
  1559. KMP_VERSION_SYMBOL(FTN_GET_PROC_BIND, 40, "OMP_4.0");
  1560. KMP_VERSION_SYMBOL(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");
  1561. KMP_VERSION_SYMBOL(FTN_GET_TEAM_NUM, 40, "OMP_4.0");
  1562. KMP_VERSION_SYMBOL(FTN_GET_CANCELLATION, 40, "OMP_4.0");
  1563. KMP_VERSION_SYMBOL(FTN_GET_DEFAULT_DEVICE, 40, "OMP_4.0");
  1564. KMP_VERSION_SYMBOL(FTN_SET_DEFAULT_DEVICE, 40, "OMP_4.0");
  1565. KMP_VERSION_SYMBOL(FTN_IS_INITIAL_DEVICE, 40, "OMP_4.0");
  1566. KMP_VERSION_SYMBOL(FTN_GET_NUM_DEVICES, 40, "OMP_4.0");
  1567. // OMP_4.5 versioned symbols
  1568. KMP_VERSION_SYMBOL(FTN_GET_MAX_TASK_PRIORITY, 45, "OMP_4.5");
  1569. KMP_VERSION_SYMBOL(FTN_GET_NUM_PLACES, 45, "OMP_4.5");
  1570. KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM_PROCS, 45, "OMP_4.5");
  1571. KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5");
  1572. KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5");
  1573. KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5");
  1574. KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");
  1575. KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5");
  1576. // OMP_5.0 versioned symbols
  1577. // KMP_VERSION_SYMBOL(FTN_GET_DEVICE_NUM, 50, "OMP_5.0");
  1578. KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE, 50, "OMP_5.0");
  1579. KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE_ALL, 50, "OMP_5.0");
  1580. // The C versions (KMP_FTN_PLAIN) of these symbols are in kmp_csupport.c
  1581. #if KMP_FTN_ENTRIES == KMP_FTN_APPEND
  1582. KMP_VERSION_SYMBOL(FTN_CAPTURE_AFFINITY, 50, "OMP_5.0");
  1583. KMP_VERSION_SYMBOL(FTN_DISPLAY_AFFINITY, 50, "OMP_5.0");
  1584. KMP_VERSION_SYMBOL(FTN_GET_AFFINITY_FORMAT, 50, "OMP_5.0");
  1585. KMP_VERSION_SYMBOL(FTN_SET_AFFINITY_FORMAT, 50, "OMP_5.0");
  1586. #endif
  1587. // KMP_VERSION_SYMBOL(FTN_GET_SUPPORTED_ACTIVE_LEVELS, 50, "OMP_5.0");
  1588. // KMP_VERSION_SYMBOL(FTN_FULFILL_EVENT, 50, "OMP_5.0");
  1589. #endif // KMP_USE_VERSION_SYMBOLS
  1590. #ifdef __cplusplus
  1591. } // extern "C"
  1592. #endif // __cplusplus
  1593. // end of file //