Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
5#if defined(__INTEL_COMPILER) || (defined(__INTEL_LLVM_COMPILER) && !defined(SYCL_LANGUAGE_VERSION))
6#define AMREX_CXX_INTEL
7#elif defined(_CRAYC) || defined(__cray__)
8#define AMREX_CXX_CRAY
9#elif defined(__PGI)
10#define AMREX_CXX_PGI
11#elif defined(__NVCOMPILER)
12#define AMREX_CXX_NVHPC
13#elif defined(__NEC__)
14#define AMREX_CXX_NEC
15#elif defined(__ibmxl__)
16#define AMREX_CXX_IBM
17#elif defined(__clang__)
18#define AMREX_CXX_CLANG
19#elif defined(__GNUC__)
20#define AMREX_CXX_GCC
21#endif
22
23#if !defined(BL_LANG_FORT)
24
25// restrict
26
27#ifdef __cplusplus
28
29#ifdef _WIN32
30#define AMREX_RESTRICT __restrict
31#else
32#define AMREX_RESTRICT __restrict__
33#endif
34
35#else
36
37#define AMREX_RESTRICT restrict
38
39#endif
40
41// simd
42
43#if defined(AMREX_DEBUG)
44#define AMREX_PRAGMA_SIMD
45
46#elif defined(__CUDA_ARCH__) && defined(AMREX_USE_CUDA)
47#define AMREX_PRAGMA_SIMD
48
49#elif defined(__HIP_DEVICE_COMPILE__) && defined(AMREX_USE_HIP)
50#define AMREX_PRAGMA_SIMD
51
52//#elif defined(AMREX_USE_OMP) && defined(_OPENMP) && (_OPENMP >= 201307) && !defined(__PGI)
53//#define AMREX_PRAGMA_SIMD _Pragma("omp simd")
54
55#elif defined(AMREX_CXX_INTEL)
56#define AMREX_PRAGMA_SIMD _Pragma("ivdep")
57
58#elif defined(AMREX_CXX_CRAY)
59#define AMREX_PRAGMA_SIMD _Pragma("ivdep")
60
61#elif defined(AMREX_CXX_PGI)
62#define AMREX_PRAGMA_SIMD _Pragma("loop ivdep")
63
64#elif defined(AMREX_CXX_NVHPC)
65#define AMREX_PRAGMA_SIMD _Pragma("loop ivdep")
66
67#elif defined(AMREX_CXX_NEC)
68#define AMREX_PRAGMA_SIMD
69
70#elif defined(AMREX_CXX_IBM)
71#define AMREX_PRAGMA_SIMD _Pragma("ibm independent_loop")
72
73#elif defined(__clang__)
74#define AMREX_PRAGMA_SIMD
75
76#elif defined(__GNUC__)
77#define AMREX_PRAGMA_SIMD _Pragma("GCC ivdep")
78
79#else
80#define AMREX_PRAGMA_SIMD
81
82#endif /* simd */
83
84// force inline
85#if defined(__CUDA_ARCH__) && defined(AMREX_USE_CUDA)
86#define AMREX_FORCE_INLINE __forceinline__
87
88#elif defined(__HIP_DEVICE_COMPILE__) && defined(AMREX_USE_HIP)
89#define AMREX_FORCE_INLINE __forceinline__
90
91#elif defined(AMREX_CXX_INTEL)
92#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
93
94#elif defined(AMREX_CXX_CRAY)
95#define AMREX_FORCE_INLINE inline
96
97#elif defined(AMREX_CXX_PGI)
98#define AMREX_FORCE_INLINE inline
99
100#elif defined(AMREX_CXX_NVHPC)
101#define AMREX_FORCE_INLINE inline
102
103#elif defined(AMREX_CXX_NEC)
104#define AMREX_FORCE_INLINE inline
105
106#elif defined(AMREX_CXX_IBM)
107#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
108
109#elif defined(__clang__)
110#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
111
112#elif defined(__GNUC__)
113#define AMREX_FORCE_INLINE inline __attribute__((always_inline))
114
115#elif defined(_MSC_VER)
116#define AMREX_FORCE_INLINE inline __forceinline
117
118#else
119#define AMREX_FORCE_INLINE inline
120
121#endif /* force inline */
122
123
124#ifdef AMREX_USE_FORCE_INLINE
125#define AMREX_INLINE AMREX_FORCE_INLINE
126#else
127#define AMREX_INLINE inline
128#endif
129
130// no inline
131#if defined(_MSC_VER)
132#define AMREX_NO_INLINE __declspec(noinline)
133#elif (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIP__) || defined(__INTEL_CLANG_COMPILER))
134#define AMREX_NO_INLINE __attribute__((noinline))
135#else
136#define AMREX_NO_INLINE
137#endif
138
139// flatten
140#if defined(_MSC_VER)
141#define AMREX_FLATTEN [[msvc::flatten]]
142#elif defined(__clang__) || defined(__GNUC__)
143#define AMREX_FLATTEN __attribute__((flatten))
144#else
145#define AMREX_FLATTEN
146#endif
147
148#ifdef AMREX_USE_FLATTEN_FOR
149#define AMREX_ATTRIBUTE_FLATTEN_FOR AMREX_FLATTEN
150#else
151#define AMREX_ATTRIBUTE_FLATTEN_FOR
152#endif
153
154// unroll loop
155#define AMREX_TO_STRING_HELPER(X) #X
156#define AMREX_TO_STRING(X) AMREX_TO_STRING_HELPER(X)
157
158#if defined(__clang__) || defined(__CUDACC__) || defined(__HIP__) || defined(__INTEL_CLANG_COMPILER)
159#define AMREX_UNROLL_LOOP(n) _Pragma(AMREX_TO_STRING(unroll n))
160#elif defined(__GNUC__)
161#define AMREX_UNROLL_LOOP(n) _Pragma(AMREX_TO_STRING(GCC unroll n))
162#else
163#define AMREX_UNROLL_LOOP(n)
164#endif
165
166// __attribute__((weak))
167
168#if defined(AMREX_TYPECHECK)
169#define AMREX_ATTRIBUTE_WEAK
170#elif defined(_WIN32)
171#define AMREX_ATTRIBUTE_WEAK
172#elif defined(__clang__) && defined(__apple_build_version__)
173#define AMREX_ATTRIBUTE_WEAK __attribute__((weak_import))
174#else
175#define AMREX_ATTRIBUTE_WEAK __attribute__((weak))
176#endif
177
178// public globals
179// https://stackoverflow.com/questions/54560832/cmake-windows-export-all-symbols-does-not-cover-global-variables/54568678#54568678
180#if defined(_MSC_VER)
181# if defined(AMREX_IS_DLL)
182# if defined(AMREX_IS_DLL_BUILDING)
183# define AMREX_EXPORT __declspec(dllexport)
184# else
185# define AMREX_EXPORT __declspec(dllimport)
186# endif
187# else
188# define AMREX_EXPORT
189# endif
190#else
191# define AMREX_EXPORT
192#endif
193
194#if defined(__cplusplus) && defined(_WIN32)
195#include <ciso646>
196#endif
197
198#if defined(__INTEL_COMPILER) && defined(__EDG__) && (__cplusplus < 201703L)
199// Classical EDG based Intel compiler does not support fallthrough when std=c++14
200# define AMREX_FALLTHROUGH ((void)0)
201#elif defined(__has_cpp_attribute) && __has_cpp_attribute(fallthrough) >= 201603L
202# define AMREX_FALLTHROUGH [[fallthrough]]
203#elif defined(__clang__)
204# define AMREX_FALLTHROUGH [[clang::fallthrough]]
205#elif defined(__GNUC__) && (__GNUC__ >= 7)
206# define AMREX_FALLTHROUGH [[gnu::fallthrough]]
207#else
208# define AMREX_FALLTHROUGH ((void)0)
209#endif
210
211// Note: following compilers support [[likely]] and [[unlikely]]
212// - Clang >= 12.0
213// - GCC >= 9.0
214// - Intel >= 2021.7
215// - MSVC >= 19.26
216// - nvcc >= 12
217#if defined(__has_cpp_attribute) && __has_cpp_attribute(likely) >= 201803L
218# define AMREX_LIKELY [[likely]]
219# define AMREX_UNLIKELY [[unlikely]]
220#else
221# define AMREX_LIKELY
222# define AMREX_UNLIKELY
223#endif
224
225// Note: following compilers support assumptions, at least using builtin functions:
226// - Clang >= 3.7
227// - GCC >= 5.1
228// - MSVC >= 19.20
229// - nvcc >= 11.1.0
230// - icx >= 2021.1.2
231#if defined(__has_cpp_attribute) && __has_cpp_attribute(assume)
232# define AMREX_ASSUME(ASSUMPTION) [[assume(ASSUMPTION)]]
233#else
234# if defined(__CUDA_ARCH__) && defined(__CUDACC__) && ( (__CUDACC_VER_MAJOR__ > 11) || ((__CUDACC_VER_MAJOR__ == 11) && (__CUDACC_VER_MINOR__ >= 2)) )
235# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
236# elif defined(AMREX_CXX_INTEL) || defined(__clang__)
237# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
238# elif defined(_MSC_VER)
239# define AMREX_ASSUME(ASSUMPTION) __assume(ASSUMPTION)
240# elif defined(__GNUC__)
241# define AMREX_ASSUME(ASSUMPTION) if (ASSUMPTION) {} else { __builtin_unreachable(); }
242# else
243# define AMREX_ASSUME(ASSUMPTION)
244# endif
245#endif
246
247// CI uses -Werror -Wc++17-extension, thus we need to add the __cplusplus clause
248#if !defined(AMREX_NO_NODISCARD) && defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard) >= 201603L
249# define AMREX_NODISCARD [[nodiscard]]
250#else
251# define AMREX_NODISCARD
252#endif
253
254// Note: following compilers support [[no_unique_address]]
255// - Clang >= 9.0
256// - GCC >= 9.0
257// - MSVC >= 19.26
258// Using no unique address makes empty base class optimization for multiple policies much easier
259#if !defined(AMREX_NO_NO_UNIQUE_ADDRESS) && defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address) >= 201803L
260# define AMREX_NO_UNIQUE_ADDRESS [[no_unique_address]]
261# define AMREX_HAS_NO_UNIQUE_ADDRESS 1
262#else
263# define AMREX_NO_UNIQUE_ADDRESS
264#endif
265
266#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
267# define AMREX_IF_CONSTEXPR if constexpr
268#else
269# define AMREX_IF_CONSTEXPR if
270#endif
271
272#if !defined(AMREX_NO_BUILTIN_CLZ)
273# if defined(__clang__) || defined(__GNUC__)
274# define AMREX_HAS_BUILTIN_CLZ 1
275# endif
276#endif
277
278
279#endif /* !BL_LANG_FORT */
280
281#endif