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