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