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