LLVM OpenMP* Runtime Library
kmp_ftn_entry.h
1 /*
2  * kmp_ftn_entry.h -- Fortran entry linkage support for OpenMP.
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // The LLVM Compiler Infrastructure
8 //
9 // This file is dual licensed under the MIT and the University of Illinois Open
10 // Source Licenses. See LICENSE.txt for details.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef FTN_STDCALL
15 #error The support file kmp_ftn_entry.h should not be compiled by itself.
16 #endif
17 
18 #ifdef KMP_STUB
19 #include "kmp_stub.h"
20 #endif
21 
22 #include "kmp_i18n.h"
23 
24 #if OMPT_SUPPORT
25 #include "ompt-specific.h"
26 #endif
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif // __cplusplus
31 
32 /* For compatibility with the Gnu/MS Open MP codegen, omp_set_num_threads(),
33  * omp_set_nested(), and omp_set_dynamic() [in lowercase on MS, and w/o
34  * a trailing underscore on Linux* OS] take call by value integer arguments.
35  * + omp_set_max_active_levels()
36  * + omp_set_schedule()
37  *
38  * For backward compatibility with 9.1 and previous Intel compiler, these
39  * entry points take call by reference integer arguments. */
40 #ifdef KMP_GOMP_COMPAT
41 #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_UPPER)
42 #define PASS_ARGS_BY_VALUE 1
43 #endif
44 #endif
45 #if KMP_OS_WINDOWS
46 #if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_APPEND)
47 #define PASS_ARGS_BY_VALUE 1
48 #endif
49 #endif
50 
51 // This macro helps to reduce code duplication.
52 #ifdef PASS_ARGS_BY_VALUE
53 #define KMP_DEREF
54 #else
55 #define KMP_DEREF *
56 #endif
57 
58 void FTN_STDCALL FTN_SET_STACKSIZE(int KMP_DEREF arg) {
59 #ifdef KMP_STUB
60  __kmps_set_stacksize(KMP_DEREF arg);
61 #else
62  // __kmp_aux_set_stacksize initializes the library if needed
63  __kmp_aux_set_stacksize((size_t)KMP_DEREF arg);
64 #endif
65 }
66 
67 void FTN_STDCALL FTN_SET_STACKSIZE_S(size_t KMP_DEREF arg) {
68 #ifdef KMP_STUB
69  __kmps_set_stacksize(KMP_DEREF arg);
70 #else
71  // __kmp_aux_set_stacksize initializes the library if needed
72  __kmp_aux_set_stacksize(KMP_DEREF arg);
73 #endif
74 }
75 
76 int FTN_STDCALL FTN_GET_STACKSIZE(void) {
77 #ifdef KMP_STUB
78  return __kmps_get_stacksize();
79 #else
80  if (!__kmp_init_serial) {
81  __kmp_serial_initialize();
82  }
83  return (int)__kmp_stksize;
84 #endif
85 }
86 
87 size_t FTN_STDCALL FTN_GET_STACKSIZE_S(void) {
88 #ifdef KMP_STUB
89  return __kmps_get_stacksize();
90 #else
91  if (!__kmp_init_serial) {
92  __kmp_serial_initialize();
93  }
94  return __kmp_stksize;
95 #endif
96 }
97 
98 void FTN_STDCALL FTN_SET_BLOCKTIME(int KMP_DEREF arg) {
99 #ifdef KMP_STUB
100  __kmps_set_blocktime(KMP_DEREF arg);
101 #else
102  int gtid, tid;
103  kmp_info_t *thread;
104 
105  gtid = __kmp_entry_gtid();
106  tid = __kmp_tid_from_gtid(gtid);
107  thread = __kmp_thread_from_gtid(gtid);
108 
109  __kmp_aux_set_blocktime(KMP_DEREF arg, thread, tid);
110 #endif
111 }
112 
113 int FTN_STDCALL FTN_GET_BLOCKTIME(void) {
114 #ifdef KMP_STUB
115  return __kmps_get_blocktime();
116 #else
117  int gtid, tid;
118  kmp_info_t *thread;
119  kmp_team_p *team;
120 
121  gtid = __kmp_entry_gtid();
122  tid = __kmp_tid_from_gtid(gtid);
123  thread = __kmp_thread_from_gtid(gtid);
124  team = __kmp_threads[gtid]->th.th_team;
125 
126  /* These must match the settings used in __kmp_wait_sleep() */
127  if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {
128  KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
129  team->t.t_id, tid, KMP_MAX_BLOCKTIME));
130  return KMP_MAX_BLOCKTIME;
131  }
132 #ifdef KMP_ADJUST_BLOCKTIME
133  else if (__kmp_zero_bt && !get__bt_set(team, tid)) {
134  KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
135  team->t.t_id, tid, 0));
136  return 0;
137  }
138 #endif /* KMP_ADJUST_BLOCKTIME */
139  else {
140  KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d\n", gtid,
141  team->t.t_id, tid, get__blocktime(team, tid)));
142  return get__blocktime(team, tid);
143  }
144 #endif
145 }
146 
147 void FTN_STDCALL FTN_SET_LIBRARY_SERIAL(void) {
148 #ifdef KMP_STUB
149  __kmps_set_library(library_serial);
150 #else
151  // __kmp_user_set_library initializes the library if needed
152  __kmp_user_set_library(library_serial);
153 #endif
154 }
155 
156 void FTN_STDCALL FTN_SET_LIBRARY_TURNAROUND(void) {
157 #ifdef KMP_STUB
158  __kmps_set_library(library_turnaround);
159 #else
160  // __kmp_user_set_library initializes the library if needed
161  __kmp_user_set_library(library_turnaround);
162 #endif
163 }
164 
165 void FTN_STDCALL FTN_SET_LIBRARY_THROUGHPUT(void) {
166 #ifdef KMP_STUB
167  __kmps_set_library(library_throughput);
168 #else
169  // __kmp_user_set_library initializes the library if needed
170  __kmp_user_set_library(library_throughput);
171 #endif
172 }
173 
174 void FTN_STDCALL FTN_SET_LIBRARY(int KMP_DEREF arg) {
175 #ifdef KMP_STUB
176  __kmps_set_library(KMP_DEREF arg);
177 #else
178  enum library_type lib;
179  lib = (enum library_type)KMP_DEREF arg;
180  // __kmp_user_set_library initializes the library if needed
181  __kmp_user_set_library(lib);
182 #endif
183 }
184 
185 int FTN_STDCALL FTN_GET_LIBRARY(void) {
186 #ifdef KMP_STUB
187  return __kmps_get_library();
188 #else
189  if (!__kmp_init_serial) {
190  __kmp_serial_initialize();
191  }
192  return ((int)__kmp_library);
193 #endif
194 }
195 
196 void FTN_STDCALL FTN_SET_DISP_NUM_BUFFERS(int KMP_DEREF arg) {
197 #ifdef KMP_STUB
198  ; // empty routine
199 #else
200  // ignore after initialization because some teams have already
201  // allocated dispatch buffers
202  if (__kmp_init_serial == 0 && (KMP_DEREF arg) > 0)
203  __kmp_dispatch_num_buffers = KMP_DEREF arg;
204 #endif
205 }
206 
207 int FTN_STDCALL FTN_SET_AFFINITY(void **mask) {
208 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
209  return -1;
210 #else
211  if (!TCR_4(__kmp_init_middle)) {
212  __kmp_middle_initialize();
213  }
214  return __kmp_aux_set_affinity(mask);
215 #endif
216 }
217 
218 int FTN_STDCALL FTN_GET_AFFINITY(void **mask) {
219 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
220  return -1;
221 #else
222  if (!TCR_4(__kmp_init_middle)) {
223  __kmp_middle_initialize();
224  }
225  return __kmp_aux_get_affinity(mask);
226 #endif
227 }
228 
229 int FTN_STDCALL FTN_GET_AFFINITY_MAX_PROC(void) {
230 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
231  return 0;
232 #else
233  // We really only NEED serial initialization here.
234  if (!TCR_4(__kmp_init_middle)) {
235  __kmp_middle_initialize();
236  }
237  return __kmp_aux_get_affinity_max_proc();
238 #endif
239 }
240 
241 void FTN_STDCALL FTN_CREATE_AFFINITY_MASK(void **mask) {
242 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
243  *mask = NULL;
244 #else
245  // We really only NEED serial initialization here.
246  kmp_affin_mask_t *mask_internals;
247  if (!TCR_4(__kmp_init_middle)) {
248  __kmp_middle_initialize();
249  }
250  mask_internals = __kmp_affinity_dispatch->allocate_mask();
251  KMP_CPU_ZERO(mask_internals);
252  *mask = mask_internals;
253 #endif
254 }
255 
256 void FTN_STDCALL FTN_DESTROY_AFFINITY_MASK(void **mask) {
257 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
258 // Nothing
259 #else
260  // We really only NEED serial initialization here.
261  kmp_affin_mask_t *mask_internals;
262  if (!TCR_4(__kmp_init_middle)) {
263  __kmp_middle_initialize();
264  }
265  if (__kmp_env_consistency_check) {
266  if (*mask == NULL) {
267  KMP_FATAL(AffinityInvalidMask, "kmp_destroy_affinity_mask");
268  }
269  }
270  mask_internals = (kmp_affin_mask_t *)(*mask);
271  __kmp_affinity_dispatch->deallocate_mask(mask_internals);
272  *mask = NULL;
273 #endif
274 }
275 
276 int FTN_STDCALL FTN_SET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
277 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
278  return -1;
279 #else
280  if (!TCR_4(__kmp_init_middle)) {
281  __kmp_middle_initialize();
282  }
283  return __kmp_aux_set_affinity_mask_proc(KMP_DEREF proc, mask);
284 #endif
285 }
286 
287 int FTN_STDCALL FTN_UNSET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
288 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
289  return -1;
290 #else
291  if (!TCR_4(__kmp_init_middle)) {
292  __kmp_middle_initialize();
293  }
294  return __kmp_aux_unset_affinity_mask_proc(KMP_DEREF proc, mask);
295 #endif
296 }
297 
298 int FTN_STDCALL FTN_GET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {
299 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
300  return -1;
301 #else
302  if (!TCR_4(__kmp_init_middle)) {
303  __kmp_middle_initialize();
304  }
305  return __kmp_aux_get_affinity_mask_proc(KMP_DEREF proc, mask);
306 #endif
307 }
308 
309 /* ------------------------------------------------------------------------ */
310 
311 /* sets the requested number of threads for the next parallel region */
312 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NUM_THREADS)(int KMP_DEREF arg) {
313 #ifdef KMP_STUB
314 // Nothing.
315 #else
316  __kmp_set_num_threads(KMP_DEREF arg, __kmp_entry_gtid());
317 #endif
318 }
319 
320 /* returns the number of threads in current team */
321 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_THREADS)(void) {
322 #ifdef KMP_STUB
323  return 1;
324 #else
325  // __kmpc_bound_num_threads initializes the library if needed
326  return __kmpc_bound_num_threads(NULL);
327 #endif
328 }
329 
330 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_THREADS)(void) {
331 #ifdef KMP_STUB
332  return 1;
333 #else
334  int gtid;
335  kmp_info_t *thread;
336  if (!TCR_4(__kmp_init_middle)) {
337  __kmp_middle_initialize();
338  }
339  gtid = __kmp_entry_gtid();
340  thread = __kmp_threads[gtid];
341  // return thread -> th.th_team -> t.t_current_task[
342  // thread->th.th_info.ds.ds_tid ] -> icvs.nproc;
343  return thread->th.th_current_task->td_icvs.nproc;
344 #endif
345 }
346 
347 #if OMP_50_ENABLED
348 int FTN_STDCALL FTN_CONTROL_TOOL(int command, int modifier, void *arg) {
349 #if defined(KMP_STUB) || !OMPT_SUPPORT
350  return -2;
351 #else
352  OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());
353  if (!TCR_4(__kmp_init_middle)) {
354  return -2;
355  }
356  kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];
357  ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);
358  parent_task_info->frame.enter_frame = OMPT_GET_FRAME_ADDRESS(1);
359  int ret = __kmp_control_tool(command, modifier, arg);
360  parent_task_info->frame.enter_frame = 0;
361  return ret;
362 #endif
363 }
364 
365 /* OpenMP 5.0 Memory Management support */
366 void FTN_STDCALL FTN_SET_DEFAULT_ALLOCATOR(const omp_allocator_t *allocator) {
367 #ifndef KMP_STUB
368  __kmpc_set_default_allocator(__kmp_entry_gtid(), allocator);
369 #endif
370 }
371 const omp_allocator_t *FTN_STDCALL FTN_GET_DEFAULT_ALLOCATOR(void) {
372 #ifdef KMP_STUB
373  return NULL;
374 #else
375  return __kmpc_get_default_allocator(__kmp_entry_gtid());
376 #endif
377 }
378 void *FTN_STDCALL FTN_ALLOC(size_t size, const omp_allocator_t *allocator) {
379 #ifdef KMP_STUB
380  return malloc(size);
381 #else
382  return __kmpc_alloc(__kmp_entry_gtid(), size, allocator);
383 #endif
384 }
385 void FTN_STDCALL FTN_FREE(void *ptr, const omp_allocator_t *allocator) {
386 #ifdef KMP_STUB
387  free(ptr);
388 #else
389  __kmpc_free(__kmp_entry_gtid(), ptr, allocator);
390 #endif
391 }
392 #endif /* OMP_50_ENABLED */
393 
394 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
395 #ifdef KMP_STUB
396  return 0;
397 #else
398  int gtid;
399 
400 #if KMP_OS_DARWIN || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_HURD
401  gtid = __kmp_entry_gtid();
402 #elif KMP_OS_WINDOWS
403  if (!__kmp_init_parallel ||
404  (gtid = (int)((kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key))) ==
405  0) {
406  // Either library isn't initialized or thread is not registered
407  // 0 is the correct TID in this case
408  return 0;
409  }
410  --gtid; // We keep (gtid+1) in TLS
411 #elif KMP_OS_LINUX
412 #ifdef KMP_TDATA_GTID
413  if (__kmp_gtid_mode >= 3) {
414  if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
415  return 0;
416  }
417  } else {
418 #endif
419  if (!__kmp_init_parallel ||
420  (gtid = (kmp_intptr_t)(
421  pthread_getspecific(__kmp_gtid_threadprivate_key))) == 0) {
422  return 0;
423  }
424  --gtid;
425 #ifdef KMP_TDATA_GTID
426  }
427 #endif
428 #else
429 #error Unknown or unsupported OS
430 #endif
431 
432  return __kmp_tid_from_gtid(gtid);
433 #endif
434 }
435 
436 int FTN_STDCALL FTN_GET_NUM_KNOWN_THREADS(void) {
437 #ifdef KMP_STUB
438  return 1;
439 #else
440  if (!__kmp_init_serial) {
441  __kmp_serial_initialize();
442  }
443  /* NOTE: this is not syncronized, so it can change at any moment */
444  /* NOTE: this number also includes threads preallocated in hot-teams */
445  return TCR_4(__kmp_nth);
446 #endif
447 }
448 
449 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)(void) {
450 #ifdef KMP_STUB
451  return 1;
452 #else
453  if (!TCR_4(__kmp_init_middle)) {
454  __kmp_middle_initialize();
455  }
456  return __kmp_avail_proc;
457 #endif
458 }
459 
460 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NESTED)(int KMP_DEREF flag) {
461 #ifdef KMP_STUB
462  __kmps_set_nested(KMP_DEREF flag);
463 #else
464  kmp_info_t *thread;
465  /* For the thread-private internal controls implementation */
466  thread = __kmp_entry_thread();
467  __kmp_save_internal_controls(thread);
468  set__nested(thread, ((KMP_DEREF flag) ? TRUE : FALSE));
469 #endif
470 }
471 
472 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NESTED)(void) {
473 #ifdef KMP_STUB
474  return __kmps_get_nested();
475 #else
476  kmp_info_t *thread;
477  thread = __kmp_entry_thread();
478  return get__nested(thread);
479 #endif
480 }
481 
482 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DYNAMIC)(int KMP_DEREF flag) {
483 #ifdef KMP_STUB
484  __kmps_set_dynamic(KMP_DEREF flag ? TRUE : FALSE);
485 #else
486  kmp_info_t *thread;
487  /* For the thread-private implementation of the internal controls */
488  thread = __kmp_entry_thread();
489  // !!! What if foreign thread calls it?
490  __kmp_save_internal_controls(thread);
491  set__dynamic(thread, KMP_DEREF flag ? TRUE : FALSE);
492 #endif
493 }
494 
495 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DYNAMIC)(void) {
496 #ifdef KMP_STUB
497  return __kmps_get_dynamic();
498 #else
499  kmp_info_t *thread;
500  thread = __kmp_entry_thread();
501  return get__dynamic(thread);
502 #endif
503 }
504 
505 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_PARALLEL)(void) {
506 #ifdef KMP_STUB
507  return 0;
508 #else
509  kmp_info_t *th = __kmp_entry_thread();
510 #if OMP_40_ENABLED
511  if (th->th.th_teams_microtask) {
512  // AC: r_in_parallel does not work inside teams construct where real
513  // parallel is inactive, but all threads have same root, so setting it in
514  // one team affects other teams.
515  // The solution is to use per-team nesting level
516  return (th->th.th_team->t.t_active_level ? 1 : 0);
517  } else
518 #endif /* OMP_40_ENABLED */
519  return (th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE);
520 #endif
521 }
522 
523 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_SCHEDULE)(kmp_sched_t KMP_DEREF kind,
524  int KMP_DEREF modifier) {
525 #ifdef KMP_STUB
526  __kmps_set_schedule(KMP_DEREF kind, KMP_DEREF modifier);
527 #else
528  /* TO DO: For the per-task implementation of the internal controls */
529  __kmp_set_schedule(__kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier);
530 #endif
531 }
532 
533 void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_SCHEDULE)(kmp_sched_t *kind,
534  int *modifier) {
535 #ifdef KMP_STUB
536  __kmps_get_schedule(kind, modifier);
537 #else
538  /* TO DO: For the per-task implementation of the internal controls */
539  __kmp_get_schedule(__kmp_entry_gtid(), kind, modifier);
540 #endif
541 }
542 
543 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)(int KMP_DEREF arg) {
544 #ifdef KMP_STUB
545 // Nothing.
546 #else
547  /* TO DO: We want per-task implementation of this internal control */
548  __kmp_set_max_active_levels(__kmp_entry_gtid(), KMP_DEREF arg);
549 #endif
550 }
551 
552 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)(void) {
553 #ifdef KMP_STUB
554  return 0;
555 #else
556  /* TO DO: We want per-task implementation of this internal control */
557  return __kmp_get_max_active_levels(__kmp_entry_gtid());
558 #endif
559 }
560 
561 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)(void) {
562 #ifdef KMP_STUB
563  return 0; // returns 0 if it is called from the sequential part of the program
564 #else
565  /* TO DO: For the per-task implementation of the internal controls */
566  return __kmp_entry_thread()->th.th_team->t.t_active_level;
567 #endif
568 }
569 
570 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_LEVEL)(void) {
571 #ifdef KMP_STUB
572  return 0; // returns 0 if it is called from the sequential part of the program
573 #else
574  /* TO DO: For the per-task implementation of the internal controls */
575  return __kmp_entry_thread()->th.th_team->t.t_level;
576 #endif
577 }
578 
579 int FTN_STDCALL
580  KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)(int KMP_DEREF level) {
581 #ifdef KMP_STUB
582  return (KMP_DEREF level) ? (-1) : (0);
583 #else
584  return __kmp_get_ancestor_thread_num(__kmp_entry_gtid(), KMP_DEREF level);
585 #endif
586 }
587 
588 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)(int KMP_DEREF level) {
589 #ifdef KMP_STUB
590  return (KMP_DEREF level) ? (-1) : (1);
591 #else
592  return __kmp_get_team_size(__kmp_entry_gtid(), KMP_DEREF level);
593 #endif
594 }
595 
596 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)(void) {
597 #ifdef KMP_STUB
598  return 1; // TO DO: clarify whether it returns 1 or 0?
599 #else
600  if (!__kmp_init_serial) {
601  __kmp_serial_initialize();
602  }
603  /* global ICV */
604  return __kmp_cg_max_nth;
605 #endif
606 }
607 
608 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_FINAL)(void) {
609 #ifdef KMP_STUB
610  return 0; // TO DO: clarify whether it returns 1 or 0?
611 #else
612  if (!TCR_4(__kmp_init_parallel)) {
613  return 0;
614  }
615  return __kmp_entry_thread()->th.th_current_task->td_flags.final;
616 #endif
617 }
618 
619 #if OMP_40_ENABLED
620 
621 kmp_proc_bind_t FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PROC_BIND)(void) {
622 #ifdef KMP_STUB
623  return __kmps_get_proc_bind();
624 #else
625  return get__proc_bind(__kmp_entry_thread());
626 #endif
627 }
628 
629 #if OMP_45_ENABLED
630 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PLACES)(void) {
631 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
632  return 0;
633 #else
634  if (!TCR_4(__kmp_init_middle)) {
635  __kmp_middle_initialize();
636  }
637  if (!KMP_AFFINITY_CAPABLE())
638  return 0;
639  return __kmp_affinity_num_masks;
640 #endif
641 }
642 
643 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM_PROCS)(int place_num) {
644 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
645  return 0;
646 #else
647  int i;
648  int retval = 0;
649  if (!TCR_4(__kmp_init_middle)) {
650  __kmp_middle_initialize();
651  }
652  if (!KMP_AFFINITY_CAPABLE())
653  return 0;
654  if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
655  return 0;
656  kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
657  KMP_CPU_SET_ITERATE(i, mask) {
658  if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
659  (!KMP_CPU_ISSET(i, mask))) {
660  continue;
661  }
662  ++retval;
663  }
664  return retval;
665 #endif
666 }
667 
668 void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_PROC_IDS)(int place_num,
669  int *ids) {
670 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
671 // Nothing.
672 #else
673  int i, j;
674  if (!TCR_4(__kmp_init_middle)) {
675  __kmp_middle_initialize();
676  }
677  if (!KMP_AFFINITY_CAPABLE())
678  return;
679  if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
680  return;
681  kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
682  j = 0;
683  KMP_CPU_SET_ITERATE(i, mask) {
684  if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
685  (!KMP_CPU_ISSET(i, mask))) {
686  continue;
687  }
688  ids[j++] = i;
689  }
690 #endif
691 }
692 
693 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM)(void) {
694 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
695  return -1;
696 #else
697  int gtid;
698  kmp_info_t *thread;
699  if (!TCR_4(__kmp_init_middle)) {
700  __kmp_middle_initialize();
701  }
702  if (!KMP_AFFINITY_CAPABLE())
703  return -1;
704  gtid = __kmp_entry_gtid();
705  thread = __kmp_thread_from_gtid(gtid);
706  if (thread->th.th_current_place < 0)
707  return -1;
708  return thread->th.th_current_place;
709 #endif
710 }
711 
712 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PARTITION_NUM_PLACES)(void) {
713 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
714  return 0;
715 #else
716  int gtid, num_places, first_place, last_place;
717  kmp_info_t *thread;
718  if (!TCR_4(__kmp_init_middle)) {
719  __kmp_middle_initialize();
720  }
721  if (!KMP_AFFINITY_CAPABLE())
722  return 0;
723  if (KMP_AFFINITY_NON_PROC_BIND) {
724  return 1;
725  }
726  gtid = __kmp_entry_gtid();
727  thread = __kmp_thread_from_gtid(gtid);
728  first_place = thread->th.th_first_place;
729  last_place = thread->th.th_last_place;
730  if (first_place < 0 || last_place < 0)
731  return 0;
732  if (first_place <= last_place)
733  num_places = last_place - first_place + 1;
734  else
735  num_places = __kmp_affinity_num_masks - first_place + last_place + 1;
736  return num_places;
737 #endif
738 }
739 
740 void
741  FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PARTITION_PLACE_NUMS)(int *place_nums) {
742 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
743 // Nothing.
744 #else
745  int i, gtid, place_num, first_place, last_place, start, end;
746  kmp_info_t *thread;
747  if (!TCR_4(__kmp_init_middle)) {
748  __kmp_middle_initialize();
749  }
750  if (!KMP_AFFINITY_CAPABLE())
751  return;
752  gtid = __kmp_entry_gtid();
753  thread = __kmp_thread_from_gtid(gtid);
754  if (KMP_AFFINITY_NON_PROC_BIND) {
755  place_nums[0] = thread->th.th_current_place;
756  return;
757  }
758  first_place = thread->th.th_first_place;
759  last_place = thread->th.th_last_place;
760  if (first_place < 0 || last_place < 0)
761  return;
762  if (first_place <= last_place) {
763  start = first_place;
764  end = last_place;
765  } else {
766  start = last_place;
767  end = first_place;
768  }
769  for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
770  place_nums[i] = place_num;
771  }
772 #endif
773 }
774 #endif
775 
776 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {
777 #ifdef KMP_STUB
778  return 1;
779 #else
780  kmp_info_t *thr = __kmp_entry_thread();
781  if (thr->th.th_teams_microtask) {
782  kmp_team_t *team = thr->th.th_team;
783  int tlevel = thr->th.th_teams_level;
784  int ii = team->t.t_level; // the level of the teams construct
785  int dd = team->t.t_serialized;
786  int level = tlevel + 1;
787  KMP_DEBUG_ASSERT(ii >= tlevel);
788  while (ii > level) {
789  for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
790  }
791  if (team->t.t_serialized && (!dd)) {
792  team = team->t.t_parent;
793  continue;
794  }
795  if (ii > level) {
796  team = team->t.t_parent;
797  ii--;
798  }
799  }
800  if (dd > 1) {
801  return 1; // teams region is serialized ( 1 team of 1 thread ).
802  } else {
803  return team->t.t_parent->t.t_nproc;
804  }
805  } else {
806  return 1;
807  }
808 #endif
809 }
810 
811 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {
812 #ifdef KMP_STUB
813  return 0;
814 #else
815  kmp_info_t *thr = __kmp_entry_thread();
816  if (thr->th.th_teams_microtask) {
817  kmp_team_t *team = thr->th.th_team;
818  int tlevel = thr->th.th_teams_level; // the level of the teams construct
819  int ii = team->t.t_level;
820  int dd = team->t.t_serialized;
821  int level = tlevel + 1;
822  KMP_DEBUG_ASSERT(ii >= tlevel);
823  while (ii > level) {
824  for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
825  }
826  if (team->t.t_serialized && (!dd)) {
827  team = team->t.t_parent;
828  continue;
829  }
830  if (ii > level) {
831  team = team->t.t_parent;
832  ii--;
833  }
834  }
835  if (dd > 1) {
836  return 0; // teams region is serialized ( 1 team of 1 thread ).
837  } else {
838  return team->t.t_master_tid;
839  }
840  } else {
841  return 0;
842  }
843 #endif
844 }
845 
846 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)(void) {
847 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
848  return 0;
849 #else
850  return __kmp_entry_thread()->th.th_current_task->td_icvs.default_device;
851 #endif
852 }
853 
854 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
855 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
856 // Nothing.
857 #else
858  __kmp_entry_thread()->th.th_current_task->td_icvs.default_device =
859  KMP_DEREF arg;
860 #endif
861 }
862 
863 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
864 
865 int FTN_STDCALL FTN_GET_NUM_DEVICES(void) { return 0; }
866 
867 #endif // KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
868 
869 #if !KMP_OS_LINUX
870 
871 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) { return 1; }
872 
873 #else
874 
875 // This internal function is used when the entry from the offload library
876 // is not found.
877 int _Offload_get_device_number(void) KMP_WEAK_ATTRIBUTE;
878 
879 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {
880  if (_Offload_get_device_number) {
881  return _Offload_get_device_number() == -1;
882  } else {
883  return 1;
884  }
885 }
886 
887 #endif // ! KMP_OS_LINUX
888 
889 #endif // OMP_40_ENABLED
890 
891 #if OMP_45_ENABLED && defined(KMP_STUB)
892 // OpenMP 4.5 entries for stubs library
893 
894 int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) { return -1; }
895 
896 // As all *target* functions are C-only parameters always passed by value
897 void *FTN_STDCALL FTN_TARGET_ALLOC(size_t size, int device_num) { return 0; }
898 
899 void FTN_STDCALL FTN_TARGET_FREE(void *device_ptr, int device_num) {}
900 
901 int FTN_STDCALL FTN_TARGET_IS_PRESENT(void *ptr, int device_num) { return 0; }
902 
903 int FTN_STDCALL FTN_TARGET_MEMCPY(void *dst, void *src, size_t length,
904  size_t dst_offset, size_t src_offset,
905  int dst_device, int src_device) {
906  return -1;
907 }
908 
909 int FTN_STDCALL FTN_TARGET_MEMCPY_RECT(
910  void *dst, void *src, size_t element_size, int num_dims,
911  const size_t *volume, const size_t *dst_offsets, const size_t *src_offsets,
912  const size_t *dst_dimensions, const size_t *src_dimensions, int dst_device,
913  int src_device) {
914  return -1;
915 }
916 
917 int FTN_STDCALL FTN_TARGET_ASSOCIATE_PTR(void *host_ptr, void *device_ptr,
918  size_t size, size_t device_offset,
919  int device_num) {
920  return -1;
921 }
922 
923 int FTN_STDCALL FTN_TARGET_DISASSOCIATE_PTR(void *host_ptr, int device_num) {
924  return -1;
925 }
926 #endif // OMP_45_ENABLED && defined(KMP_STUB)
927 
928 #ifdef KMP_STUB
929 typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;
930 #endif /* KMP_STUB */
931 
932 #if KMP_USE_DYNAMIC_LOCK
933 void FTN_STDCALL FTN_INIT_LOCK_WITH_HINT(void **user_lock,
934  uintptr_t KMP_DEREF hint) {
935 #ifdef KMP_STUB
936  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
937 #else
938  int gtid = __kmp_entry_gtid();
939 #if OMPT_SUPPORT && OMPT_OPTIONAL
940  OMPT_STORE_RETURN_ADDRESS(gtid);
941 #endif
942  __kmpc_init_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
943 #endif
944 }
945 
946 void FTN_STDCALL FTN_INIT_NEST_LOCK_WITH_HINT(void **user_lock,
947  uintptr_t KMP_DEREF hint) {
948 #ifdef KMP_STUB
949  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
950 #else
951  int gtid = __kmp_entry_gtid();
952 #if OMPT_SUPPORT && OMPT_OPTIONAL
953  OMPT_STORE_RETURN_ADDRESS(gtid);
954 #endif
955  __kmpc_init_nest_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
956 #endif
957 }
958 #endif
959 
960 /* initialize the lock */
961 void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_LOCK)(void **user_lock) {
962 #ifdef KMP_STUB
963  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
964 #else
965  int gtid = __kmp_entry_gtid();
966 #if OMPT_SUPPORT && OMPT_OPTIONAL
967  OMPT_STORE_RETURN_ADDRESS(gtid);
968 #endif
969  __kmpc_init_lock(NULL, gtid, user_lock);
970 #endif
971 }
972 
973 /* initialize the lock */
974 void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)(void **user_lock) {
975 #ifdef KMP_STUB
976  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
977 #else
978  int gtid = __kmp_entry_gtid();
979 #if OMPT_SUPPORT && OMPT_OPTIONAL
980  OMPT_STORE_RETURN_ADDRESS(gtid);
981 #endif
982  __kmpc_init_nest_lock(NULL, gtid, user_lock);
983 #endif
984 }
985 
986 void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_LOCK)(void **user_lock) {
987 #ifdef KMP_STUB
988  *((kmp_stub_lock_t *)user_lock) = UNINIT;
989 #else
990  int gtid = __kmp_entry_gtid();
991 #if OMPT_SUPPORT && OMPT_OPTIONAL
992  OMPT_STORE_RETURN_ADDRESS(gtid);
993 #endif
994  __kmpc_destroy_lock(NULL, gtid, user_lock);
995 #endif
996 }
997 
998 void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)(void **user_lock) {
999 #ifdef KMP_STUB
1000  *((kmp_stub_lock_t *)user_lock) = UNINIT;
1001 #else
1002  int gtid = __kmp_entry_gtid();
1003 #if OMPT_SUPPORT && OMPT_OPTIONAL
1004  OMPT_STORE_RETURN_ADDRESS(gtid);
1005 #endif
1006  __kmpc_destroy_nest_lock(NULL, gtid, user_lock);
1007 #endif
1008 }
1009 
1010 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_LOCK)(void **user_lock) {
1011 #ifdef KMP_STUB
1012  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1013  // TODO: Issue an error.
1014  }
1015  if (*((kmp_stub_lock_t *)user_lock) != UNLOCKED) {
1016  // TODO: Issue an error.
1017  }
1018  *((kmp_stub_lock_t *)user_lock) = LOCKED;
1019 #else
1020  int gtid = __kmp_entry_gtid();
1021 #if OMPT_SUPPORT && OMPT_OPTIONAL
1022  OMPT_STORE_RETURN_ADDRESS(gtid);
1023 #endif
1024  __kmpc_set_lock(NULL, gtid, user_lock);
1025 #endif
1026 }
1027 
1028 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)(void **user_lock) {
1029 #ifdef KMP_STUB
1030  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1031  // TODO: Issue an error.
1032  }
1033  (*((int *)user_lock))++;
1034 #else
1035  int gtid = __kmp_entry_gtid();
1036 #if OMPT_SUPPORT && OMPT_OPTIONAL
1037  OMPT_STORE_RETURN_ADDRESS(gtid);
1038 #endif
1039  __kmpc_set_nest_lock(NULL, gtid, user_lock);
1040 #endif
1041 }
1042 
1043 void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_LOCK)(void **user_lock) {
1044 #ifdef KMP_STUB
1045  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1046  // TODO: Issue an error.
1047  }
1048  if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
1049  // TODO: Issue an error.
1050  }
1051  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
1052 #else
1053  int gtid = __kmp_entry_gtid();
1054 #if OMPT_SUPPORT && OMPT_OPTIONAL
1055  OMPT_STORE_RETURN_ADDRESS(gtid);
1056 #endif
1057  __kmpc_unset_lock(NULL, gtid, user_lock);
1058 #endif
1059 }
1060 
1061 void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)(void **user_lock) {
1062 #ifdef KMP_STUB
1063  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1064  // TODO: Issue an error.
1065  }
1066  if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
1067  // TODO: Issue an error.
1068  }
1069  (*((int *)user_lock))--;
1070 #else
1071  int gtid = __kmp_entry_gtid();
1072 #if OMPT_SUPPORT && OMPT_OPTIONAL
1073  OMPT_STORE_RETURN_ADDRESS(gtid);
1074 #endif
1075  __kmpc_unset_nest_lock(NULL, gtid, user_lock);
1076 #endif
1077 }
1078 
1079 int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_LOCK)(void **user_lock) {
1080 #ifdef KMP_STUB
1081  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1082  // TODO: Issue an error.
1083  }
1084  if (*((kmp_stub_lock_t *)user_lock) == LOCKED) {
1085  return 0;
1086  }
1087  *((kmp_stub_lock_t *)user_lock) = LOCKED;
1088  return 1;
1089 #else
1090  int gtid = __kmp_entry_gtid();
1091 #if OMPT_SUPPORT && OMPT_OPTIONAL
1092  OMPT_STORE_RETURN_ADDRESS(gtid);
1093 #endif
1094  return __kmpc_test_lock(NULL, gtid, user_lock);
1095 #endif
1096 }
1097 
1098 int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)(void **user_lock) {
1099 #ifdef KMP_STUB
1100  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1101  // TODO: Issue an error.
1102  }
1103  return ++(*((int *)user_lock));
1104 #else
1105  int gtid = __kmp_entry_gtid();
1106 #if OMPT_SUPPORT && OMPT_OPTIONAL
1107  OMPT_STORE_RETURN_ADDRESS(gtid);
1108 #endif
1109  return __kmpc_test_nest_lock(NULL, gtid, user_lock);
1110 #endif
1111 }
1112 
1113 double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTIME)(void) {
1114 #ifdef KMP_STUB
1115  return __kmps_get_wtime();
1116 #else
1117  double data;
1118 #if !KMP_OS_LINUX
1119  // We don't need library initialization to get the time on Linux* OS. The
1120  // routine can be used to measure library initialization time on Linux* OS now
1121  if (!__kmp_init_serial) {
1122  __kmp_serial_initialize();
1123  }
1124 #endif
1125  __kmp_elapsed(&data);
1126  return data;
1127 #endif
1128 }
1129 
1130 double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTICK)(void) {
1131 #ifdef KMP_STUB
1132  return __kmps_get_wtick();
1133 #else
1134  double data;
1135  if (!__kmp_init_serial) {
1136  __kmp_serial_initialize();
1137  }
1138  __kmp_elapsed_tick(&data);
1139  return data;
1140 #endif
1141 }
1142 
1143 /* ------------------------------------------------------------------------ */
1144 
1145 void *FTN_STDCALL FTN_MALLOC(size_t KMP_DEREF size) {
1146  // kmpc_malloc initializes the library if needed
1147  return kmpc_malloc(KMP_DEREF size);
1148 }
1149 
1150 void *FTN_STDCALL FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,
1151  size_t KMP_DEREF alignment) {
1152  // kmpc_aligned_malloc initializes the library if needed
1153  return kmpc_aligned_malloc(KMP_DEREF size, KMP_DEREF alignment);
1154 }
1155 
1156 void *FTN_STDCALL FTN_CALLOC(size_t KMP_DEREF nelem, size_t KMP_DEREF elsize) {
1157  // kmpc_calloc initializes the library if needed
1158  return kmpc_calloc(KMP_DEREF nelem, KMP_DEREF elsize);
1159 }
1160 
1161 void *FTN_STDCALL FTN_REALLOC(void *KMP_DEREF ptr, size_t KMP_DEREF size) {
1162  // kmpc_realloc initializes the library if needed
1163  return kmpc_realloc(KMP_DEREF ptr, KMP_DEREF size);
1164 }
1165 
1166 void FTN_STDCALL FTN_KFREE(void *KMP_DEREF ptr) {
1167  // does nothing if the library is not initialized
1168  kmpc_free(KMP_DEREF ptr);
1169 }
1170 
1171 void FTN_STDCALL FTN_SET_WARNINGS_ON(void) {
1172 #ifndef KMP_STUB
1173  __kmp_generate_warnings = kmp_warnings_explicit;
1174 #endif
1175 }
1176 
1177 void FTN_STDCALL FTN_SET_WARNINGS_OFF(void) {
1178 #ifndef KMP_STUB
1179  __kmp_generate_warnings = FALSE;
1180 #endif
1181 }
1182 
1183 void FTN_STDCALL FTN_SET_DEFAULTS(char const *str
1184 #ifndef PASS_ARGS_BY_VALUE
1185  ,
1186  int len
1187 #endif
1188  ) {
1189 #ifndef KMP_STUB
1190 #ifdef PASS_ARGS_BY_VALUE
1191  int len = (int)KMP_STRLEN(str);
1192 #endif
1193  __kmp_aux_set_defaults(str, len);
1194 #endif
1195 }
1196 
1197 /* ------------------------------------------------------------------------ */
1198 
1199 #if OMP_40_ENABLED
1200 /* returns the status of cancellation */
1201 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_CANCELLATION)(void) {
1202 #ifdef KMP_STUB
1203  return 0 /* false */;
1204 #else
1205  // initialize the library if needed
1206  if (!__kmp_init_serial) {
1207  __kmp_serial_initialize();
1208  }
1209  return __kmp_omp_cancellation;
1210 #endif
1211 }
1212 
1213 int FTN_STDCALL FTN_GET_CANCELLATION_STATUS(int cancel_kind) {
1214 #ifdef KMP_STUB
1215  return 0 /* false */;
1216 #else
1217  return __kmp_get_cancellation_status(cancel_kind);
1218 #endif
1219 }
1220 
1221 #endif // OMP_40_ENABLED
1222 
1223 #if OMP_45_ENABLED
1224 /* returns the maximum allowed task priority */
1225 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {
1226 #ifdef KMP_STUB
1227  return 0;
1228 #else
1229  if (!__kmp_init_serial) {
1230  __kmp_serial_initialize();
1231  }
1232  return __kmp_max_task_priority;
1233 #endif
1234 }
1235 #endif
1236 
1237 // GCC compatibility (versioned symbols)
1238 #ifdef KMP_USE_VERSION_SYMBOLS
1239 
1240 /* These following sections create versioned symbols for the
1241  omp_* routines. The KMP_VERSION_SYMBOL macro expands the API name and
1242  then maps it to a versioned symbol.
1243  libgomp ``versions'' its symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also
1244  retaining the default version which libomp uses: VERSION (defined in
1245  exports_so.txt). If you want to see the versioned symbols for libgomp.so.1
1246  then just type:
1247 
1248  objdump -T /path/to/libgomp.so.1 | grep omp_
1249 
1250  Example:
1251  Step 1) Create __kmp_api_omp_set_num_threads_10_alias which is alias of
1252  __kmp_api_omp_set_num_threads
1253  Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version:
1254  omp_set_num_threads@OMP_1.0
1255  Step 2B) Set __kmp_api_omp_set_num_threads to default version:
1256  omp_set_num_threads@@VERSION
1257 */
1258 
1259 // OMP_1.0 versioned symbols
1260 KMP_VERSION_SYMBOL(FTN_SET_NUM_THREADS, 10, "OMP_1.0");
1261 KMP_VERSION_SYMBOL(FTN_GET_NUM_THREADS, 10, "OMP_1.0");
1262 KMP_VERSION_SYMBOL(FTN_GET_MAX_THREADS, 10, "OMP_1.0");
1263 KMP_VERSION_SYMBOL(FTN_GET_THREAD_NUM, 10, "OMP_1.0");
1264 KMP_VERSION_SYMBOL(FTN_GET_NUM_PROCS, 10, "OMP_1.0");
1265 KMP_VERSION_SYMBOL(FTN_IN_PARALLEL, 10, "OMP_1.0");
1266 KMP_VERSION_SYMBOL(FTN_SET_DYNAMIC, 10, "OMP_1.0");
1267 KMP_VERSION_SYMBOL(FTN_GET_DYNAMIC, 10, "OMP_1.0");
1268 KMP_VERSION_SYMBOL(FTN_SET_NESTED, 10, "OMP_1.0");
1269 KMP_VERSION_SYMBOL(FTN_GET_NESTED, 10, "OMP_1.0");
1270 KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 10, "OMP_1.0");
1271 KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");
1272 KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 10, "OMP_1.0");
1273 KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");
1274 KMP_VERSION_SYMBOL(FTN_SET_LOCK, 10, "OMP_1.0");
1275 KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 10, "OMP_1.0");
1276 KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 10, "OMP_1.0");
1277 KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");
1278 KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 10, "OMP_1.0");
1279 KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");
1280 
1281 // OMP_2.0 versioned symbols
1282 KMP_VERSION_SYMBOL(FTN_GET_WTICK, 20, "OMP_2.0");
1283 KMP_VERSION_SYMBOL(FTN_GET_WTIME, 20, "OMP_2.0");
1284 
1285 // OMP_3.0 versioned symbols
1286 KMP_VERSION_SYMBOL(FTN_SET_SCHEDULE, 30, "OMP_3.0");
1287 KMP_VERSION_SYMBOL(FTN_GET_SCHEDULE, 30, "OMP_3.0");
1288 KMP_VERSION_SYMBOL(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");
1289 KMP_VERSION_SYMBOL(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1290 KMP_VERSION_SYMBOL(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1291 KMP_VERSION_SYMBOL(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");
1292 KMP_VERSION_SYMBOL(FTN_GET_LEVEL, 30, "OMP_3.0");
1293 KMP_VERSION_SYMBOL(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");
1294 KMP_VERSION_SYMBOL(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");
1295 
1296 // the lock routines have a 1.0 and 3.0 version
1297 KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 30, "OMP_3.0");
1298 KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");
1299 KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 30, "OMP_3.0");
1300 KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");
1301 KMP_VERSION_SYMBOL(FTN_SET_LOCK, 30, "OMP_3.0");
1302 KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 30, "OMP_3.0");
1303 KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 30, "OMP_3.0");
1304 KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");
1305 KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 30, "OMP_3.0");
1306 KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");
1307 
1308 // OMP_3.1 versioned symbol
1309 KMP_VERSION_SYMBOL(FTN_IN_FINAL, 31, "OMP_3.1");
1310 
1311 #if OMP_40_ENABLED
1312 // OMP_4.0 versioned symbols
1313 KMP_VERSION_SYMBOL(FTN_GET_PROC_BIND, 40, "OMP_4.0");
1314 KMP_VERSION_SYMBOL(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");
1315 KMP_VERSION_SYMBOL(FTN_GET_TEAM_NUM, 40, "OMP_4.0");
1316 KMP_VERSION_SYMBOL(FTN_GET_CANCELLATION, 40, "OMP_4.0");
1317 KMP_VERSION_SYMBOL(FTN_GET_DEFAULT_DEVICE, 40, "OMP_4.0");
1318 KMP_VERSION_SYMBOL(FTN_SET_DEFAULT_DEVICE, 40, "OMP_4.0");
1319 KMP_VERSION_SYMBOL(FTN_IS_INITIAL_DEVICE, 40, "OMP_4.0");
1320 #endif /* OMP_40_ENABLED */
1321 
1322 #if OMP_45_ENABLED
1323 // OMP_4.5 versioned symbols
1324 KMP_VERSION_SYMBOL(FTN_GET_MAX_TASK_PRIORITY, 45, "OMP_4.5");
1325 KMP_VERSION_SYMBOL(FTN_GET_NUM_PLACES, 45, "OMP_4.5");
1326 KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM_PROCS, 45, "OMP_4.5");
1327 KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5");
1328 KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5");
1329 KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5");
1330 KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");
1331 #endif
1332 
1333 #if OMP_50_ENABLED
1334 // OMP_5.0 versioned symbols
1335 #endif
1336 
1337 #endif // KMP_USE_VERSION_SYMBOLS
1338 
1339 #ifdef __cplusplus
1340 } // extern "C"
1341 #endif // __cplusplus
1342 
1343 // end of file //
KMP_EXPORT kmp_int32 __kmpc_bound_num_threads(ident_t *)