Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_Extension.H
Go to the documentation of this file.
1
#ifndef AMREX_EXTENSION_H_
2
#define AMREX_EXTENSION_H_
3
#include <AMReX_Config.H>
4
10
#if defined(__INTEL_COMPILER) || (defined(__INTEL_LLVM_COMPILER) && !defined(SYCL_LANGUAGE_VERSION))
11
#define AMREX_CXX_INTEL
12
#elif defined(_CRAYC) || defined(__cray__)
13
#define AMREX_CXX_CRAY
14
#elif defined(__PGI)
15
#define AMREX_CXX_PGI
16
#elif defined(__NVCOMPILER)
17
#define AMREX_CXX_NVHPC
18
#elif defined(__NEC__)
19
#define AMREX_CXX_NEC
20
#elif defined(__ibmxl__)
21
#define AMREX_CXX_IBM
22
#elif defined(__clang__)
23
#define AMREX_CXX_CLANG
24
#elif defined(__GNUC__)
25
#define AMREX_CXX_GCC
26
#endif
27
28
#if !defined(BL_LANG_FORT)
29
30
// restrict
31
32
#ifdef __cplusplus
33
34
#ifdef _WIN32
35
#define AMREX_RESTRICT __restrict
36
#else
37
#define AMREX_RESTRICT __restrict__
38
#endif
39
40
#else
41
42
#define AMREX_RESTRICT restrict
43
44
#endif
45
46
// simd
47
48
#if defined(AMREX_DEBUG)
49
#define AMREX_PRAGMA_SIMD
50
51
#elif defined(__CUDA_ARCH__) && defined(AMREX_USE_CUDA)
52
#define AMREX_PRAGMA_SIMD
53
54
#elif defined(__HIP_DEVICE_COMPILE__) && defined(AMREX_USE_HIP)
55
#define AMREX_PRAGMA_SIMD
56
57
//#elif defined(AMREX_USE_OMP) && defined(_OPENMP) && (_OPENMP >= 201307) && !defined(__PGI)
58
//#define AMREX_PRAGMA_SIMD _Pragma("omp simd")
59
60
#elif defined(AMREX_CXX_INTEL)
61
#define AMREX_PRAGMA_SIMD _Pragma("ivdep")
62
63
#elif defined(AMREX_CXX_CRAY)
64
#define AMREX_PRAGMA_SIMD _Pragma("ivdep")
65
66
#elif defined(AMREX_CXX_PGI)
67
#define AMREX_PRAGMA_SIMD _Pragma("loop ivdep")
68
69
#elif defined(AMREX_CXX_NVHPC)
70
#define AMREX_PRAGMA_SIMD _Pragma("loop ivdep")
71
72
#elif defined(AMREX_CXX_NEC)
73
#define AMREX_PRAGMA_SIMD
74
75
#elif defined(AMREX_CXX_IBM)
76
#define AMREX_PRAGMA_SIMD _Pragma("ibm independent_loop")
77
78
#elif defined(__clang__)
79
#define AMREX_PRAGMA_SIMD
80
81
#elif defined(__GNUC__)
82
#define AMREX_PRAGMA_SIMD _Pragma("GCC ivdep")
83
84
#else
85
#define AMREX_PRAGMA_SIMD
86
87
#endif
/* simd */
88
89
// force inline
90
#if defined(__CUDA_ARCH__) && defined(AMREX_USE_CUDA)
91
#define AMREX_FORCE_INLINE __forceinline__
92
93
#elif defined(__HIP_DEVICE_COMPILE__) && defined(AMREX_USE_HIP)
94
#define AMREX_FORCE_INLINE __forceinline__
95
96
#elif defined(AMREX_CXX_INTEL)
97
#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
98
99
#elif defined(AMREX_CXX_CRAY)
100
#define AMREX_FORCE_INLINE inline
101
102
#elif defined(AMREX_CXX_PGI)
103
#define AMREX_FORCE_INLINE inline
104
105
#elif defined(AMREX_CXX_NVHPC)
106
#define AMREX_FORCE_INLINE inline
107
108
#elif defined(AMREX_CXX_NEC)
109
#define AMREX_FORCE_INLINE inline
110
111
#elif defined(AMREX_CXX_IBM)
112
#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
113
114
#elif defined(__clang__)
115
#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
116
117
#elif defined(__GNUC__)
118
#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
119
120
#elif defined(_MSC_VER)
121
#define AMREX_FORCE_INLINE inline __forceinline
122
123
#else
124
#define AMREX_FORCE_INLINE inline
125
126
#endif
/* force inline */
127
128
129
#ifdef AMREX_USE_FORCE_INLINE
130
#define AMREX_INLINE AMREX_FORCE_INLINE
131
#else
132
#define AMREX_INLINE inline
133
#endif
134
135
// no inline
136
#if defined(_MSC_VER)
137
#define AMREX_NO_INLINE __declspec(noinline)
138
#elif (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIP__) || defined(__INTEL_CLANG_COMPILER))
139
#define AMREX_NO_INLINE __attribute__((noinline))
140
#else
141
#define AMREX_NO_INLINE
142
#endif
143
144
// flatten
145
#if defined(_MSC_VER)
146
#define AMREX_FLATTEN [[msvc::flatten]]
147
#elif defined(__clang__) || defined(__GNUC__)
148
#define AMREX_FLATTEN __attribute__((flatten))
149
#else
150
#define AMREX_FLATTEN
151
#endif
152
153
#ifdef AMREX_USE_FLATTEN_FOR
154
#define AMREX_ATTRIBUTE_FLATTEN_FOR AMREX_FLATTEN
155
#else
156
#define AMREX_ATTRIBUTE_FLATTEN_FOR
157
#endif
158
159
// unroll loop
160
#define AMREX_TO_STRING_HELPER(X) #X
161
#define AMREX_TO_STRING(X) AMREX_TO_STRING_HELPER(X)
162
163
#if defined(__clang__) || defined(__CUDACC__) || defined(__HIP__) || defined(__INTEL_CLANG_COMPILER)
164
#define AMREX_UNROLL_LOOP(n) _Pragma(AMREX_TO_STRING(unroll n))
165
#elif defined(__GNUC__)
166
#define AMREX_UNROLL_LOOP(n) _Pragma(AMREX_TO_STRING(GCC unroll n))
167
#else
168
#define AMREX_UNROLL_LOOP(n)
169
#endif
170
171
// __COUNTER__
172
//
173
// __COUNTER__ has been a de-facto extension in all compilers AMReX supports for
174
// a very long time, but it was only recently adopted into C2y. Clang 22 and
175
// later therefore diagnose it as a C2y extension under -Wpedantic, even in C++
176
// (https://github.com/llvm/llvm-project/issues/196557). Bracket a use of
177
// __COUNTER__ with these macros to silence that diagnostic. The nested
178
// -Wunknown-warning-option suppression keeps older Clang, which does not know
179
// -Wc2y-extensions, quiet as well.
180
//
181
// Each AMREX_WARNING_PUSH_* macro silences a specific diagnostic, while the
182
// single AMREX_WARNING_POP restores the previous state of whatever was pushed
183
// last. The naming is intentionally asymmetric: the pops are not tied to a
184
// particular warning, so pushes and pops must nest, not interleave.
185
186
#if defined(__clang__)
187
#define AMREX_WARNING_PUSH_COUNTER \
188
_Pragma("clang diagnostic push") \
189
_Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \
190
_Pragma("clang diagnostic ignored \"-Wc2y-extensions\"")
191
#define AMREX_WARNING_POP \
192
_Pragma("clang diagnostic pop")
193
#else
194
#define AMREX_WARNING_PUSH_COUNTER
195
#define AMREX_WARNING_POP
196
#endif
197
198
// __attribute__((weak))
199
200
#if defined(AMREX_TYPECHECK)
201
#define AMREX_ATTRIBUTE_WEAK
202
#elif defined(_WIN32)
203
#define AMREX_ATTRIBUTE_WEAK
204
#elif defined(__clang__) && defined(__apple_build_version__)
205
#define AMREX_ATTRIBUTE_WEAK __attribute__((weak_import))
206
#else
207
#define AMREX_ATTRIBUTE_WEAK __attribute__((weak))
208
#endif
209
210
// public globals
211
// https://stackoverflow.com/questions/54560832/cmake-windows-export-all-symbols-does-not-cover-global-variables/54568678#54568678
212
#if defined(_MSC_VER)
213
# if defined(AMREX_IS_DLL)
214
# if defined(AMREX_IS_DLL_BUILDING)
215
# define AMREX_EXPORT __declspec(dllexport)
216
# else
217
# define AMREX_EXPORT __declspec(dllimport)
218
# endif
219
# else
220
# define AMREX_EXPORT
221
# endif
222
#else
223
# define AMREX_EXPORT
224
#endif
225
226
#if defined(__cplusplus) && defined(_WIN32)
227
#include <ciso646>
228
#endif
229
230
#if defined(__INTEL_COMPILER) && defined(__EDG__) && (__cplusplus < 201703L)
231
// Classical EDG based Intel compiler does not support fallthrough when std=c++14
232
# define AMREX_FALLTHROUGH ((void)0)
233
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(fallthrough) >= 201603L
234
# define AMREX_FALLTHROUGH [[fallthrough]]
235
#elif defined(__clang__)
236
# define AMREX_FALLTHROUGH [[clang::fallthrough]]
237
#elif defined(__GNUC__) && (__GNUC__ >= 7)
238
# define AMREX_FALLTHROUGH [[gnu::fallthrough]]
239
#else
240
# define AMREX_FALLTHROUGH ((void)0)
241
#endif
242
243
// Note: following compilers support [[likely]] and [[unlikely]]
244
// - Clang >= 12.0
245
// - GCC >= 9.0
246
// - Intel >= 2021.7
247
// - MSVC >= 19.26
248
// - nvcc >= 12
249
#if defined(__has_cpp_attribute) && __has_cpp_attribute(likely) >= 201803L
250
# define AMREX_LIKELY [[likely]]
251
# define AMREX_UNLIKELY [[unlikely]]
252
#else
253
# define AMREX_LIKELY
254
# define AMREX_UNLIKELY
255
#endif
256
257
// Note: following compilers support assumptions, at least using builtin functions:
258
// - Clang >= 3.7
259
// - GCC >= 5.1
260
// - MSVC >= 19.20
261
// - nvcc >= 11.1.0
262
// - icx >= 2021.1.2
263
//
264
// [[assume]] itself is C++23. Clang >= 19 and GCC >= 13 advertise it through
265
// __has_cpp_attribute in older language modes as well, and Clang then diagnoses
266
// every use as a C++23 extension under -Wpedantic
267
// (-Wc++23-attribute-extensions). So only take the attribute when the language
268
// mode really is C++23 and rely on the compiler-specific spellings below
269
// otherwise; they carry the same information to the optimizer.
270
#if defined(__has_cpp_attribute) && __has_cpp_attribute(assume) >= 202207L && \
271
defined(__cplusplus) && __cplusplus >= 202302L
272
# define AMREX_ASSUME(ASSUMPTION) [[assume(ASSUMPTION)]]
273
#else
274
# if defined(__CUDA_ARCH__) && defined(__CUDACC__)
275
# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
276
# elif defined(AMREX_CXX_INTEL) || defined(__clang__)
277
# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
278
# elif defined(_MSC_VER)
279
# define AMREX_ASSUME(ASSUMPTION) __assume(ASSUMPTION)
280
# elif defined(__GNUC__) && __GNUC__ >= 13
281
// like [[assume]], this does not evaluate ASSUMPTION
282
# define AMREX_ASSUME(ASSUMPTION) __attribute__((assume(ASSUMPTION)))
283
# elif defined(__GNUC__)
284
# define AMREX_ASSUME(ASSUMPTION) \
285
do { if (!(ASSUMPTION)) { __builtin_unreachable(); } } while (0)
286
# else
287
# define AMREX_ASSUME(ASSUMPTION)
288
# endif
289
#endif
290
291
// CI uses -Werror -Wc++17-extension, thus we need to add the __cplusplus clause
292
#if !defined(AMREX_NO_NODISCARD) && defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard) >= 201603L
293
# define AMREX_NODISCARD [[nodiscard]]
294
#else
295
# define AMREX_NODISCARD
296
#endif
297
298
// Note: following compilers support [[no_unique_address]]
299
// - Clang >= 9.0
300
// - GCC >= 9.0
301
// - MSVC >= 19.26
302
// Using no unique address makes empty base class optimization for multiple policies much easier
303
#if !defined(AMREX_NO_NO_UNIQUE_ADDRESS) && defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address) >= 201803L
304
# define AMREX_NO_UNIQUE_ADDRESS [[no_unique_address]]
305
# define AMREX_HAS_NO_UNIQUE_ADDRESS 1
306
#else
307
# define AMREX_NO_UNIQUE_ADDRESS
308
#endif
309
310
#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
311
# define AMREX_IF_CONSTEXPR if constexpr
312
#else
313
# define AMREX_IF_CONSTEXPR if
314
#endif
315
316
#endif
/* !BL_LANG_FORT */
317
318
#endif
Src
Base
AMReX_Extension.H
Generated by
1.9.8