mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
166 lines
5.2 KiB
C
166 lines
5.2 KiB
C
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef __OMPX_H
|
||
|
#define __OMPX_H
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
int omp_get_ancestor_thread_num(int);
|
||
|
int omp_get_team_size(int);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/// Target kernel language extensions
|
||
|
///
|
||
|
/// These extensions exist for the host to allow fallback implementations,
|
||
|
/// however, they cannot be arbitrarily composed with OpenMP. If the rules of
|
||
|
/// the kernel language are followed, the host fallbacks should behave as
|
||
|
/// expected since the kernel is represented as 3 sequential outer loops, one
|
||
|
/// for each grid dimension, and three (nested) parallel loops, one for each
|
||
|
/// block dimension. This fallback is not supposed to be optimal and should be
|
||
|
/// configurable by the user.
|
||
|
///
|
||
|
///{
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
enum {
|
||
|
ompx_relaxed = __ATOMIC_RELAXED,
|
||
|
ompx_aquire = __ATOMIC_ACQUIRE,
|
||
|
ompx_release = __ATOMIC_RELEASE,
|
||
|
ompx_acq_rel = __ATOMIC_ACQ_REL,
|
||
|
ompx_seq_cst = __ATOMIC_SEQ_CST,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
ompx_dim_x = 0,
|
||
|
ompx_dim_y = 1,
|
||
|
ompx_dim_z = 2,
|
||
|
};
|
||
|
|
||
|
/// ompx_{thread,block}_{id,dim}
|
||
|
///{
|
||
|
#pragma omp begin declare variant match(device = {kind(cpu)})
|
||
|
#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(NAME, VALUE) \
|
||
|
static inline int ompx_##NAME(int Dim) { return VALUE; }
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(thread_id,
|
||
|
omp_get_ancestor_thread_num(Dim + 1))
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(block_dim, omp_get_team_size(Dim + 1))
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(block_id, 0)
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C(grid_dim, 1)
|
||
|
#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_C
|
||
|
///}
|
||
|
|
||
|
/// ompx_{sync_block}_{,divergent}
|
||
|
///{
|
||
|
#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(RETTY, NAME, ARGS, BODY) \
|
||
|
static inline RETTY ompx_##NAME(ARGS) { BODY; }
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block, int Ordering,
|
||
|
_Pragma("omp barrier"));
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block_acq_rel, void,
|
||
|
ompx_sync_block(ompx_acq_rel));
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C(void, sync_block_divergent, int Ordering,
|
||
|
ompx_sync_block(Ordering));
|
||
|
#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_C
|
||
|
///}
|
||
|
|
||
|
#pragma omp end declare variant
|
||
|
|
||
|
/// ompx_{sync_block}_{,divergent}
|
||
|
///{
|
||
|
#define _TGT_KERNEL_LANGUAGE_DECL_SYNC_C(RETTY, NAME, ARGS) \
|
||
|
RETTY ompx_##NAME(ARGS);
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block, int Ordering);
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block_acq_rel, void);
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_SYNC_C(void, sync_block_divergent, int Ordering);
|
||
|
#undef _TGT_KERNEL_LANGUAGE_DECL_SYNC_C
|
||
|
///}
|
||
|
|
||
|
/// ompx_{thread,block}_{id,dim}_{x,y,z}
|
||
|
///{
|
||
|
#define _TGT_KERNEL_LANGUAGE_DECL_GRID_C(NAME) \
|
||
|
int ompx_##NAME(int Dim); \
|
||
|
static inline int ompx_##NAME##_x() { return ompx_##NAME(ompx_dim_x); } \
|
||
|
static inline int ompx_##NAME##_y() { return ompx_##NAME(ompx_dim_y); } \
|
||
|
static inline int ompx_##NAME##_z() { return ompx_##NAME(ompx_dim_z); }
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_GRID_C(thread_id)
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_GRID_C(block_dim)
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_GRID_C(block_id)
|
||
|
_TGT_KERNEL_LANGUAGE_DECL_GRID_C(grid_dim)
|
||
|
#undef _TGT_KERNEL_LANGUAGE_DECL_GRID_C
|
||
|
///}
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
namespace ompx {
|
||
|
|
||
|
enum {
|
||
|
dim_x = ompx_dim_x,
|
||
|
dim_y = ompx_dim_y,
|
||
|
dim_z = ompx_dim_z,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
relaxed = ompx_relaxed ,
|
||
|
aquire = ompx_aquire,
|
||
|
release = ompx_release,
|
||
|
acc_rel = ompx_acq_rel,
|
||
|
seq_cst = ompx_seq_cst,
|
||
|
};
|
||
|
|
||
|
/// ompx::{thread,block}_{id,dim}_{,x,y,z}
|
||
|
///{
|
||
|
#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(NAME) \
|
||
|
static inline int NAME(int Dim) noexcept { return ompx_##NAME(Dim); } \
|
||
|
static inline int NAME##_x() noexcept { return NAME(ompx_dim_x); } \
|
||
|
static inline int NAME##_y() noexcept { return NAME(ompx_dim_y); } \
|
||
|
static inline int NAME##_z() noexcept { return NAME(ompx_dim_z); }
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(thread_id)
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(block_dim)
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(block_id)
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX(grid_dim)
|
||
|
#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_GRID_CXX
|
||
|
///}
|
||
|
|
||
|
/// ompx_{sync_block}_{,divergent}
|
||
|
///{
|
||
|
#define _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(RETTY, NAME, ARGS, CALL_ARGS) \
|
||
|
static inline RETTY NAME(ARGS) { \
|
||
|
return ompx_##NAME(CALL_ARGS); \
|
||
|
}
|
||
|
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(void, sync_block, int Ordering = acc_rel,
|
||
|
Ordering);
|
||
|
_TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX(void, sync_block_divergent,
|
||
|
int Ordering = acc_rel, Ordering);
|
||
|
#undef _TGT_KERNEL_LANGUAGE_HOST_IMPL_SYNC_CXX
|
||
|
///}
|
||
|
|
||
|
} // namespace ompx
|
||
|
#endif
|
||
|
|
||
|
///}
|
||
|
|
||
|
#endif /* __OMPX_H */
|