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