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