1 //===------- interface.h - OpenMP interface definitions ---------- CUDA -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file contains all the definitions that are relevant to
10 //  the interface. The first section contains the interface as
11 //  declared by OpenMP.  The second section includes the compiler
12 //  specific interfaces.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef _INTERFACES_H_
17 #define _INTERFACES_H_
18 
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 #ifdef __AMDGCN__
23 #include "amdgcn/src/amdgcn_interface.h"
24 #endif
25 #ifdef __CUDACC__
26 #include "nvptx/src/nvptx_interface.h"
27 #endif
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 // OpenMP interface
31 ////////////////////////////////////////////////////////////////////////////////
32 
33 typedef uint64_t omp_nest_lock_t; /* arbitrary type of the right length */
34 
35 typedef enum omp_sched_t {
36   omp_sched_static = 1,  /* chunkSize >0 */
37   omp_sched_dynamic = 2, /* chunkSize >0 */
38   omp_sched_guided = 3,  /* chunkSize >0 */
39   omp_sched_auto = 4,    /* no chunkSize */
40 } omp_sched_t;
41 
42 typedef enum omp_proc_bind_t {
43   omp_proc_bind_false = 0,
44   omp_proc_bind_true = 1,
45   omp_proc_bind_master = 2,
46   omp_proc_bind_close = 3,
47   omp_proc_bind_spread = 4
48 } omp_proc_bind_t;
49 
50 EXTERN double omp_get_wtick(void);
51 EXTERN double omp_get_wtime(void);
52 
53 EXTERN void omp_set_num_threads(int num);
54 EXTERN int omp_get_num_threads(void);
55 EXTERN int omp_get_max_threads(void);
56 EXTERN int omp_get_thread_limit(void);
57 EXTERN int omp_get_thread_num(void);
58 EXTERN int omp_get_num_procs(void);
59 EXTERN int omp_in_parallel(void);
60 EXTERN int omp_in_final(void);
61 EXTERN void omp_set_dynamic(int flag);
62 EXTERN int omp_get_dynamic(void);
63 EXTERN void omp_set_nested(int flag);
64 EXTERN int omp_get_nested(void);
65 EXTERN void omp_set_max_active_levels(int level);
66 EXTERN int omp_get_max_active_levels(void);
67 EXTERN int omp_get_level(void);
68 EXTERN int omp_get_active_level(void);
69 EXTERN int omp_get_ancestor_thread_num(int level);
70 EXTERN int omp_get_team_size(int level);
71 
72 EXTERN void omp_init_lock(omp_lock_t *lock);
73 EXTERN void omp_init_nest_lock(omp_nest_lock_t *lock);
74 EXTERN void omp_destroy_lock(omp_lock_t *lock);
75 EXTERN void omp_destroy_nest_lock(omp_nest_lock_t *lock);
76 EXTERN void omp_set_lock(omp_lock_t *lock);
77 EXTERN void omp_set_nest_lock(omp_nest_lock_t *lock);
78 EXTERN void omp_unset_lock(omp_lock_t *lock);
79 EXTERN void omp_unset_nest_lock(omp_nest_lock_t *lock);
80 EXTERN int omp_test_lock(omp_lock_t *lock);
81 EXTERN int omp_test_nest_lock(omp_nest_lock_t *lock);
82 
83 EXTERN void omp_get_schedule(omp_sched_t *kind, int *modifier);
84 EXTERN void omp_set_schedule(omp_sched_t kind, int modifier);
85 EXTERN omp_proc_bind_t omp_get_proc_bind(void);
86 EXTERN int omp_get_cancellation(void);
87 EXTERN void omp_set_default_device(int deviceId);
88 EXTERN int omp_get_default_device(void);
89 EXTERN int omp_get_num_devices(void);
90 EXTERN int omp_get_num_teams(void);
91 EXTERN int omp_get_team_num(void);
92 EXTERN int omp_get_initial_device(void);
93 EXTERN int omp_get_max_task_priority(void);
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 // file below is swiped from kmpc host interface
97 ////////////////////////////////////////////////////////////////////////////////
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 // kmp specific types
101 ////////////////////////////////////////////////////////////////////////////////
102 
103 typedef enum kmp_sched_t {
104   kmp_sched_static_chunk = 33,
105   kmp_sched_static_nochunk = 34,
106   kmp_sched_dynamic = 35,
107   kmp_sched_guided = 36,
108   kmp_sched_runtime = 37,
109   kmp_sched_auto = 38,
110 
111   kmp_sched_static_balanced_chunk = 45,
112 
113   kmp_sched_static_ordered = 65,
114   kmp_sched_static_nochunk_ordered = 66,
115   kmp_sched_dynamic_ordered = 67,
116   kmp_sched_guided_ordered = 68,
117   kmp_sched_runtime_ordered = 69,
118   kmp_sched_auto_ordered = 70,
119 
120   kmp_sched_distr_static_chunk = 91,
121   kmp_sched_distr_static_nochunk = 92,
122   kmp_sched_distr_static_chunk_sched_static_chunkone = 93,
123 
124   kmp_sched_default = kmp_sched_static_nochunk,
125   kmp_sched_unordered_first = kmp_sched_static_chunk,
126   kmp_sched_unordered_last = kmp_sched_auto,
127   kmp_sched_ordered_first = kmp_sched_static_ordered,
128   kmp_sched_ordered_last = kmp_sched_auto_ordered,
129   kmp_sched_distribute_first = kmp_sched_distr_static_chunk,
130   kmp_sched_distribute_last =
131       kmp_sched_distr_static_chunk_sched_static_chunkone,
132 
133   /* Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
134    * Since we need to distinguish the three possible cases (no modifier,
135    * monotonic modifier, nonmonotonic modifier), we need separate bits for
136    * each modifier. The absence of monotonic does not imply nonmonotonic,
137    * especially since 4.5 says that the behaviour of the "no modifier" case
138    * is implementation defined in 4.5, but will become "nonmonotonic" in 5.0.
139    *
140    * Since we're passing a full 32 bit value, we can use a couple of high
141    * bits for these flags; out of paranoia we avoid the sign bit.
142    *
143    * These modifiers can be or-ed into non-static schedules by the compiler
144    * to pass the additional information. They will be stripped early in the
145    * processing in __kmp_dispatch_init when setting up schedules, so
146    * most of the code won't ever see schedules with these bits set.
147    */
148   kmp_sched_modifier_monotonic = (1 << 29),
149   /**< Set if the monotonic schedule modifier was present */
150   kmp_sched_modifier_nonmonotonic = (1 << 30),
151 /**< Set if the nonmonotonic schedule modifier was present */
152 
153 #define SCHEDULE_WITHOUT_MODIFIERS(s)                                          \
154   (enum kmp_sched_t)(                                                          \
155       (s) & ~(kmp_sched_modifier_nonmonotonic | kmp_sched_modifier_monotonic))
156 #define SCHEDULE_HAS_MONOTONIC(s) (((s)&kmp_sched_modifier_monotonic) != 0)
157 #define SCHEDULE_HAS_NONMONOTONIC(s)                                           \
158   (((s)&kmp_sched_modifier_nonmonotonic) != 0)
159 #define SCHEDULE_HAS_NO_MODIFIERS(s)                                           \
160   (((s) & (kmp_sched_modifier_nonmonotonic | kmp_sched_modifier_monotonic)) == \
161    0)
162 
163 } kmp_sched_t;
164 
165 /*!
166  * Enum for accesseing the reserved_2 field of the ident_t struct below.
167  */
168 enum {
169   /*! Bit set to 1 when in SPMD mode. */
170   KMP_IDENT_SPMD_MODE = 0x01,
171   /*! Bit set to 1 when a simplified runtime is used. */
172   KMP_IDENT_SIMPLE_RT_MODE = 0x02,
173 };
174 
175 /*!
176  * The ident structure that describes a source location.
177  * The struct is identical to the one in the kmp.h file.
178  * We maintain the same data structure for compatibility.
179  */
180 typedef short kmp_int16;
181 typedef int kmp_int32;
182 typedef struct ident {
183   kmp_int32 reserved_1; /**<  might be used in Fortran; see above  */
184   kmp_int32 flags;      /**<  also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC
185                            identifies this union member  */
186   kmp_int32 reserved_2; /**<  not really used in Fortran any more; see above */
187   kmp_int32 reserved_3; /**<  source[4] in Fortran, do not use for C++  */
188   char const *psource;  /**<  String describing the source location.
189                         The string is composed of semi-colon separated fields
190                         which describe the source file, the function and a pair
191                         of line numbers that delimit the construct. */
192 } ident_t;
193 
194 // parallel defs
195 typedef ident_t kmp_Ident;
196 typedef void (*kmp_InterWarpCopyFctPtr)(void *src, int32_t warp_num);
197 typedef void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id,
198                                         int16_t lane_offset,
199                                         int16_t shortCircuit);
200 typedef void (*kmp_ListGlobalFctPtr)(void *buffer, int idx, void *reduce_data);
201 
202 // task defs
203 typedef struct kmp_TaskDescr kmp_TaskDescr;
204 typedef int32_t (*kmp_TaskFctPtr)(int32_t global_tid, kmp_TaskDescr *taskDescr);
205 typedef struct kmp_TaskDescr {
206   void *sharedPointerTable;   // ptr to a table of shared var ptrs
207   kmp_TaskFctPtr sub;         // task subroutine
208   int32_t partId;             // unused
209   kmp_TaskFctPtr destructors; // destructor of c++ first private
210 } kmp_TaskDescr;
211 
212 // sync defs
213 typedef int32_t kmp_CriticalName[8];
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 // external interface
217 ////////////////////////////////////////////////////////////////////////////////
218 
219 // parallel
220 EXTERN int32_t __kmpc_global_thread_num(kmp_Ident *loc);
221 EXTERN void __kmpc_push_num_threads(kmp_Ident *loc, int32_t global_tid,
222                                     int32_t num_threads);
223 EXTERN void __kmpc_serialized_parallel(kmp_Ident *loc, uint32_t global_tid);
224 EXTERN void __kmpc_end_serialized_parallel(kmp_Ident *loc, uint32_t global_tid);
225 NOINLINE EXTERN uint8_t __kmpc_parallel_level();
226 
227 // proc bind
228 EXTERN void __kmpc_push_proc_bind(kmp_Ident *loc, uint32_t global_tid,
229                                   int proc_bind);
230 EXTERN int omp_get_num_places(void);
231 EXTERN int omp_get_place_num_procs(int place_num);
232 EXTERN void omp_get_place_proc_ids(int place_num, int *ids);
233 EXTERN int omp_get_place_num(void);
234 EXTERN int omp_get_partition_num_places(void);
235 EXTERN void omp_get_partition_place_nums(int *place_nums);
236 
237 // for static (no chunk or chunk)
238 EXTERN void __kmpc_for_static_init_4(kmp_Ident *loc, int32_t global_tid,
239                                      int32_t sched, int32_t *plastiter,
240                                      int32_t *plower, int32_t *pupper,
241                                      int32_t *pstride, int32_t incr,
242                                      int32_t chunk);
243 EXTERN void __kmpc_for_static_init_4u(kmp_Ident *loc, int32_t global_tid,
244                                       int32_t sched, int32_t *plastiter,
245                                       uint32_t *plower, uint32_t *pupper,
246                                       int32_t *pstride, int32_t incr,
247                                       int32_t chunk);
248 EXTERN void __kmpc_for_static_init_8(kmp_Ident *loc, int32_t global_tid,
249                                      int32_t sched, int32_t *plastiter,
250                                      int64_t *plower, int64_t *pupper,
251                                      int64_t *pstride, int64_t incr,
252                                      int64_t chunk);
253 EXTERN void __kmpc_for_static_init_8u(kmp_Ident *loc, int32_t global_tid,
254                                       int32_t sched, int32_t *plastiter1,
255                                       uint64_t *plower, uint64_t *pupper,
256                                       int64_t *pstride, int64_t incr,
257                                       int64_t chunk);
258 EXTERN
259 void __kmpc_for_static_init_4_simple_spmd(kmp_Ident *loc, int32_t global_tid,
260                                           int32_t sched, int32_t *plastiter,
261                                           int32_t *plower, int32_t *pupper,
262                                           int32_t *pstride, int32_t incr,
263                                           int32_t chunk);
264 EXTERN
265 void __kmpc_for_static_init_4u_simple_spmd(kmp_Ident *loc, int32_t global_tid,
266                                            int32_t sched, int32_t *plastiter,
267                                            uint32_t *plower, uint32_t *pupper,
268                                            int32_t *pstride, int32_t incr,
269                                            int32_t chunk);
270 EXTERN
271 void __kmpc_for_static_init_8_simple_spmd(kmp_Ident *loc, int32_t global_tid,
272                                           int32_t sched, int32_t *plastiter,
273                                           int64_t *plower, int64_t *pupper,
274                                           int64_t *pstride, int64_t incr,
275                                           int64_t chunk);
276 EXTERN
277 void __kmpc_for_static_init_8u_simple_spmd(kmp_Ident *loc, int32_t global_tid,
278                                            int32_t sched, int32_t *plastiter1,
279                                            uint64_t *plower, uint64_t *pupper,
280                                            int64_t *pstride, int64_t incr,
281                                            int64_t chunk);
282 EXTERN
283 void __kmpc_for_static_init_4_simple_generic(kmp_Ident *loc, int32_t global_tid,
284                                              int32_t sched, int32_t *plastiter,
285                                              int32_t *plower, int32_t *pupper,
286                                              int32_t *pstride, int32_t incr,
287                                              int32_t chunk);
288 EXTERN
289 void __kmpc_for_static_init_4u_simple_generic(
290     kmp_Ident *loc, int32_t global_tid, int32_t sched, int32_t *plastiter,
291     uint32_t *plower, uint32_t *pupper, int32_t *pstride, int32_t incr,
292     int32_t chunk);
293 EXTERN
294 void __kmpc_for_static_init_8_simple_generic(kmp_Ident *loc, int32_t global_tid,
295                                              int32_t sched, int32_t *plastiter,
296                                              int64_t *plower, int64_t *pupper,
297                                              int64_t *pstride, int64_t incr,
298                                              int64_t chunk);
299 EXTERN
300 void __kmpc_for_static_init_8u_simple_generic(
301     kmp_Ident *loc, int32_t global_tid, int32_t sched, int32_t *plastiter1,
302     uint64_t *plower, uint64_t *pupper, int64_t *pstride, int64_t incr,
303     int64_t chunk);
304 
305 EXTERN void __kmpc_for_static_fini(kmp_Ident *loc, int32_t global_tid);
306 
307 // for dynamic
308 EXTERN void __kmpc_dispatch_init_4(kmp_Ident *loc, int32_t global_tid,
309                                    int32_t sched, int32_t lower, int32_t upper,
310                                    int32_t incr, int32_t chunk);
311 EXTERN void __kmpc_dispatch_init_4u(kmp_Ident *loc, int32_t global_tid,
312                                     int32_t sched, uint32_t lower,
313                                     uint32_t upper, int32_t incr,
314                                     int32_t chunk);
315 EXTERN void __kmpc_dispatch_init_8(kmp_Ident *loc, int32_t global_tid,
316                                    int32_t sched, int64_t lower, int64_t upper,
317                                    int64_t incr, int64_t chunk);
318 EXTERN void __kmpc_dispatch_init_8u(kmp_Ident *loc, int32_t global_tid,
319                                     int32_t sched, uint64_t lower,
320                                     uint64_t upper, int64_t incr,
321                                     int64_t chunk);
322 
323 EXTERN int __kmpc_dispatch_next_4(kmp_Ident *loc, int32_t global_tid,
324                                   int32_t *plastiter, int32_t *plower,
325                                   int32_t *pupper, int32_t *pstride);
326 EXTERN int __kmpc_dispatch_next_4u(kmp_Ident *loc, int32_t global_tid,
327                                    int32_t *plastiter, uint32_t *plower,
328                                    uint32_t *pupper, int32_t *pstride);
329 EXTERN int __kmpc_dispatch_next_8(kmp_Ident *loc, int32_t global_tid,
330                                   int32_t *plastiter, int64_t *plower,
331                                   int64_t *pupper, int64_t *pstride);
332 EXTERN int __kmpc_dispatch_next_8u(kmp_Ident *loc, int32_t global_tid,
333                                    int32_t *plastiter, uint64_t *plower,
334                                    uint64_t *pupper, int64_t *pstride);
335 
336 EXTERN void __kmpc_dispatch_fini_4(kmp_Ident *loc, int32_t global_tid);
337 EXTERN void __kmpc_dispatch_fini_4u(kmp_Ident *loc, int32_t global_tid);
338 EXTERN void __kmpc_dispatch_fini_8(kmp_Ident *loc, int32_t global_tid);
339 EXTERN void __kmpc_dispatch_fini_8u(kmp_Ident *loc, int32_t global_tid);
340 
341 // reduction
342 EXTERN void __kmpc_nvptx_end_reduce(int32_t global_tid);
343 EXTERN void __kmpc_nvptx_end_reduce_nowait(int32_t global_tid);
344 EXTERN int32_t __kmpc_nvptx_parallel_reduce_nowait_v2(
345     kmp_Ident *loc, int32_t global_tid, int32_t num_vars, size_t reduce_size,
346     void *reduce_data, kmp_ShuffleReductFctPtr shflFct,
347     kmp_InterWarpCopyFctPtr cpyFct);
348 EXTERN int32_t __kmpc_nvptx_teams_reduce_nowait_v2(
349     kmp_Ident *loc, int32_t global_tid, void *global_buffer,
350     int32_t num_of_records, void *reduce_data, kmp_ShuffleReductFctPtr shflFct,
351     kmp_InterWarpCopyFctPtr cpyFct, kmp_ListGlobalFctPtr lgcpyFct,
352     kmp_ListGlobalFctPtr lgredFct, kmp_ListGlobalFctPtr glcpyFct,
353     kmp_ListGlobalFctPtr glredFct);
354 EXTERN int32_t __kmpc_shuffle_int32(int32_t val, int16_t delta, int16_t size);
355 EXTERN int64_t __kmpc_shuffle_int64(int64_t val, int16_t delta, int16_t size);
356 
357 // sync barrier
358 EXTERN void __kmpc_barrier(kmp_Ident *loc_ref, int32_t tid);
359 EXTERN void __kmpc_barrier_simple_spmd(kmp_Ident *loc_ref, int32_t tid);
360 EXTERN int32_t __kmpc_cancel_barrier(kmp_Ident *loc, int32_t global_tid);
361 
362 // single
363 EXTERN int32_t __kmpc_single(kmp_Ident *loc, int32_t global_tid);
364 EXTERN void __kmpc_end_single(kmp_Ident *loc, int32_t global_tid);
365 
366 // sync
367 EXTERN int32_t __kmpc_master(kmp_Ident *loc, int32_t global_tid);
368 EXTERN void __kmpc_end_master(kmp_Ident *loc, int32_t global_tid);
369 EXTERN void __kmpc_ordered(kmp_Ident *loc, int32_t global_tid);
370 EXTERN void __kmpc_end_ordered(kmp_Ident *loc, int32_t global_tid);
371 EXTERN void __kmpc_critical(kmp_Ident *loc, int32_t global_tid,
372                             kmp_CriticalName *crit);
373 EXTERN void __kmpc_end_critical(kmp_Ident *loc, int32_t global_tid,
374                                 kmp_CriticalName *crit);
375 EXTERN void __kmpc_flush(kmp_Ident *loc);
376 
377 // vote
378 EXTERN __kmpc_impl_lanemask_t __kmpc_warp_active_thread_mask();
379 // syncwarp
380 EXTERN void __kmpc_syncwarp(__kmpc_impl_lanemask_t);
381 
382 // tasks
383 EXTERN kmp_TaskDescr *__kmpc_omp_task_alloc(kmp_Ident *loc, uint32_t global_tid,
384                                             int32_t flag,
385                                             size_t sizeOfTaskInclPrivate,
386                                             size_t sizeOfSharedTable,
387                                             kmp_TaskFctPtr sub);
388 EXTERN int32_t __kmpc_omp_task(kmp_Ident *loc, uint32_t global_tid,
389                                kmp_TaskDescr *newLegacyTaskDescr);
390 EXTERN int32_t __kmpc_omp_task_with_deps(kmp_Ident *loc, uint32_t global_tid,
391                                          kmp_TaskDescr *newLegacyTaskDescr,
392                                          int32_t depNum, void *depList,
393                                          int32_t noAliasDepNum,
394                                          void *noAliasDepList);
395 EXTERN void __kmpc_omp_task_begin_if0(kmp_Ident *loc, uint32_t global_tid,
396                                       kmp_TaskDescr *newLegacyTaskDescr);
397 EXTERN void __kmpc_omp_task_complete_if0(kmp_Ident *loc, uint32_t global_tid,
398                                          kmp_TaskDescr *newLegacyTaskDescr);
399 EXTERN void __kmpc_omp_wait_deps(kmp_Ident *loc, uint32_t global_tid,
400                                  int32_t depNum, void *depList,
401                                  int32_t noAliasDepNum, void *noAliasDepList);
402 EXTERN void __kmpc_taskgroup(kmp_Ident *loc, uint32_t global_tid);
403 EXTERN void __kmpc_end_taskgroup(kmp_Ident *loc, uint32_t global_tid);
404 EXTERN int32_t __kmpc_omp_taskyield(kmp_Ident *loc, uint32_t global_tid,
405                                     int end_part);
406 EXTERN int32_t __kmpc_omp_taskwait(kmp_Ident *loc, uint32_t global_tid);
407 EXTERN void __kmpc_taskloop(kmp_Ident *loc, uint32_t global_tid,
408                             kmp_TaskDescr *newKmpTaskDescr, int if_val,
409                             uint64_t *lb, uint64_t *ub, int64_t st, int nogroup,
410                             int32_t sched, uint64_t grainsize, void *task_dup);
411 
412 // cancel
413 EXTERN int32_t __kmpc_cancellationpoint(kmp_Ident *loc, int32_t global_tid,
414                                         int32_t cancelVal);
415 EXTERN int32_t __kmpc_cancel(kmp_Ident *loc, int32_t global_tid,
416                              int32_t cancelVal);
417 
418 // non standard
419 EXTERN int32_t __kmpc_target_init(ident_t *Ident, bool IsSPMD,
420                                  bool UseGenericStateMachine,
421                            bool RequiresFullRuntime);
422 EXTERN void __kmpc_target_deinit(ident_t *Ident, bool IsSPMD,
423                            bool RequiresFullRuntime);
424 EXTERN void __kmpc_kernel_prepare_parallel(void *WorkFn);
425 EXTERN bool __kmpc_kernel_parallel(void **WorkFn);
426 EXTERN void __kmpc_kernel_end_parallel();
427 
428 EXTERN void __kmpc_data_sharing_init_stack();
429 EXTERN void __kmpc_begin_sharing_variables(void ***GlobalArgs, size_t nArgs);
430 EXTERN void __kmpc_end_sharing_variables();
431 EXTERN void __kmpc_get_shared_variables(void ***GlobalArgs);
432 
433 /// Entry point to start a new parallel region.
434 ///
435 /// \param ident       The source identifier.
436 /// \param global_tid  The global thread ID.
437 /// \param if_expr     The if(expr), or 1 if none given.
438 /// \param num_threads The num_threads(expr), or -1 if none given.
439 /// \param proc_bind   The proc_bind, or `proc_bind_default` if none given.
440 /// \param fn          The outlined parallel region function.
441 /// \param wrapper_fn  The worker wrapper function of fn.
442 /// \param args        The pointer array of arguments to fn.
443 /// \param nargs       The number of arguments to fn.
444 NOINLINE EXTERN void __kmpc_parallel_51(ident_t *ident, kmp_int32 global_tid,
445                                         kmp_int32 if_expr,
446                                         kmp_int32 num_threads, int proc_bind,
447                                         void *fn, void *wrapper_fn, void **args,
448                                         size_t nargs);
449 
450 // SPMD execution mode interrogation function.
451 EXTERN int8_t __kmpc_is_spmd_exec_mode();
452 
453 /// Return true if the hardware thread id \p Tid represents the OpenMP main
454 /// thread in generic mode outside of a parallel region.
455 EXTERN int8_t __kmpc_is_generic_main_thread(kmp_int32 Tid);
456 
457 /// Return true if the hardware thread id \p Tid represents the OpenMP main
458 /// thread in generic mode.
459 EXTERN int8_t __kmpc_is_generic_main_thread_id(kmp_int32 Tid);
460 
461 EXTERN void __kmpc_get_team_static_memory(int16_t isSPMDExecutionMode,
462                                           const void *buf, size_t size,
463                                           int16_t is_shared, const void **res);
464 
465 EXTERN void __kmpc_restore_team_static_memory(int16_t isSPMDExecutionMode,
466                                               int16_t is_shared);
467 
468 /// Allocate \p Bytes in "shareable" memory and return the address. Needs to be
469 /// called balanced with __kmpc_free_shared like a stack (push/pop). Can be
470 /// called by any thread, allocation happens per-thread.
471 EXTERN void *__kmpc_alloc_shared(uint64_t Bytes);
472 
473 /// Deallocate \p Ptr. Needs to be called balanced with __kmpc_alloc_shared like
474 /// a stack (push/pop). Can be called by any thread. \p Ptr must be allocated by
475 /// __kmpc_alloc_shared by the same thread. \p Bytes contains the size of the
476 /// paired allocation to make memory management easier.
477 EXTERN void __kmpc_free_shared(void *Ptr, size_t Bytes);
478 
479 #endif
480