1*5f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
2*5f757f3fSDimitry Andric//
3*5f757f3fSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric//
7*5f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric
9*5f757f3fSDimitry Andric#ifndef __OMPX_H
10*5f757f3fSDimitry Andric#define __OMPX_H
11*5f757f3fSDimitry Andric
12*5f757f3fSDimitry Andric#ifdef __cplusplus
13*5f757f3fSDimitry Andricextern "C" {
14*5f757f3fSDimitry Andric#endif
15*5f757f3fSDimitry Andric
16*5f757f3fSDimitry Andricint omp_get_ancestor_thread_num(int);
17*5f757f3fSDimitry Andricint omp_get_team_size(int);
18*5f757f3fSDimitry Andric
19*5f757f3fSDimitry Andric#ifdef __cplusplus
20*5f757f3fSDimitry Andric}
21*5f757f3fSDimitry Andric#endif
22*5f757f3fSDimitry Andric
23*5f757f3fSDimitry Andric/// Target kernel language extensions
24*5f757f3fSDimitry Andric///
25*5f757f3fSDimitry Andric/// These extensions exist for the host to allow fallback implementations,
26*5f757f3fSDimitry Andric/// however, they cannot be arbitrarily composed with OpenMP. If the rules of
27*5f757f3fSDimitry Andric/// the kernel language are followed, the host fallbacks should behave as
28*5f757f3fSDimitry Andric/// expected since the kernel is represented as 3 sequential outer loops, one
29*5f757f3fSDimitry Andric/// for each grid dimension, and three (nested) parallel loops, one for each
30*5f757f3fSDimitry Andric/// block dimension. This fallback is not supposed to be optimal and should be
31*5f757f3fSDimitry Andric/// configurable by the user.
32*5f757f3fSDimitry Andric///
33*5f757f3fSDimitry Andric///{
34*5f757f3fSDimitry Andric
35*5f757f3fSDimitry Andric#ifdef __cplusplus
36*5f757f3fSDimitry Andricextern "C" {
37*5f757f3fSDimitry Andric#endif
38*5f757f3fSDimitry Andric
39*5f757f3fSDimitry Andricenum {
40*5f757f3fSDimitry Andric  ompx_relaxed = __ATOMIC_RELAXED,
41*5f757f3fSDimitry Andric  ompx_aquire = __ATOMIC_ACQUIRE,
42*5f757f3fSDimitry Andric  ompx_release = __ATOMIC_RELEASE,
43*5f757f3fSDimitry Andric  ompx_acq_rel = __ATOMIC_ACQ_REL,
44*5f757f3fSDimitry Andric  ompx_seq_cst = __ATOMIC_SEQ_CST,
45*5f757f3fSDimitry Andric};
46*5f757f3fSDimitry Andric
47*5f757f3fSDimitry Andricenum {
48*5f757f3fSDimitry Andric  ompx_dim_x = 0,
49*5f757f3fSDimitry Andric  ompx_dim_y = 1,
50*5f757f3fSDimitry Andric  ompx_dim_z = 2,
51*5f757f3fSDimitry Andric};
52*5f757f3fSDimitry Andric
53*5f757f3fSDimitry Andric/// ompx_{thread,block}_{id,dim}
54*5f757f3fSDimitry Andric///{
55*5f757f3fSDimitry Andric#pragma omp begin declare variant match(device = {kind(cpu)})
56*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(NAME, VALUE)                     \
57*5f757f3fSDimitry Andric  static inline int ompx_##NAME(int Dim) { return VALUE; }
58*5f757f3fSDimitry Andric
59*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(thread_id,
60*5f757f3fSDimitry Andric                                      omp_get_ancestor_thread_num(Dim + 1))
61*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(block_dim, omp_get_team_size(Dim + 1))
62*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(block_id, 0)
63*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(grid_dim, 1)
64*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C
65*5f757f3fSDimitry Andric///}
66*5f757f3fSDimitry Andric
67*5f757f3fSDimitry Andric/// ompx_{sync_block}_{,divergent}
68*5f757f3fSDimitry Andric///{
69*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(RETTY, NAME, ARGS, BODY)         \
70*5f757f3fSDimitry Andric  static inline RETTY ompx_##NAME(ARGS) { BODY; }
71*5f757f3fSDimitry Andric
72*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block, int Ordering,
73*5f757f3fSDimitry Andric                                      _Pragma("omp barrier"));
74*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block_acq_rel, void,
75*5f757f3fSDimitry Andric                                      ompx_sync_block(ompx_acq_rel));
76*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block_divergent, int Ordering,
77*5f757f3fSDimitry Andric                                      ompx_sync_block(Ordering));
78*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C
79*5f757f3fSDimitry Andric///}
80*5f757f3fSDimitry Andric
81*5f757f3fSDimitry Andric#pragma omp end declare variant
82*5f757f3fSDimitry Andric
83*5f757f3fSDimitry Andric/// ompx_{sync_block}_{,divergent}
84*5f757f3fSDimitry Andric///{
85*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_DECL_SYNC_C(RETTY, NAME, ARGS)         \
86*5f757f3fSDimitry Andric  RETTY ompx_##NAME(ARGS);
87*5f757f3fSDimitry Andric
88*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block, int Ordering);
89*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block_acq_rel, void);
90*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block_divergent, int Ordering);
91*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_DECL_SYNC_C
92*5f757f3fSDimitry Andric///}
93*5f757f3fSDimitry Andric
94*5f757f3fSDimitry Andric/// ompx_{thread,block}_{id,dim}_{x,y,z}
95*5f757f3fSDimitry Andric///{
96*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_DECL_GRID_C(NAME)                                 \
97*5f757f3fSDimitry Andric  int ompx_##NAME(int Dim);                                                    \
98*5f757f3fSDimitry Andric  static inline int ompx_##NAME##_x() { return ompx_##NAME(ompx_dim_x); }      \
99*5f757f3fSDimitry Andric  static inline int ompx_##NAME##_y() { return ompx_##NAME(ompx_dim_y); }      \
100*5f757f3fSDimitry Andric  static inline int ompx_##NAME##_z() { return ompx_##NAME(ompx_dim_z); }
101*5f757f3fSDimitry Andric
102*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_GRID_C(thread_id)
103*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_GRID_C(block_dim)
104*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_GRID_C(block_id)
105*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_DECL_GRID_C(grid_dim)
106*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_DECL_GRID_C
107*5f757f3fSDimitry Andric///}
108*5f757f3fSDimitry Andric
109*5f757f3fSDimitry Andric#ifdef __cplusplus
110*5f757f3fSDimitry Andric}
111*5f757f3fSDimitry Andric#endif
112*5f757f3fSDimitry Andric
113*5f757f3fSDimitry Andric#ifdef __cplusplus
114*5f757f3fSDimitry Andric
115*5f757f3fSDimitry Andricnamespace ompx {
116*5f757f3fSDimitry Andric
117*5f757f3fSDimitry Andricenum {
118*5f757f3fSDimitry Andric  dim_x = ompx_dim_x,
119*5f757f3fSDimitry Andric  dim_y = ompx_dim_y,
120*5f757f3fSDimitry Andric  dim_z = ompx_dim_z,
121*5f757f3fSDimitry Andric};
122*5f757f3fSDimitry Andric
123*5f757f3fSDimitry Andricenum {
124*5f757f3fSDimitry Andric  relaxed = ompx_relaxed ,
125*5f757f3fSDimitry Andric  aquire = ompx_aquire,
126*5f757f3fSDimitry Andric  release = ompx_release,
127*5f757f3fSDimitry Andric  acc_rel = ompx_acq_rel,
128*5f757f3fSDimitry Andric  seq_cst = ompx_seq_cst,
129*5f757f3fSDimitry Andric};
130*5f757f3fSDimitry Andric
131*5f757f3fSDimitry Andric/// ompx::{thread,block}_{id,dim}_{,x,y,z}
132*5f757f3fSDimitry Andric///{
133*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(NAME)                          \
134*5f757f3fSDimitry Andric  static inline int NAME(int Dim) noexcept { return ompx_##NAME(Dim); }        \
135*5f757f3fSDimitry Andric  static inline int NAME##_x() noexcept { return NAME(ompx_dim_x); }           \
136*5f757f3fSDimitry Andric  static inline int NAME##_y() noexcept { return NAME(ompx_dim_y); }           \
137*5f757f3fSDimitry Andric  static inline int NAME##_z() noexcept { return NAME(ompx_dim_z); }
138*5f757f3fSDimitry Andric
139*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(thread_id)
140*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(block_dim)
141*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(block_id)
142*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(grid_dim)
143*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX
144*5f757f3fSDimitry Andric///}
145*5f757f3fSDimitry Andric
146*5f757f3fSDimitry Andric/// ompx_{sync_block}_{,divergent}
147*5f757f3fSDimitry Andric///{
148*5f757f3fSDimitry Andric#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(RETTY, NAME, ARGS, CALL_ARGS)  \
149*5f757f3fSDimitry Andric  static inline RETTY NAME(ARGS) {               \
150*5f757f3fSDimitry Andric    return ompx_##NAME(CALL_ARGS);                                             \
151*5f757f3fSDimitry Andric  }
152*5f757f3fSDimitry Andric
153*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(void, sync_block, int Ordering = acc_rel,
154*5f757f3fSDimitry Andric                                        Ordering);
155*5f757f3fSDimitry Andric_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(void, sync_block_divergent,
156*5f757f3fSDimitry Andric                                        int Ordering = acc_rel, Ordering);
157*5f757f3fSDimitry Andric#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX
158*5f757f3fSDimitry Andric///}
159*5f757f3fSDimitry Andric
160*5f757f3fSDimitry Andric} // namespace ompx
161*5f757f3fSDimitry Andric#endif
162*5f757f3fSDimitry Andric
163*5f757f3fSDimitry Andric///}
164*5f757f3fSDimitry Andric
165*5f757f3fSDimitry Andric#endif /* __OMPX_H */
166