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// __attribute__((weak))
172
173#if defined(AMREX_TYPECHECK)
174#define AMREX_ATTRIBUTE_WEAK
175#elif defined(_WIN32)
176#define AMREX_ATTRIBUTE_WEAK
177#elif defined(__clang__) && defined(__apple_build_version__)
178#define AMREX_ATTRIBUTE_WEAK __attribute__((weak_import))
179#else
180#define AMREX_ATTRIBUTE_WEAK __attribute__((weak))
181#endif
182
183// public globals
184// https://stackoverflow.com/questions/54560832/cmake-windows-export-all-symbols-does-not-cover-global-variables/54568678#54568678
185#if defined(_MSC_VER)
186# if defined(AMREX_IS_DLL)
187# if defined(AMREX_IS_DLL_BUILDING)
188# define AMREX_EXPORT __declspec(dllexport)
189# else
190# define AMREX_EXPORT __declspec(dllimport)
191# endif
192# else
193# define AMREX_EXPORT
194# endif
195#else
196# define AMREX_EXPORT
197#endif
198
199#if defined(__cplusplus) && defined(_WIN32)
200#include <ciso646>
201#endif
202
203#if defined(__INTEL_COMPILER) && defined(__EDG__) && (__cplusplus < 201703L)
204// Classical EDG based Intel compiler does not support fallthrough when std=c++14
205# define AMREX_FALLTHROUGH ((void)0)
206#elif defined(__has_cpp_attribute) && __has_cpp_attribute(fallthrough) >= 201603L
207# define AMREX_FALLTHROUGH [[fallthrough]]
208#elif defined(__clang__)
209# define AMREX_FALLTHROUGH [[clang::fallthrough]]
210#elif defined(__GNUC__) && (__GNUC__ >= 7)
211# define AMREX_FALLTHROUGH [[gnu::fallthrough]]
212#else
213# define AMREX_FALLTHROUGH ((void)0)
214#endif
215
216// Note: following compilers support [[likely]] and [[unlikely]]
217// - Clang >= 12.0
218// - GCC >= 9.0
219// - Intel >= 2021.7
220// - MSVC >= 19.26
221// - nvcc >= 12
222#if defined(__has_cpp_attribute) && __has_cpp_attribute(likely) >= 201803L
223# define AMREX_LIKELY [[likely]]
224# define AMREX_UNLIKELY [[unlikely]]
225#else
226# define AMREX_LIKELY
227# define AMREX_UNLIKELY
228#endif
229
230// Note: following compilers support assumptions, at least using builtin functions:
231// - Clang >= 3.7
232// - GCC >= 5.1
233// - MSVC >= 19.20
234// - nvcc >= 11.1.0
235// - icx >= 2021.1.2
236#if defined(__has_cpp_attribute) && __has_cpp_attribute(assume)
237# define AMREX_ASSUME(ASSUMPTION) [[assume(ASSUMPTION)]]
238#else
239# if defined(__CUDA_ARCH__) && defined(__CUDACC__)
240# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
241# elif defined(AMREX_CXX_INTEL) || defined(__clang__)
242# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
243# elif defined(_MSC_VER)
244# define AMREX_ASSUME(ASSUMPTION) __assume(ASSUMPTION)
245# elif defined(__GNUC__)
246# define AMREX_ASSUME(ASSUMPTION) \
247 do { if (!(ASSUMPTION)) { __builtin_unreachable(); } } while (0)
248# else
249# define AMREX_ASSUME(ASSUMPTION)
250# endif
251#endif
252
253// CI uses -Werror -Wc++17-extension, thus we need to add the __cplusplus clause
254#if !defined(AMREX_NO_NODISCARD) && defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard) >= 201603L
255# define AMREX_NODISCARD [[nodiscard]]
256#else
257# define AMREX_NODISCARD
258#endif
259
260// Note: following compilers support [[no_unique_address]]
261// - Clang >= 9.0
262// - GCC >= 9.0
263// - MSVC >= 19.26
264// Using no unique address makes empty base class optimization for multiple policies much easier
265#if !defined(AMREX_NO_NO_UNIQUE_ADDRESS) && defined(__has_cpp_attribute) && __has_cpp_attribute(no_unique_address) >= 201803L
266# define AMREX_NO_UNIQUE_ADDRESS [[no_unique_address]]
267# define AMREX_HAS_NO_UNIQUE_ADDRESS 1
268#else
269# define AMREX_NO_UNIQUE_ADDRESS
270#endif
271
272#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
273# define AMREX_IF_CONSTEXPR if constexpr
274#else
275# define AMREX_IF_CONSTEXPR if
276#endif
277
278#endif /* !BL_LANG_FORT */
279
280#endif