1 /*
2  * Copyright (c) 2016-2019, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef KMPC_RUNTIME_H_
19 #define KMPC_RUNTIME_H_
20 
21 #include "gbldefs.h"
22 #include "global.h"
23 #include "symtab.h"
24 #include "ili.h"
25 
26 /** \file
27  * \brief Various definitions for the kmpc runtime
28  */
29 
30 /* KMPC Task Flags
31  * See KMPC's kmp.h struct kmp_tasking_flags
32  */
33 #define KMPC_TASK_UNTIED 0x00
34 #define KMPC_TASK_TIED 0x01
35 #define KMPC_TASK_FINAL 0x02
36 #define KMPC_TASK_MERGED_IF0 0x04
37 #define KMPC_TASK_DTOR_THK 0x08
38 #define KMPC_TASK_PROXY 0x10
39 #define KMPC_TASK_PRIORITY 0x20
40 
41 /* KMPC Schedule Types
42  * https://www.openmprtl.org/sites/default/files/resources/libomp_20151009_manual.pdf
43  * Additional types mentioned in the source and used in the refereced manual's
44  * example (KMP_SCH_DYNAMIC_CHUNKED).
45  */
46 typedef enum _kmpc_sched_e {
47   KMP_SCH_NONE = 0,
48   KMP_SCH_LOWER = 32,
49   KMP_SCH_STATIC_CHUNKED = 33,
50   KMP_SCH_STATIC = 34,
51   KMP_SCH_DYNAMIC_CHUNKED = 35,
52   KMP_SCH_GUIDED_CHUNKED = 36,
53   KMP_SCH_RUNTIME_CHUNKED = 37,
54   KMP_SCH_AUTO = 38,
55   KMP_SCH_STATIC_STEAL = 44,
56   KMP_SCH_UPPER = 45,
57   KMP_ORD_LOWER = 64,
58   KMP_ORD_STATIC_CHUNKED = 65,
59   KMP_ORD_STATIC = 66,
60   KMP_ORD_DYNAMIC_CHUNKED = 67,
61   KMP_ORD_GUIDED_CHUNKED = 68,
62   KMP_ORD_RUNTIME = 69,
63   KMP_ORD_AUTO = 70,
64   KMP_ORD_UPPER = 72,
65   KMP_DISTRIBUTE_STATIC_CHUNKED = 91,
66   KMP_DISTRIBUTE_STATIC = 92,
67   KMP_DISTRIBUTE_STATIC_CHUNKED_CHUNKONE = 93,
68   KMP_NM_LOWER = 160,
69   KMP_NM_STATIC = 162,
70   KMP_NM_GUIDED_CHUNKED = 164,
71   KMP_NM_AUTO = 166,
72   KMP_NM_ORD_STATIC = 194,
73   KMP_NM_ORD_AUTO = 198,
74   KMP_NM_UPPER = 200,
75   KMP_SCH_DEFAULT = KMP_SCH_STATIC
76 } kmpc_sched_e;
77 
78 typedef enum RegionType { OPENMP, OPENACC } RegionType;
79 
80 /* Argument type used for handling for loops and scheduling.
81  * All values here are sptrs.
82  */
83 typedef struct _loop_args_t {
84   SPTR lower;
85   SPTR upper;
86   SPTR stride;
87   SPTR chunk;
88   SPTR last;
89   SPTR upperd;
90   DTYPE dtype;        /* Lower/Upper bound data type INT,INT8,UINT, UINT8 */
91   kmpc_sched_e sched; /* KMPC schedule type */
92 } loop_args_t;
93 
94 struct kmpc_api_entry_t {
95   const char *name;      /* KMPC API function name                    */
96   const ILI_OP ret_iliopc;  /* KMPC API function return value ili opcode */
97   const DTYPE ret_dtype; /* KMPC API function return value type       */
98   const int flags;       /* (Optional) See KMPC_FLAG_XXX above        */
99 };
100 
101 /* Used internally for creating structs, or representing formal parameters when
102  * generating fortran outlined function/task signatures.
103  */
104 typedef struct any_kmpc_struct {
105   char *name;
106   DTYPE dtype;
107   int byval;
108   int psptr;
109 } KMPC_ST_TYPE;
110 
111 /* KMPC API macros and structs */
112 enum {
113   KMPC_API_BAD,
114   KMPC_API_FORK_CALL,
115   KMPC_API_BARRIER,
116   KMPC_API_CANCEL_BARRIER,
117   KMPC_API_COPYPRIVATE,
118   KMPC_API_CRITICAL,
119   KMPC_API_END_CRITICAL,
120   KMPC_API_SINGLE,
121   KMPC_API_END_SINGLE,
122   KMPC_API_MASTER,
123   KMPC_API_END_MASTER,
124   KMPC_API_FLUSH,
125   KMPC_API_ORDERED,
126   KMPC_API_END_ORDERED,
127   KMPC_API_FOR_STATIC_INIT,
128   KMPC_API_FOR_STATIC_FINI,
129   KMPC_API_DISPATCH_INIT,
130   KMPC_API_DISPATCH_NEXT,
131   KMPC_API_DISPATCH_FINI,
132   KMPC_API_GLOBAL_THREAD_NUM,
133   KMPC_API_GLOBAL_NUM_THREADS,
134   KMPC_API_BOUND_THREAD_NUM,
135   KMPC_API_BOUND_NUM_THREADS,
136   KMPC_API_PUSH_NUM_THREADS,
137   KMPC_API_SERIALIZED_PARALLEL,
138   KMPC_API_END_SERIALIZED_PARALLEL,
139   KMPC_API_THREADPRIVATE_CACHED,
140   KMPC_API_THREADPRIVATE_REGISTER_VEC,
141   KMPC_API_THREADPRIVATE_REGISTER,
142   KMPC_API_TASK_ALLOC,
143   KMPC_API_TASK,
144   KMPC_API_TASK_BEGIN_IF0,
145   KMPC_API_TASK_COMPLETE_IF0,
146   KMPC_API_TASK_WAIT,
147   KMPC_API_TASK_YIELD,
148   KMPC_API_CANCEL,
149   KMPC_API_CANCELLATIONPOINT,
150   KMPC_API_TASKGROUP,
151   KMPC_API_END_TASKGROUP,
152   KMPC_API_TASK_WITH_DEPS,
153   KMPC_API_WAIT_DEPS,
154   KMPC_API_TASKLOOP,
155   KMPC_API_THREADPRIVATE,
156   KMPC_API_PUSH_NUM_TEAMS,
157   KMPC_API_FORK_TEAMS,
158   KMPC_API_DIST_FOR_STATIC_INIT,
159   KMPC_API_DIST_DISPATCH_INIT,
160   KMPC_API_PUSH_PROC_BIND,
161   KMPC_API_ATOMIC_RD,
162   KMPC_API_ATOMIC_WR,
163   /* Begin - OpenMP Accelerator RT (libomptarget-nvptx) - non standard - */
164   KMPC_API_PUSH_TARGET_TRIPCOUNT,
165   KMPC_API_FOR_STATIC_INIT_SIMPLE_SPMD,
166   KMPC_API_SPMD_KERNEL_INIT,
167   KMPC_API_KERNEL_INIT_PARAMS,
168   KMPC_API_SHUFFLE_I32,
169   KMPC_API_SHUFFLE_I64,
170   KMPC_API_NVPTX_PARALLEL_REDUCE_NOWAIT_SIMPLE_SPMD,
171   KMPC_API_NVPTX_END_REDUCE_NOWAIT,
172   /* End - OpenMP Accelerator RT (libomptarget-nvptx) - non standard - */
173   KMPC_API_N_ENTRIES /* <-- Always last */
174 };
175 
176 /**
177    \brief ...
178  */
179 int ll_make_kmpc_atomic_read(int *opnd, DTYPE dtype);
180 
181 /**
182    \brief ...
183  */
184 int ll_make_kmpc_atomic_write(int *opnd, DTYPE dtype);
185 
186 /**
187    \brief ...
188  */
189 int ll_make_kmpc_barrier(void);
190 
191 /**
192    \brief ...
193  */
194 int ll_make_kmpc_bound_num_threads(void);
195 
196 /**
197    \brief ...
198  */
199 int ll_make_kmpc_bound_thread_num(void);
200 
201 /**
202    \brief ...
203  */
204 int ll_make_kmpc_cancel_barrier(void);
205 
206 /**
207    \brief ...
208  */
209 int ll_make_kmpc_cancel(int argili);
210 
211 /**
212    \brief ...
213  */
214 int ll_make_kmpc_cancellationpoint(int argili);
215 
216 /// Return a result or JSR ili to __kmpc_copyprivate()
217 int ll_make_kmpc_copyprivate(SPTR array_sptr, int single_ili,
218                              int copyfunc_acon);
219 
220 /// Return a result or JSR ili to __kmpc_critical()
221 int ll_make_kmpc_critical(SPTR sem);
222 
223 /**
224    \brief ...
225  */
226 int ll_make_kmpc_dispatch_fini(DTYPE dtype);
227 
228 /**
229    \brief ...
230  */
231 int ll_make_kmpc_dispatch_init(const loop_args_t *inargs);
232 
233 /// Return a result or JSR ili to __kmpc_dispatch_next_<size><signed|unsigned>
234 /// lower, upper, stride: sptrs
235 int ll_make_kmpc_dispatch_next(SPTR lower, SPTR upper, SPTR stride, SPTR last,
236                                DTYPE dtype);
237 
238 /**
239    \brief ...
240  */
241 int ll_make_kmpc_dist_dispatch_init(const loop_args_t *inargs);
242 
243 /**
244    \brief ...
245  */
246 int ll_make_kmpc_dist_for_static_init(const loop_args_t *inargs);
247 
248 /// Return a result or JSR ili to __kmpc_end_critical()
249 int ll_make_kmpc_end_critical(SPTR sem);
250 
251 /**
252    \brief ...
253  */
254 int ll_make_kmpc_end_master(void);
255 
256 /**
257    \brief ...
258  */
259 int ll_make_kmpc_end_ordered(void);
260 
261 /**
262    \brief ...
263  */
264 int ll_make_kmpc_end_serialized_parallel(void);
265 
266 /**
267    \brief ...
268  */
269 int ll_make_kmpc_end_single(void);
270 
271 /**
272    \brief ...
273  */
274 int ll_make_kmpc_end_taskgroup(void);
275 
276 /// Return a result or JSR ili to __kmpc_flush()
277 int ll_make_kmpc_flush(void);
278 
279 /**
280    \brief ...
281  */
282 int ll_make_kmpc_fork_call(SPTR sptr, int argc, int *arglist, RegionType rt, int ngangs_ili);
283 
284 /**
285    \brief ...
286  */
287 int ll_make_kmpc_fork_teams(SPTR sptr, int argc, int *arglist);
288 
289 /**
290    \brief ...
291  */
292 int ll_make_kmpc_for_static_fini(void);
293 
294 /**
295    \brief ...
296  */
297 int ll_make_kmpc_for_static_init_args(DTYPE dtype, int *inargs);
298 
299 /**
300    \brief ...
301  */
302 int ll_make_kmpc_for_static_init(const loop_args_t *inargs);
303 
304 /**
305    \brief ...
306  */
307 int ll_make_kmpc_global_num_threads(void);
308 
309 /**
310    \brief ...
311  */
312 int ll_make_kmpc_global_thread_num(void);
313 
314 /**
315    \brief ...
316  */
317 int ll_make_kmpc_master(void);
318 
319 /**
320    \brief ...
321  */
322 int ll_make_kmpc_omp_wait_deps(const loop_args_t *inargs);
323 
324 /**
325    \brief ...
326  */
327 int ll_make_kmpc_ordered(void);
328 
329 /**
330    \brief ...
331  */
332 int ll_make_kmpc_push_num_teams(int nteams_ili, int thread_limit_ili);
333 
334 /**
335    \brief ...
336  */
337 int ll_make_kmpc_push_num_threads(int argili);
338 
339 /**
340    \brief ...
341  */
342 int ll_make_kmpc_push_proc_bind(int argili);
343 
344 /**
345    \brief ...
346  */
347 int ll_make_kmpc_serialized_parallel(void);
348 
349 /**
350    \brief ...
351  */
352 int ll_make_kmpc_single(void);
353 
354 /**
355    \brief ...
356  */
357 DTYPE ll_make_kmpc_struct_type(int count, char *name, KMPC_ST_TYPE *meminfo,
358                                ISZ_T sz);
359 
360 /// Return an sptr to the allocated task object:  __kmp_omp_task_alloc()
361 /// \param base  sptr for storing return value from __kmpc_omp_task_alloc
362 /// \param sptr  sptr representing the outlined function that is the task
363 /// \param flags MP_TASK_xxx flags (see mp.h)
364 /// \param scope_sptr ST_BLOCK containing the uplevel block
365 /// \param uplevel_ili unused
366 SPTR ll_make_kmpc_task_arg(SPTR base, SPTR sptr, SPTR scope_sptr,
367                            SPTR flags_sptr, int uplevel_ili);
368 
369 /// Return a JSR ili to __kmpc_omp_task_begin_if0.
370 /// \param task_sptr sptr representing the allocated task
371 int ll_make_kmpc_task_begin_if0(SPTR task_sptr);
372 
373 /// Return a JSR ili to __kmpc_omp_task_complete_if0.
374 /// \param task_sptr sptr representing the allocated task
375 int ll_make_kmpc_task_complete_if0(SPTR task_sptr);
376 
377 /**
378    \brief ...
379  */
380 int ll_make_kmpc_taskgroup(void);
381 
382 /**
383    \brief ...
384  */
385 int ll_make_kmpc_task(SPTR task_sptr);
386 
387 /**
388    \brief ...
389  */
390 int ll_make_kmpc_taskloop(int *inargs);
391 
392 /**
393    \brief ...
394  */
395 int ll_make_kmpc_task_wait(void);
396 
397 /**
398    \brief ...
399  */
400 int ll_make_kmpc_task_with_deps(const loop_args_t *inargs);
401 
402 /**
403    \brief ...
404  */
405 int ll_make_kmpc_task_yield(void);
406 
407 /**
408    \brief ...
409  */
410 int ll_make_kmpc_threadprivate_cached(int data_ili, int size_ili,
411                                       int cache_ili);
412 
413 /**
414    \brief ...
415  */
416 int ll_make_kmpc_threadprivate(int data_ili, int size_ili);
417 
418 /**
419    \brief ...
420  */
421 int ll_make_kmpc_threadprivate_register(int data_ili, int ctor_ili,
422                                         int cctor_ili, int dtor_ili);
423 
424 /**
425    \brief ...
426  */
427 int ll_make_kmpc_threadprivate_register_vec(int data_ili, int ctor_ili,
428                                             int cctor_ili, int dtor_ili,
429                                             int size_ili);
430 
431 /**
432    \brief ...
433  */
434 int mp_to_kmpc_tasking_flags(const int mp);
435 
436 /**
437    \brief Given a MP_ or DI_ schedule type and return the KMPC equivalent
438  */
439 kmpc_sched_e mp_sched_to_kmpc_sched(int sched);
440 
441 /**
442    \brief ...
443  */
444 void reset_kmpc_ident_dtype(void);
445 
446 /* OpenMP Accelerator RT - non standard */
447 /* Only Available for linomptarget-nvptx device runtime */
448 #if defined(OMP_OFFLOAD_LLVM) || defined(OMP_OFFLOAD_PGI)
449 /**
450    \brief cuda special register shuffling for int 32 or int 64
451  */
452 int ll_make_kmpc_shuffle(int, int, int, bool);
453 
454 /**
455   \brief SPMD mode - static loop init
456 */
457 int ll_make_kmpc_for_static_init_simple_spmd(const loop_args_t *, int);
458 
459 /**
460   \brief SPMD mode - kernel init.
461 */
462 int ll_make_kmpc_spmd_kernel_init(int);
463 
464 /**
465   \brief Push the trip count of the loop that is going to be parallelized.
466 */
467 int ll_make_kmpc_push_target_tripcount(int, SPTR);
468 
469 /**
470   \brief Parallel reduction within kernel for SPMD mode
471 */
472 int ll_make_kmpc_nvptx_parallel_reduce_nowait_simple_spmd(int, int, int, SPTR, SPTR);
473 
474 /**
475   \brief End of reduction within kernel
476 */
477 int ll_make_kmpc_nvptx_end_reduce_nowait();
478 
479 /* End OpenMP Accelerator RT - non standard */
480 #endif
481 #endif /* KMPC_RUNTIME_H_ */
482