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,
349  void *arg) {
350 #if defined(KMP_STUB) || !OMPT_SUPPORT
351  return -2;
352 #else
353  OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());
354  if (!TCR_4(__kmp_init_middle)) {
355  return -2;
356  }
357  kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];
358  ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);
359  parent_task_info->frame.enter_frame = OMPT_GET_FRAME_ADDRESS(1);
360  int ret = __kmp_control_tool(command, modifier, arg);
361  parent_task_info->frame.enter_frame = 0;
362  return ret;
363 #endif
364 }
365 #endif
366 
367 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
368 #ifdef KMP_STUB
369  return 0;
370 #else
371  int gtid;
372 
373 #if KMP_OS_DARWIN || KMP_OS_FREEBSD || KMP_OS_NETBSD
374  gtid = __kmp_entry_gtid();
375 #elif KMP_OS_WINDOWS
376  if (!__kmp_init_parallel ||
377  (gtid = (int)((kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key))) ==
378  0) {
379  // Either library isn't initialized or thread is not registered
380  // 0 is the correct TID in this case
381  return 0;
382  }
383  --gtid; // We keep (gtid+1) in TLS
384 #elif KMP_OS_LINUX
385 #ifdef KMP_TDATA_GTID
386  if (__kmp_gtid_mode >= 3) {
387  if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
388  return 0;
389  }
390  } else {
391 #endif
392  if (!__kmp_init_parallel ||
393  (gtid = (kmp_intptr_t)(
394  pthread_getspecific(__kmp_gtid_threadprivate_key))) == 0) {
395  return 0;
396  }
397  --gtid;
398 #ifdef KMP_TDATA_GTID
399  }
400 #endif
401 #else
402 #error Unknown or unsupported OS
403 #endif
404 
405  return __kmp_tid_from_gtid(gtid);
406 #endif
407 }
408 
409 int FTN_STDCALL FTN_GET_NUM_KNOWN_THREADS(void) {
410 #ifdef KMP_STUB
411  return 1;
412 #else
413  if (!__kmp_init_serial) {
414  __kmp_serial_initialize();
415  }
416  /* NOTE: this is not syncronized, so it can change at any moment */
417  /* NOTE: this number also includes threads preallocated in hot-teams */
418  return TCR_4(__kmp_nth);
419 #endif
420 }
421 
422 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)(void) {
423 #ifdef KMP_STUB
424  return 1;
425 #else
426  if (!TCR_4(__kmp_init_middle)) {
427  __kmp_middle_initialize();
428  }
429  return __kmp_avail_proc;
430 #endif
431 }
432 
433 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NESTED)(int KMP_DEREF flag) {
434 #ifdef KMP_STUB
435  __kmps_set_nested(KMP_DEREF flag);
436 #else
437  kmp_info_t *thread;
438  /* For the thread-private internal controls implementation */
439  thread = __kmp_entry_thread();
440  __kmp_save_internal_controls(thread);
441  set__nested(thread, ((KMP_DEREF flag) ? TRUE : FALSE));
442 #endif
443 }
444 
445 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NESTED)(void) {
446 #ifdef KMP_STUB
447  return __kmps_get_nested();
448 #else
449  kmp_info_t *thread;
450  thread = __kmp_entry_thread();
451  return get__nested(thread);
452 #endif
453 }
454 
455 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DYNAMIC)(int KMP_DEREF flag) {
456 #ifdef KMP_STUB
457  __kmps_set_dynamic(KMP_DEREF flag ? TRUE : FALSE);
458 #else
459  kmp_info_t *thread;
460  /* For the thread-private implementation of the internal controls */
461  thread = __kmp_entry_thread();
462  // !!! What if foreign thread calls it?
463  __kmp_save_internal_controls(thread);
464  set__dynamic(thread, KMP_DEREF flag ? TRUE : FALSE);
465 #endif
466 }
467 
468 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DYNAMIC)(void) {
469 #ifdef KMP_STUB
470  return __kmps_get_dynamic();
471 #else
472  kmp_info_t *thread;
473  thread = __kmp_entry_thread();
474  return get__dynamic(thread);
475 #endif
476 }
477 
478 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_PARALLEL)(void) {
479 #ifdef KMP_STUB
480  return 0;
481 #else
482  kmp_info_t *th = __kmp_entry_thread();
483 #if OMP_40_ENABLED
484  if (th->th.th_teams_microtask) {
485  // AC: r_in_parallel does not work inside teams construct where real
486  // parallel is inactive, but all threads have same root, so setting it in
487  // one team affects other teams.
488  // The solution is to use per-team nesting level
489  return (th->th.th_team->t.t_active_level ? 1 : 0);
490  } else
491 #endif /* OMP_40_ENABLED */
492  return (th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE);
493 #endif
494 }
495 
496 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_SCHEDULE)(kmp_sched_t KMP_DEREF kind,
497  int KMP_DEREF modifier) {
498 #ifdef KMP_STUB
499  __kmps_set_schedule(KMP_DEREF kind, KMP_DEREF modifier);
500 #else
501  /* TO DO: For the per-task implementation of the internal controls */
502  __kmp_set_schedule(__kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier);
503 #endif
504 }
505 
506 void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_SCHEDULE)(kmp_sched_t *kind,
507  int *modifier) {
508 #ifdef KMP_STUB
509  __kmps_get_schedule(kind, modifier);
510 #else
511  /* TO DO: For the per-task implementation of the internal controls */
512  __kmp_get_schedule(__kmp_entry_gtid(), kind, modifier);
513 #endif
514 }
515 
516 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)(int KMP_DEREF arg) {
517 #ifdef KMP_STUB
518 // Nothing.
519 #else
520  /* TO DO: We want per-task implementation of this internal control */
521  __kmp_set_max_active_levels(__kmp_entry_gtid(), KMP_DEREF arg);
522 #endif
523 }
524 
525 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)(void) {
526 #ifdef KMP_STUB
527  return 0;
528 #else
529  /* TO DO: We want per-task implementation of this internal control */
530  return __kmp_get_max_active_levels(__kmp_entry_gtid());
531 #endif
532 }
533 
534 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)(void) {
535 #ifdef KMP_STUB
536  return 0; // returns 0 if it is called from the sequential part of the program
537 #else
538  /* TO DO: For the per-task implementation of the internal controls */
539  return __kmp_entry_thread()->th.th_team->t.t_active_level;
540 #endif
541 }
542 
543 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_LEVEL)(void) {
544 #ifdef KMP_STUB
545  return 0; // returns 0 if it is called from the sequential part of the program
546 #else
547  /* TO DO: For the per-task implementation of the internal controls */
548  return __kmp_entry_thread()->th.th_team->t.t_level;
549 #endif
550 }
551 
552 int FTN_STDCALL
553  KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)(int KMP_DEREF level) {
554 #ifdef KMP_STUB
555  return (KMP_DEREF level) ? (-1) : (0);
556 #else
557  return __kmp_get_ancestor_thread_num(__kmp_entry_gtid(), KMP_DEREF level);
558 #endif
559 }
560 
561 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)(int KMP_DEREF level) {
562 #ifdef KMP_STUB
563  return (KMP_DEREF level) ? (-1) : (1);
564 #else
565  return __kmp_get_team_size(__kmp_entry_gtid(), KMP_DEREF level);
566 #endif
567 }
568 
569 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)(void) {
570 #ifdef KMP_STUB
571  return 1; // TO DO: clarify whether it returns 1 or 0?
572 #else
573  if (!__kmp_init_serial) {
574  __kmp_serial_initialize();
575  }
576  /* global ICV */
577  return __kmp_cg_max_nth;
578 #endif
579 }
580 
581 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_FINAL)(void) {
582 #ifdef KMP_STUB
583  return 0; // TO DO: clarify whether it returns 1 or 0?
584 #else
585  if (!TCR_4(__kmp_init_parallel)) {
586  return 0;
587  }
588  return __kmp_entry_thread()->th.th_current_task->td_flags.final;
589 #endif
590 }
591 
592 #if OMP_40_ENABLED
593 
594 kmp_proc_bind_t FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PROC_BIND)(void) {
595 #ifdef KMP_STUB
596  return __kmps_get_proc_bind();
597 #else
598  return get__proc_bind(__kmp_entry_thread());
599 #endif
600 }
601 
602 #if OMP_45_ENABLED
603 int FTN_STDCALL FTN_GET_NUM_PLACES(void) {
604 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
605  return 0;
606 #else
607  if (!TCR_4(__kmp_init_middle)) {
608  __kmp_middle_initialize();
609  }
610  if (!KMP_AFFINITY_CAPABLE())
611  return 0;
612  return __kmp_affinity_num_masks;
613 #endif
614 }
615 
616 int FTN_STDCALL FTN_GET_PLACE_NUM_PROCS(int place_num) {
617 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
618  return 0;
619 #else
620  int i;
621  int retval = 0;
622  if (!TCR_4(__kmp_init_middle)) {
623  __kmp_middle_initialize();
624  }
625  if (!KMP_AFFINITY_CAPABLE())
626  return 0;
627  if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
628  return 0;
629  kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
630  KMP_CPU_SET_ITERATE(i, mask) {
631  if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
632  (!KMP_CPU_ISSET(i, mask))) {
633  continue;
634  }
635  ++retval;
636  }
637  return retval;
638 #endif
639 }
640 
641 void FTN_STDCALL FTN_GET_PLACE_PROC_IDS(int place_num, int *ids) {
642 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
643 // Nothing.
644 #else
645  int i, j;
646  if (!TCR_4(__kmp_init_middle)) {
647  __kmp_middle_initialize();
648  }
649  if (!KMP_AFFINITY_CAPABLE())
650  return;
651  if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks)
652  return;
653  kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
654  j = 0;
655  KMP_CPU_SET_ITERATE(i, mask) {
656  if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
657  (!KMP_CPU_ISSET(i, mask))) {
658  continue;
659  }
660  ids[j++] = i;
661  }
662 #endif
663 }
664 
665 int FTN_STDCALL FTN_GET_PLACE_NUM(void) {
666 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
667  return -1;
668 #else
669  int gtid;
670  kmp_info_t *thread;
671  if (!TCR_4(__kmp_init_middle)) {
672  __kmp_middle_initialize();
673  }
674  if (!KMP_AFFINITY_CAPABLE())
675  return -1;
676  gtid = __kmp_entry_gtid();
677  thread = __kmp_thread_from_gtid(gtid);
678  if (thread->th.th_current_place < 0)
679  return -1;
680  return thread->th.th_current_place;
681 #endif
682 }
683 
684 int FTN_STDCALL FTN_GET_PARTITION_NUM_PLACES(void) {
685 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
686  return 0;
687 #else
688  int gtid, num_places, first_place, last_place;
689  kmp_info_t *thread;
690  if (!TCR_4(__kmp_init_middle)) {
691  __kmp_middle_initialize();
692  }
693  if (!KMP_AFFINITY_CAPABLE())
694  return 0;
695  gtid = __kmp_entry_gtid();
696  thread = __kmp_thread_from_gtid(gtid);
697  first_place = thread->th.th_first_place;
698  last_place = thread->th.th_last_place;
699  if (first_place < 0 || last_place < 0)
700  return 0;
701  if (first_place <= last_place)
702  num_places = last_place - first_place + 1;
703  else
704  num_places = __kmp_affinity_num_masks - first_place + last_place + 1;
705  return num_places;
706 #endif
707 }
708 
709 void FTN_STDCALL FTN_GET_PARTITION_PLACE_NUMS(int *place_nums) {
710 #if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED
711 // Nothing.
712 #else
713  int i, gtid, place_num, first_place, last_place, start, end;
714  kmp_info_t *thread;
715  if (!TCR_4(__kmp_init_middle)) {
716  __kmp_middle_initialize();
717  }
718  if (!KMP_AFFINITY_CAPABLE())
719  return;
720  gtid = __kmp_entry_gtid();
721  thread = __kmp_thread_from_gtid(gtid);
722  first_place = thread->th.th_first_place;
723  last_place = thread->th.th_last_place;
724  if (first_place < 0 || last_place < 0)
725  return;
726  if (first_place <= last_place) {
727  start = first_place;
728  end = last_place;
729  } else {
730  start = last_place;
731  end = first_place;
732  }
733  for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
734  place_nums[i] = place_num;
735  }
736 #endif
737 }
738 #endif
739 
740 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {
741 #ifdef KMP_STUB
742  return 1;
743 #else
744  kmp_info_t *thr = __kmp_entry_thread();
745  if (thr->th.th_teams_microtask) {
746  kmp_team_t *team = thr->th.th_team;
747  int tlevel = thr->th.th_teams_level;
748  int ii = team->t.t_level; // the level of the teams construct
749  int dd = team->t.t_serialized;
750  int level = tlevel + 1;
751  KMP_DEBUG_ASSERT(ii >= tlevel);
752  while (ii > level) {
753  for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
754  }
755  if (team->t.t_serialized && (!dd)) {
756  team = team->t.t_parent;
757  continue;
758  }
759  if (ii > level) {
760  team = team->t.t_parent;
761  ii--;
762  }
763  }
764  if (dd > 1) {
765  return 1; // teams region is serialized ( 1 team of 1 thread ).
766  } else {
767  return team->t.t_parent->t.t_nproc;
768  }
769  } else {
770  return 1;
771  }
772 #endif
773 }
774 
775 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {
776 #ifdef KMP_STUB
777  return 0;
778 #else
779  kmp_info_t *thr = __kmp_entry_thread();
780  if (thr->th.th_teams_microtask) {
781  kmp_team_t *team = thr->th.th_team;
782  int tlevel = thr->th.th_teams_level; // the level of the teams construct
783  int ii = team->t.t_level;
784  int dd = team->t.t_serialized;
785  int level = tlevel + 1;
786  KMP_DEBUG_ASSERT(ii >= tlevel);
787  while (ii > level) {
788  for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
789  }
790  if (team->t.t_serialized && (!dd)) {
791  team = team->t.t_parent;
792  continue;
793  }
794  if (ii > level) {
795  team = team->t.t_parent;
796  ii--;
797  }
798  }
799  if (dd > 1) {
800  return 0; // teams region is serialized ( 1 team of 1 thread ).
801  } else {
802  return team->t.t_master_tid;
803  }
804  } else {
805  return 0;
806  }
807 #endif
808 }
809 
810 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)(void) {
811 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
812  return 0;
813 #else
814  return __kmp_entry_thread()->th.th_current_task->td_icvs.default_device;
815 #endif
816 }
817 
818 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
819 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
820 // Nothing.
821 #else
822  __kmp_entry_thread()->th.th_current_task->td_icvs.default_device =
823  KMP_DEREF arg;
824 #endif
825 }
826 
827 #if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
828 
829 int FTN_STDCALL FTN_GET_NUM_DEVICES(void) { return 0; }
830 
831 #endif // KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
832 
833 #if !KMP_OS_LINUX
834 
835 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) { return 1; }
836 
837 #else
838 
839 // This internal function is used when the entry from the offload library
840 // is not found.
841 int _Offload_get_device_number(void) KMP_WEAK_ATTRIBUTE;
842 
843 int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {
844  if (_Offload_get_device_number) {
845  return _Offload_get_device_number() == -1;
846  } else {
847  return 1;
848  }
849 }
850 
851 #endif // ! KMP_OS_LINUX
852 
853 #endif // OMP_40_ENABLED
854 
855 #if OMP_45_ENABLED && defined(KMP_STUB)
856 // OpenMP 4.5 entries for stubs library
857 
858 int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) { return -1; }
859 
860 // As all *target* functions are C-only parameters always passed by value
861 void *FTN_STDCALL FTN_TARGET_ALLOC(size_t size, int device_num) { return 0; }
862 
863 void FTN_STDCALL FTN_TARGET_FREE(void *device_ptr, int device_num) {}
864 
865 int FTN_STDCALL FTN_TARGET_IS_PRESENT(void *ptr, int device_num) { return 0; }
866 
867 int FTN_STDCALL FTN_TARGET_MEMCPY(void *dst, void *src, size_t length,
868  size_t dst_offset, size_t src_offset,
869  int dst_device, int src_device) {
870  return -1;
871 }
872 
873 int FTN_STDCALL FTN_TARGET_MEMCPY_RECT(
874  void *dst, void *src, size_t element_size, int num_dims,
875  const size_t *volume, const size_t *dst_offsets, const size_t *src_offsets,
876  const size_t *dst_dimensions, const size_t *src_dimensions, int dst_device,
877  int src_device) {
878  return -1;
879 }
880 
881 int FTN_STDCALL FTN_TARGET_ASSOCIATE_PTR(void *host_ptr, void *device_ptr,
882  size_t size, size_t device_offset,
883  int device_num) {
884  return -1;
885 }
886 
887 int FTN_STDCALL FTN_TARGET_DISASSOCIATE_PTR(void *host_ptr, int device_num) {
888  return -1;
889 }
890 #endif // OMP_45_ENABLED && defined(KMP_STUB)
891 
892 #ifdef KMP_STUB
893 typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;
894 #endif /* KMP_STUB */
895 
896 #if KMP_USE_DYNAMIC_LOCK
897 void FTN_STDCALL FTN_INIT_LOCK_WITH_HINT(void **user_lock,
898  uintptr_t KMP_DEREF hint) {
899 #ifdef KMP_STUB
900  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
901 #else
902  int gtid = __kmp_entry_gtid();
903 #if OMPT_SUPPORT && OMPT_OPTIONAL
904  OMPT_STORE_RETURN_ADDRESS(gtid);
905 #endif
906  __kmpc_init_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
907 #endif
908 }
909 
910 void FTN_STDCALL FTN_INIT_NEST_LOCK_WITH_HINT(void **user_lock,
911  uintptr_t KMP_DEREF hint) {
912 #ifdef KMP_STUB
913  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
914 #else
915  int gtid = __kmp_entry_gtid();
916 #if OMPT_SUPPORT && OMPT_OPTIONAL
917  OMPT_STORE_RETURN_ADDRESS(gtid);
918 #endif
919  __kmpc_init_nest_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);
920 #endif
921 }
922 #endif
923 
924 /* initialize the lock */
925 void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_LOCK)(void **user_lock) {
926 #ifdef KMP_STUB
927  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
928 #else
929  int gtid = __kmp_entry_gtid();
930 #if OMPT_SUPPORT && OMPT_OPTIONAL
931  OMPT_STORE_RETURN_ADDRESS(gtid);
932 #endif
933  __kmpc_init_lock(NULL, gtid, user_lock);
934 #endif
935 }
936 
937 /* initialize the lock */
938 void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)(void **user_lock) {
939 #ifdef KMP_STUB
940  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
941 #else
942  int gtid = __kmp_entry_gtid();
943 #if OMPT_SUPPORT && OMPT_OPTIONAL
944  OMPT_STORE_RETURN_ADDRESS(gtid);
945 #endif
946  __kmpc_init_nest_lock(NULL, gtid, user_lock);
947 #endif
948 }
949 
950 void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_LOCK)(void **user_lock) {
951 #ifdef KMP_STUB
952  *((kmp_stub_lock_t *)user_lock) = UNINIT;
953 #else
954  int gtid = __kmp_entry_gtid();
955 #if OMPT_SUPPORT && OMPT_OPTIONAL
956  OMPT_STORE_RETURN_ADDRESS(gtid);
957 #endif
958  __kmpc_destroy_lock(NULL, gtid, user_lock);
959 #endif
960 }
961 
962 void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)(void **user_lock) {
963 #ifdef KMP_STUB
964  *((kmp_stub_lock_t *)user_lock) = UNINIT;
965 #else
966  int gtid = __kmp_entry_gtid();
967 #if OMPT_SUPPORT && OMPT_OPTIONAL
968  OMPT_STORE_RETURN_ADDRESS(gtid);
969 #endif
970  __kmpc_destroy_nest_lock(NULL, gtid, user_lock);
971 #endif
972 }
973 
974 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_LOCK)(void **user_lock) {
975 #ifdef KMP_STUB
976  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
977  // TODO: Issue an error.
978  }
979  if (*((kmp_stub_lock_t *)user_lock) != UNLOCKED) {
980  // TODO: Issue an error.
981  }
982  *((kmp_stub_lock_t *)user_lock) = LOCKED;
983 #else
984  int gtid = __kmp_entry_gtid();
985 #if OMPT_SUPPORT && OMPT_OPTIONAL
986  OMPT_STORE_RETURN_ADDRESS(gtid);
987 #endif
988  __kmpc_set_lock(NULL, gtid, user_lock);
989 #endif
990 }
991 
992 void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)(void **user_lock) {
993 #ifdef KMP_STUB
994  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
995  // TODO: Issue an error.
996  }
997  (*((int *)user_lock))++;
998 #else
999  int gtid = __kmp_entry_gtid();
1000 #if OMPT_SUPPORT && OMPT_OPTIONAL
1001  OMPT_STORE_RETURN_ADDRESS(gtid);
1002 #endif
1003  __kmpc_set_nest_lock(NULL, gtid, user_lock);
1004 #endif
1005 }
1006 
1007 void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_LOCK)(void **user_lock) {
1008 #ifdef KMP_STUB
1009  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1010  // TODO: Issue an error.
1011  }
1012  if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
1013  // TODO: Issue an error.
1014  }
1015  *((kmp_stub_lock_t *)user_lock) = UNLOCKED;
1016 #else
1017  int gtid = __kmp_entry_gtid();
1018 #if OMPT_SUPPORT && OMPT_OPTIONAL
1019  OMPT_STORE_RETURN_ADDRESS(gtid);
1020 #endif
1021  __kmpc_unset_lock(NULL, gtid, user_lock);
1022 #endif
1023 }
1024 
1025 void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)(void **user_lock) {
1026 #ifdef KMP_STUB
1027  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1028  // TODO: Issue an error.
1029  }
1030  if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {
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_unset_nest_lock(NULL, gtid, user_lock);
1040 #endif
1041 }
1042 
1043 int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_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) == LOCKED) {
1049  return 0;
1050  }
1051  *((kmp_stub_lock_t *)user_lock) = LOCKED;
1052  return 1;
1053 #else
1054  int gtid = __kmp_entry_gtid();
1055 #if OMPT_SUPPORT && OMPT_OPTIONAL
1056  OMPT_STORE_RETURN_ADDRESS(gtid);
1057 #endif
1058  return __kmpc_test_lock(NULL, gtid, user_lock);
1059 #endif
1060 }
1061 
1062 int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)(void **user_lock) {
1063 #ifdef KMP_STUB
1064  if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {
1065  // TODO: Issue an error.
1066  }
1067  return ++(*((int *)user_lock));
1068 #else
1069  int gtid = __kmp_entry_gtid();
1070 #if OMPT_SUPPORT && OMPT_OPTIONAL
1071  OMPT_STORE_RETURN_ADDRESS(gtid);
1072 #endif
1073  return __kmpc_test_nest_lock(NULL, gtid, user_lock);
1074 #endif
1075 }
1076 
1077 double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTIME)(void) {
1078 #ifdef KMP_STUB
1079  return __kmps_get_wtime();
1080 #else
1081  double data;
1082 #if !KMP_OS_LINUX
1083  // We don't need library initialization to get the time on Linux* OS. The
1084  // routine can be used to measure library initialization time on Linux* OS now
1085  if (!__kmp_init_serial) {
1086  __kmp_serial_initialize();
1087  }
1088 #endif
1089  __kmp_elapsed(&data);
1090  return data;
1091 #endif
1092 }
1093 
1094 double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTICK)(void) {
1095 #ifdef KMP_STUB
1096  return __kmps_get_wtick();
1097 #else
1098  double data;
1099  if (!__kmp_init_serial) {
1100  __kmp_serial_initialize();
1101  }
1102  __kmp_elapsed_tick(&data);
1103  return data;
1104 #endif
1105 }
1106 
1107 /* ------------------------------------------------------------------------ */
1108 
1109 void *FTN_STDCALL FTN_MALLOC(size_t KMP_DEREF size) {
1110  // kmpc_malloc initializes the library if needed
1111  return kmpc_malloc(KMP_DEREF size);
1112 }
1113 
1114 void *FTN_STDCALL FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,
1115  size_t KMP_DEREF alignment) {
1116  // kmpc_aligned_malloc initializes the library if needed
1117  return kmpc_aligned_malloc(KMP_DEREF size, KMP_DEREF alignment);
1118 }
1119 
1120 void *FTN_STDCALL FTN_CALLOC(size_t KMP_DEREF nelem, size_t KMP_DEREF elsize) {
1121  // kmpc_calloc initializes the library if needed
1122  return kmpc_calloc(KMP_DEREF nelem, KMP_DEREF elsize);
1123 }
1124 
1125 void *FTN_STDCALL FTN_REALLOC(void *KMP_DEREF ptr, size_t KMP_DEREF size) {
1126  // kmpc_realloc initializes the library if needed
1127  return kmpc_realloc(KMP_DEREF ptr, KMP_DEREF size);
1128 }
1129 
1130 void FTN_STDCALL FTN_FREE(void *KMP_DEREF ptr) {
1131  // does nothing if the library is not initialized
1132  kmpc_free(KMP_DEREF ptr);
1133 }
1134 
1135 void FTN_STDCALL FTN_SET_WARNINGS_ON(void) {
1136 #ifndef KMP_STUB
1137  __kmp_generate_warnings = kmp_warnings_explicit;
1138 #endif
1139 }
1140 
1141 void FTN_STDCALL FTN_SET_WARNINGS_OFF(void) {
1142 #ifndef KMP_STUB
1143  __kmp_generate_warnings = FALSE;
1144 #endif
1145 }
1146 
1147 void FTN_STDCALL FTN_SET_DEFAULTS(char const *str
1148 #ifndef PASS_ARGS_BY_VALUE
1149  ,
1150  int len
1151 #endif
1152  ) {
1153 #ifndef KMP_STUB
1154 #ifdef PASS_ARGS_BY_VALUE
1155  int len = (int)KMP_STRLEN(str);
1156 #endif
1157  __kmp_aux_set_defaults(str, len);
1158 #endif
1159 }
1160 
1161 /* ------------------------------------------------------------------------ */
1162 
1163 #if OMP_40_ENABLED
1164 /* returns the status of cancellation */
1165 int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_CANCELLATION)(void) {
1166 #ifdef KMP_STUB
1167  return 0 /* false */;
1168 #else
1169  // initialize the library if needed
1170  if (!__kmp_init_serial) {
1171  __kmp_serial_initialize();
1172  }
1173  return __kmp_omp_cancellation;
1174 #endif
1175 }
1176 
1177 int FTN_STDCALL FTN_GET_CANCELLATION_STATUS(int cancel_kind) {
1178 #ifdef KMP_STUB
1179  return 0 /* false */;
1180 #else
1181  return __kmp_get_cancellation_status(cancel_kind);
1182 #endif
1183 }
1184 
1185 #endif // OMP_40_ENABLED
1186 
1187 #if OMP_45_ENABLED
1188 /* returns the maximum allowed task priority */
1189 int FTN_STDCALL FTN_GET_MAX_TASK_PRIORITY(void) {
1190 #ifdef KMP_STUB
1191  return 0;
1192 #else
1193  if (!__kmp_init_serial) {
1194  __kmp_serial_initialize();
1195  }
1196  return __kmp_max_task_priority;
1197 #endif
1198 }
1199 #endif
1200 
1201 // GCC compatibility (versioned symbols)
1202 #ifdef KMP_USE_VERSION_SYMBOLS
1203 
1204 /* These following sections create versioned symbols for the
1205  omp_* routines. The KMP_VERSION_SYMBOL macro expands the API name and
1206  then maps it to a versioned symbol.
1207  libgomp ``versions'' its symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also
1208  retaining the default version which libomp uses: VERSION (defined in
1209  exports_so.txt). If you want to see the versioned symbols for libgomp.so.1
1210  then just type:
1211 
1212  objdump -T /path/to/libgomp.so.1 | grep omp_
1213 
1214  Example:
1215  Step 1) Create __kmp_api_omp_set_num_threads_10_alias which is alias of
1216  __kmp_api_omp_set_num_threads
1217  Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version:
1218  omp_set_num_threads@OMP_1.0
1219  Step 2B) Set __kmp_api_omp_set_num_threads to default version:
1220  omp_set_num_threads@@VERSION
1221 */
1222 
1223 // OMP_1.0 versioned symbols
1224 KMP_VERSION_SYMBOL(FTN_SET_NUM_THREADS, 10, "OMP_1.0");
1225 KMP_VERSION_SYMBOL(FTN_GET_NUM_THREADS, 10, "OMP_1.0");
1226 KMP_VERSION_SYMBOL(FTN_GET_MAX_THREADS, 10, "OMP_1.0");
1227 KMP_VERSION_SYMBOL(FTN_GET_THREAD_NUM, 10, "OMP_1.0");
1228 KMP_VERSION_SYMBOL(FTN_GET_NUM_PROCS, 10, "OMP_1.0");
1229 KMP_VERSION_SYMBOL(FTN_IN_PARALLEL, 10, "OMP_1.0");
1230 KMP_VERSION_SYMBOL(FTN_SET_DYNAMIC, 10, "OMP_1.0");
1231 KMP_VERSION_SYMBOL(FTN_GET_DYNAMIC, 10, "OMP_1.0");
1232 KMP_VERSION_SYMBOL(FTN_SET_NESTED, 10, "OMP_1.0");
1233 KMP_VERSION_SYMBOL(FTN_GET_NESTED, 10, "OMP_1.0");
1234 KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 10, "OMP_1.0");
1235 KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");
1236 KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 10, "OMP_1.0");
1237 KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");
1238 KMP_VERSION_SYMBOL(FTN_SET_LOCK, 10, "OMP_1.0");
1239 KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 10, "OMP_1.0");
1240 KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 10, "OMP_1.0");
1241 KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");
1242 KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 10, "OMP_1.0");
1243 KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");
1244 
1245 // OMP_2.0 versioned symbols
1246 KMP_VERSION_SYMBOL(FTN_GET_WTICK, 20, "OMP_2.0");
1247 KMP_VERSION_SYMBOL(FTN_GET_WTIME, 20, "OMP_2.0");
1248 
1249 // OMP_3.0 versioned symbols
1250 KMP_VERSION_SYMBOL(FTN_SET_SCHEDULE, 30, "OMP_3.0");
1251 KMP_VERSION_SYMBOL(FTN_GET_SCHEDULE, 30, "OMP_3.0");
1252 KMP_VERSION_SYMBOL(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");
1253 KMP_VERSION_SYMBOL(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1254 KMP_VERSION_SYMBOL(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");
1255 KMP_VERSION_SYMBOL(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");
1256 KMP_VERSION_SYMBOL(FTN_GET_LEVEL, 30, "OMP_3.0");
1257 KMP_VERSION_SYMBOL(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");
1258 KMP_VERSION_SYMBOL(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");
1259 
1260 // the lock routines have a 1.0 and 3.0 version
1261 KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 30, "OMP_3.0");
1262 KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");
1263 KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 30, "OMP_3.0");
1264 KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");
1265 KMP_VERSION_SYMBOL(FTN_SET_LOCK, 30, "OMP_3.0");
1266 KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 30, "OMP_3.0");
1267 KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 30, "OMP_3.0");
1268 KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");
1269 KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 30, "OMP_3.0");
1270 KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");
1271 
1272 // OMP_3.1 versioned symbol
1273 KMP_VERSION_SYMBOL(FTN_IN_FINAL, 31, "OMP_3.1");
1274 
1275 #if OMP_40_ENABLED
1276 // OMP_4.0 versioned symbols
1277 KMP_VERSION_SYMBOL(FTN_GET_PROC_BIND, 40, "OMP_4.0");
1278 KMP_VERSION_SYMBOL(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");
1279 KMP_VERSION_SYMBOL(FTN_GET_TEAM_NUM, 40, "OMP_4.0");
1280 KMP_VERSION_SYMBOL(FTN_GET_CANCELLATION, 40, "OMP_4.0");
1281 KMP_VERSION_SYMBOL(FTN_GET_DEFAULT_DEVICE, 40, "OMP_4.0");
1282 KMP_VERSION_SYMBOL(FTN_SET_DEFAULT_DEVICE, 40, "OMP_4.0");
1283 KMP_VERSION_SYMBOL(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 *)