Macros.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. #ifndef C10_MACROS_MACROS_H_
  2. #define C10_MACROS_MACROS_H_
  3. #include <cassert>
  4. /* Main entry for c10/macros.
  5. *
  6. * In your code, include c10/macros/Macros.h directly, instead of individual
  7. * files in this folder.
  8. */
  9. // For build systems that do not directly depend on CMake and directly build
  10. // from the source directory (such as Buck), one may not have a cmake_macros.h
  11. // file at all. In this case, the build system is responsible for providing
  12. // correct macro definitions corresponding to the cmake_macros.h.in file.
  13. //
  14. // In such scenarios, one should define the macro
  15. // C10_USING_CUSTOM_GENERATED_MACROS
  16. // to inform this header that it does not need to include the cmake_macros.h
  17. // file.
  18. #ifndef C10_USING_CUSTOM_GENERATED_MACROS
  19. #include <c10/macros/cmake_macros.h>
  20. #endif // C10_USING_CUSTOM_GENERATED_MACROS
  21. #include <c10/macros/Export.h>
  22. #if defined(__clang__)
  23. #define __ubsan_ignore_float_divide_by_zero__ \
  24. __attribute__((no_sanitize("float-divide-by-zero")))
  25. #define __ubsan_ignore_undefined__ __attribute__((no_sanitize("undefined")))
  26. #define __ubsan_ignore_signed_int_overflow__ \
  27. __attribute__((no_sanitize("signed-integer-overflow")))
  28. #define __ubsan_ignore_function__ __attribute__((no_sanitize("function")))
  29. #else
  30. #define __ubsan_ignore_float_divide_by_zero__
  31. #define __ubsan_ignore_undefined__
  32. #define __ubsan_ignore_signed_int_overflow__
  33. #define __ubsan_ignore_function__
  34. #endif
  35. // Detect address sanitizer as some stuff doesn't work with it
  36. #undef C10_ASAN_ENABLED
  37. // for clang
  38. #if defined(__has_feature)
  39. #if ((__has_feature(address_sanitizer)))
  40. #define C10_ASAN_ENABLED 1
  41. #endif
  42. #endif
  43. // for gcc
  44. #if defined(__SANITIZE_ADDRESS__)
  45. #if __SANITIZE_ADDRESS__
  46. #if !defined(C10_ASAN_ENABLED)
  47. #define C10_ASAN_ENABLED 1
  48. #endif
  49. #endif
  50. #endif
  51. #if !defined(C10_ASAN_ENABLED)
  52. #define C10_ASAN_ENABLED 0
  53. #endif
  54. // Disable the copy and assignment operator for a class. Note that this will
  55. // disable the usage of the class in std containers.
  56. #define C10_DISABLE_COPY_AND_ASSIGN(classname) \
  57. classname(const classname&) = delete; \
  58. classname& operator=(const classname&) = delete
  59. #define C10_CONCATENATE_IMPL(s1, s2) s1##s2
  60. #define C10_CONCATENATE(s1, s2) C10_CONCATENATE_IMPL(s1, s2)
  61. #define C10_MACRO_EXPAND(args) args
  62. #define C10_STRINGIZE_IMPL(x) #x
  63. #define C10_STRINGIZE(x) C10_STRINGIZE_IMPL(x)
  64. /**
  65. * C10_ANONYMOUS_VARIABLE(str) introduces an identifier starting with
  66. * str and ending with a number that varies with the line.
  67. */
  68. #ifdef __COUNTER__
  69. #define C10_UID __COUNTER__
  70. #define C10_ANONYMOUS_VARIABLE(str) C10_CONCATENATE(str, __COUNTER__)
  71. #else
  72. #define C10_UID __LINE__
  73. #define C10_ANONYMOUS_VARIABLE(str) C10_CONCATENATE(str, __LINE__)
  74. #endif
  75. #ifdef __has_cpp_attribute
  76. #define C10_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
  77. #else
  78. #define C10_HAS_CPP_ATTRIBUTE(x) (0)
  79. #endif
  80. /// C10_NODISCARD - Warn if a type or return value is discarded.
  81. // Technically, we should check if __cplusplus > 201402L here, because
  82. // [[nodiscard]] is only defined in C++17. However, some compilers
  83. // we care about don't advertise being C++17 (e.g., clang), but
  84. // support the attribute anyway. In fact, this is not just a good idea,
  85. // it's the law: clang::warn_unused_result doesn't work on nvcc + clang
  86. // and the best workaround for this case is to use [[nodiscard]]
  87. // instead; see https://github.com/pytorch/pytorch/issues/13118
  88. //
  89. // Note to future editors: if you have noticed that a compiler is
  90. // misbehaving (e.g., it advertises support, but the support doesn't
  91. // actually work, or it is emitting warnings). Some compilers which
  92. // are strict about the matter include MSVC, which will complain:
  93. //
  94. // error C2429: attribute 'nodiscard' requires compiler flag '/std:c++latest'
  95. //
  96. // Exhibits:
  97. // - MSVC 19.14: https://godbolt.org/z/Dzd7gn (requires /std:c++latest)
  98. // - Clang 8.0.0: https://godbolt.org/z/3PYL4Z (always advertises support)
  99. // - gcc 8.3: https://godbolt.org/z/4tLMQS (always advertises support)
  100. #if C10_HAS_CPP_ATTRIBUTE(nodiscard)
  101. #define C10_NODISCARD [[nodiscard]]
  102. // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
  103. // error when __has_cpp_attribute is given a scoped attribute in C mode.
  104. #elif __cplusplus && C10_HAS_CPP_ATTRIBUTE(clang::warn_unused_result)
  105. // TODO: It's possible this is still triggering
  106. // https://github.com/pytorch/pytorch/issues/13118 on Windows; if it is, better
  107. // fix it.
  108. #define C10_NODISCARD [[clang::warn_unused_result]]
  109. #else
  110. #define C10_NODISCARD
  111. #endif
  112. // suppress an unused variable.
  113. #if defined(_MSC_VER) && !defined(__clang__)
  114. #define C10_UNUSED __pragma(warning(suppress : 4100 4101))
  115. #else
  116. #define C10_UNUSED __attribute__((__unused__))
  117. #endif //_MSC_VER
  118. // Direct port of LLVM_ATTRIBUTE_USED.
  119. #if __has_attribute(used)
  120. #define C10_USED __attribute__((__used__))
  121. #else
  122. #define C10_USED
  123. #endif
  124. #define C10_RESTRICT __restrict
  125. // Simply define the namespace, in case a dependent library want to refer to
  126. // the c10 namespace but not any nontrivial files.
  127. namespace c10 {} // namespace c10
  128. namespace c10 {
  129. namespace cuda {}
  130. } // namespace c10
  131. namespace c10 {
  132. namespace hip {}
  133. } // namespace c10
  134. // Since C10 is the core library for caffe2 (and aten), we will simply reroute
  135. // all abstractions defined in c10 to be available in caffe2 as well.
  136. // This is only for backwards compatibility. Please use the symbols from the
  137. // c10 namespace where possible.
  138. namespace caffe2 {
  139. using namespace c10;
  140. }
  141. namespace at {
  142. using namespace c10;
  143. }
  144. namespace at {
  145. namespace cuda {
  146. using namespace c10::cuda;
  147. }
  148. } // namespace at
  149. // WARNING!!! THIS IS A GIANT HACK!!!
  150. // This line means you cannot simultaneously include c10/hip
  151. // and c10/cuda and then use them from the at::cuda namespace.
  152. // This is true in practice, because HIPIFY works inplace on
  153. // files in ATen/cuda, so it assumes that c10::hip is available
  154. // from at::cuda. This namespace makes that happen. When
  155. // HIPIFY is no longer out-of-place, we can switch the cuda
  156. // here to hip and everyone is happy.
  157. namespace at {
  158. namespace cuda {
  159. using namespace c10::hip;
  160. }
  161. } // namespace at
  162. // C10_LIKELY/C10_UNLIKELY
  163. //
  164. // These macros provide parentheses, so you can use these macros as:
  165. //
  166. // if C10_LIKELY(some_expr) {
  167. // ...
  168. // }
  169. //
  170. // NB: static_cast to boolean is mandatory in C++, because __builtin_expect
  171. // takes a long argument, which means you may trigger the wrong conversion
  172. // without it.
  173. //
  174. #if defined(__GNUC__) || defined(__ICL) || defined(__clang__)
  175. #define C10_LIKELY(expr) (__builtin_expect(static_cast<bool>(expr), 1))
  176. #define C10_UNLIKELY(expr) (__builtin_expect(static_cast<bool>(expr), 0))
  177. #else
  178. #define C10_LIKELY(expr) (expr)
  179. #define C10_UNLIKELY(expr) (expr)
  180. #endif
  181. /// C10_NOINLINE - Functions whose declaration is annotated with this will not
  182. /// be inlined.
  183. #ifdef __GNUC__
  184. #define C10_NOINLINE __attribute__((noinline))
  185. #elif _MSC_VER
  186. #define C10_NOINLINE __declspec(noinline)
  187. #else
  188. #define C10_NOINLINE
  189. #endif
  190. #if defined(_MSC_VER)
  191. #define C10_ALWAYS_INLINE __forceinline
  192. #elif __has_attribute(always_inline) || defined(__GNUC__)
  193. #define C10_ALWAYS_INLINE __attribute__((__always_inline__)) inline
  194. #else
  195. #define C10_ALWAYS_INLINE inline
  196. #endif
  197. #if defined(_MSC_VER)
  198. #define C10_ATTR_VISIBILITY_HIDDEN
  199. #elif defined(__GNUC__)
  200. #define C10_ATTR_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
  201. #else
  202. #define C10_ATTR_VISIBILITY_HIDDEN
  203. #endif
  204. #define C10_ERASE C10_ALWAYS_INLINE C10_ATTR_VISIBILITY_HIDDEN
  205. // C10_FALLTHROUGH - Annotate fallthrough to the next case in a switch.
  206. #if C10_HAS_CPP_ATTRIBUTE(fallthrough)
  207. #define C10_FALLTHROUGH [[fallthrough]]
  208. #else
  209. #define C10_FALLTHROUGH
  210. #endif
  211. #include <cstdint>
  212. #ifdef __HIPCC__
  213. // Unlike CUDA, HIP requires a HIP header to be included for __host__ to work.
  214. // We do this #include here so that C10_HOST_DEVICE and friends will Just Work.
  215. // See https://github.com/ROCm-Developer-Tools/HIP/issues/441
  216. #include <hip/hip_runtime.h>
  217. #endif
  218. #if defined(__CUDACC__) || defined(__HIPCC__)
  219. // Designates functions callable from the host (CPU) and the device (GPU)
  220. #define C10_HOST_DEVICE __host__ __device__
  221. #define C10_DEVICE __device__
  222. #define C10_HOST __host__
  223. // constants from
  224. // (https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#features-and-technical-specifications)
  225. // The maximum number of threads per multiprocessor is 1024 for Turing
  226. // architecture (7.5), 1536 for Geforce Ampere (8.6)/Jetson Orin (8.7), and
  227. // 2048 for all other architectures. You'll get warnings if you exceed these
  228. // constants. Hence, the following macros adjust the input values from the user
  229. // to resolve potential warnings.
  230. #if __CUDA_ARCH__ == 750
  231. constexpr uint32_t CUDA_MAX_THREADS_PER_SM = 1024;
  232. #elif __CUDA_ARCH__ == 860 || __CUDA_ARCH__ == 870 || __CUDA_ARCH__ == 890
  233. constexpr uint32_t CUDA_MAX_THREADS_PER_SM = 1536;
  234. #else
  235. constexpr uint32_t CUDA_MAX_THREADS_PER_SM = 2048;
  236. #endif
  237. // CUDA_MAX_THREADS_PER_BLOCK is same for all architectures currently
  238. constexpr uint32_t CUDA_MAX_THREADS_PER_BLOCK = 1024;
  239. // CUDA_THREADS_PER_BLOCK_FALLBACK is the "canonical fallback" choice of block
  240. // size. 256 is a good number for this fallback and should give good occupancy
  241. // and versatility across all architectures.
  242. constexpr uint32_t CUDA_THREADS_PER_BLOCK_FALLBACK = 256;
  243. // NOTE: if you are thinking of constexpr-ify the inputs to launch bounds, it
  244. // turns out that although __launch_bounds__ can take constexpr, it
  245. // can't take a constexpr that has anything to do with templates.
  246. // Currently we use launch_bounds that depend on template arguments in
  247. // Loops.cuh, Reduce.cuh and LossCTC.cuh. Hence, C10_MAX_THREADS_PER_BLOCK
  248. // and C10_MIN_BLOCKS_PER_SM are kept as macros.
  249. // Suppose you were planning to write __launch_bounds__(a, b), based on your
  250. // performance tuning on a modern GPU. Instead, you should write
  251. // __launch_bounds__(C10_MAX_THREADS_PER_BLOCK(a), C10_MIN_BLOCKS_PER_SM(a, b)),
  252. // which will also properly respect limits on old architectures.
  253. #define C10_MAX_THREADS_PER_BLOCK(val) \
  254. (((val) <= CUDA_MAX_THREADS_PER_BLOCK) ? (val) \
  255. : CUDA_THREADS_PER_BLOCK_FALLBACK)
  256. #define C10_MIN_BLOCKS_PER_SM(threads_per_block, blocks_per_sm) \
  257. ((((threads_per_block) * (blocks_per_sm) <= CUDA_MAX_THREADS_PER_SM) \
  258. ? (blocks_per_sm) \
  259. : ((CUDA_MAX_THREADS_PER_SM + (threads_per_block)-1) / \
  260. (threads_per_block))))
  261. // C10_LAUNCH_BOUNDS is analogous to __launch_bounds__
  262. #define C10_LAUNCH_BOUNDS_0 \
  263. __launch_bounds__( \
  264. 256, 4) // default launch bounds that should give good occupancy and
  265. // versatility across all architectures.
  266. #define C10_LAUNCH_BOUNDS_1(max_threads_per_block) \
  267. __launch_bounds__((C10_MAX_THREADS_PER_BLOCK((max_threads_per_block))))
  268. #define C10_LAUNCH_BOUNDS_2(max_threads_per_block, min_blocks_per_sm) \
  269. __launch_bounds__( \
  270. (C10_MAX_THREADS_PER_BLOCK((max_threads_per_block))), \
  271. (C10_MIN_BLOCKS_PER_SM((max_threads_per_block), (min_blocks_per_sm))))
  272. #else
  273. #define C10_HOST_DEVICE
  274. #define C10_HOST
  275. #define C10_DEVICE
  276. #endif
  277. #if defined(USE_ROCM)
  278. #define C10_HIP_HOST_DEVICE __host__ __device__
  279. #else
  280. #define C10_HIP_HOST_DEVICE
  281. #endif
  282. #if defined(USE_ROCM)
  283. #define C10_WARP_SIZE warpSize // = 64 or 32 (Defined in hip_runtime.h)
  284. #else
  285. #define C10_WARP_SIZE 32
  286. #endif
  287. #if defined(_MSC_VER) && _MSC_VER <= 1900
  288. #define __func__ __FUNCTION__
  289. #endif
  290. // CUDA_KERNEL_ASSERT checks the assertion
  291. // even when NDEBUG is defined. This is useful for important assertions in CUDA
  292. // code that would otherwise be suppressed when building Release.
  293. #if defined(__ANDROID__) || defined(__APPLE__) || \
  294. (defined(USE_ROCM) && ROCM_VERSION < 40100)
  295. // Those platforms do not support assert()
  296. #define CUDA_KERNEL_ASSERT(cond)
  297. #define SYCL_KERNEL_ASSERT(cond)
  298. #elif defined(_MSC_VER)
  299. #if defined(NDEBUG)
  300. extern "C" {
  301. C10_IMPORT
  302. #if defined(__SYCL_DEVICE_ONLY__)
  303. extern SYCL_EXTERNAL void _wassert(
  304. const wchar_t* wexpr,
  305. const wchar_t* wfile,
  306. unsigned line);
  307. #else
  308. #if defined(__CUDA_ARCH__)
  309. __host__ __device__
  310. #endif // __CUDA_ARCH__
  311. void
  312. _wassert(wchar_t const* _Message, wchar_t const* _File, unsigned _Line);
  313. #endif // __SYCL_DEVICE_ONLY__
  314. }
  315. #endif // NDEBUG
  316. #define CUDA_KERNEL_ASSERT(cond) \
  317. if (C10_UNLIKELY(!(cond))) { \
  318. (void)(_wassert(_CRT_WIDE(#cond), _CRT_WIDE(__FILE__), static_cast<unsigned>(__LINE__)), 0); \
  319. }
  320. #define SYCL_KERNEL_ASSERT(cond) \
  321. if (C10_UNLIKELY(!(cond))) { \
  322. (void)(_wassert(_CRT_WIDE(#cond), _CRT_WIDE(__FILE__), static_cast<unsigned>(__LINE__)), 0); \
  323. }
  324. #else // __APPLE__, _MSC_VER
  325. #if defined(NDEBUG)
  326. extern "C" {
  327. #if defined(__SYCL_DEVICE_ONLY__)
  328. extern SYCL_EXTERNAL void __assert_fail(
  329. const char* expr,
  330. const char* file,
  331. unsigned int line,
  332. const char* func);
  333. #else // __SYCL_DEVICE_ONLY__
  334. #if ( \
  335. defined(__CUDA_ARCH__) && !(defined(__clang__) && defined(__CUDA__)) && \
  336. !defined(TORCH_DISABLE_GPU_ASSERTS))
  337. // CUDA supports __assert_fail function which are common for both device
  338. // and host side code.
  339. __host__ __device__
  340. #endif
  341. // This forward declaration matching the declaration of __assert_fail
  342. // exactly how it is in glibc in case parts of the program are compiled with
  343. // different NDEBUG settings. Otherwise we might get 'ambiguous declaration'
  344. // error. Note: On ROCm - this declaration serves for host side compilation.
  345. void
  346. __assert_fail(
  347. const char* assertion,
  348. const char* file,
  349. unsigned int line,
  350. const char* function) noexcept __attribute__((__noreturn__));
  351. #if (defined(__HIP_ARCH__) || defined(__HIP__)) && \
  352. !defined(TORCH_DISABLE_GPU_ASSERTS)
  353. // ROCm supports __assert_fail only as a device side function.
  354. __device__ __attribute__((noinline)) __attribute__((weak)) void __assert_fail(
  355. const char* assertion,
  356. const char* file,
  357. unsigned int line,
  358. const char* function);
  359. #endif // defined(__HIP_ARCH__) || defined(__HIP__)
  360. #endif // __SYCL_DEVICE_ONLY__
  361. }
  362. #endif // NDEBUG
  363. #define CUDA_KERNEL_ASSERT(cond) \
  364. if (C10_UNLIKELY(!(cond))) { \
  365. __assert_fail( \
  366. #cond, __FILE__, static_cast<unsigned int>(__LINE__), __func__); \
  367. }
  368. #define SYCL_KERNEL_ASSERT(cond) \
  369. if (C10_UNLIKELY(!(cond))) { \
  370. __assert_fail( \
  371. #cond, __FILE__, static_cast<unsigned int>(__LINE__), __func__); \
  372. }
  373. #endif // __APPLE__
  374. #ifdef __APPLE__
  375. #include <TargetConditionals.h>
  376. #endif
  377. #if defined(__ANDROID__)
  378. #define C10_ANDROID 1
  379. #define C10_MOBILE 1
  380. #elif ( \
  381. defined(__APPLE__) && \
  382. (TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR || TARGET_OS_IPHONE))
  383. #define C10_IOS 1
  384. #define C10_MOBILE 1
  385. #endif // ANDROID / IOS
  386. #if defined(C10_MOBILE) && C10_MOBILE
  387. #define C10_ALWAYS_INLINE_UNLESS_MOBILE inline
  388. #else
  389. #define C10_ALWAYS_INLINE_UNLESS_MOBILE C10_ALWAYS_INLINE
  390. #endif
  391. // Portable determination of whether type T is trivially copyable.
  392. // Warning: __has_trivial_copy for GCC may not always detect the non-POD
  393. // correctly. For example, T = std::unique_ptr may evaluate to true and be
  394. // treated as POD. This can cause unexpected behavior.
  395. #if defined(__GNUG__) && __GNUC__ < 5 && !defined(__clang__)
  396. #define C10_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
  397. #else
  398. #define C10_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value
  399. #endif
  400. #if defined(__CUDA_ARCH__)
  401. #if defined(_MSC_VER) && defined(__CUDACC__)
  402. #define CONSTEXPR_EXCEPT_WIN_CUDA const
  403. #define C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA __host__
  404. // Note [static constexpr char* members for windows NVCC]
  405. // The Windows NVCC compiler doesn't handle static constexpr class members,
  406. // although it's fixed in a later version.
  407. // (see
  408. // https://developercommunity.visualstudio.com/t/intellisense-error-c11-static-constexpr-member-ini/245425)
  409. //
  410. // If we want to ensure that our field is static under all builds, then we need
  411. // to work around it specifically for windows NVCC by making it (a) const, (b)
  412. // defined outside of the class definition We need to define it outside of the
  413. // class definition because of the C++ standard; char* is not an integral type
  414. // (see
  415. // https://stackoverflow.com/questions/24278473/intellisense-a-member-of-type-const-char-const-cannot-have-an-in-class-in)
  416. //
  417. // So instead of this:
  418. // struct Foo {
  419. // static constexpr const char* name = "foo";
  420. // }
  421. // In Windows NVCC, we end up with this:
  422. // struct Foo {
  423. // static const char* name;
  424. // }
  425. // const char* Foo::name = "foo";
  426. //
  427. // This gives us a small perf hit for any code that wants to access these field
  428. // members, but right now it isn't used in any perf-critical code paths.
  429. #define STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(field, val) \
  430. static const char* field;
  431. #define STATIC_CONST_STR_OUT_OF_LINE_FOR_WIN_CUDA(cls, field, val) \
  432. const char* cls::field = val;
  433. #else
  434. #define CONSTEXPR_EXCEPT_WIN_CUDA constexpr
  435. #define C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA __host__
  436. #define STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(field, val) \
  437. static constexpr const char* field = val;
  438. #define STATIC_CONST_STR_OUT_OF_LINE_FOR_WIN_CUDA(cls, field, val)
  439. #endif
  440. #else
  441. #if defined(_MSC_VER) && defined(__CUDACC__)
  442. #define CONSTEXPR_EXCEPT_WIN_CUDA const
  443. #define C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA
  444. #define STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(field, val) \
  445. static const char* field;
  446. #define STATIC_CONST_STR_OUT_OF_LINE_FOR_WIN_CUDA(cls, field, val) \
  447. const char* cls::field = val;
  448. #else
  449. #define CONSTEXPR_EXCEPT_WIN_CUDA constexpr
  450. #define C10_HOST_CONSTEXPR_EXCEPT_WIN_CUDA constexpr
  451. #define STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(field, val) \
  452. static constexpr const char* field = val;
  453. #define STATIC_CONST_STR_OUT_OF_LINE_FOR_WIN_CUDA(cls, field, val)
  454. #endif
  455. #endif
  456. #ifndef HAS_DEMANGLE
  457. #if defined(__ANDROID__) || defined(_WIN32) || defined(__EMSCRIPTEN__)
  458. #define HAS_DEMANGLE 0
  459. #elif defined(__APPLE__) && \
  460. (TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR || TARGET_OS_IPHONE)
  461. #define HAS_DEMANGLE 0
  462. #else
  463. #define HAS_DEMANGLE 1
  464. #endif
  465. #endif // HAS_DEMANGLE
  466. #define _C10_PRAGMA__(string) _Pragma(#string)
  467. #define _C10_PRAGMA_(string) _C10_PRAGMA__(string)
  468. #ifdef __clang__
  469. #define C10_CLANG_DIAGNOSTIC_PUSH() _Pragma("clang diagnostic push")
  470. #define C10_CLANG_DIAGNOSTIC_POP() _Pragma("clang diagnostic pop")
  471. #define C10_CLANG_DIAGNOSTIC_IGNORE(flag) \
  472. _C10_PRAGMA_(clang diagnostic ignored flag)
  473. #define C10_CLANG_HAS_WARNING(flag) __has_warning(flag)
  474. #else
  475. #define C10_CLANG_DIAGNOSTIC_PUSH()
  476. #define C10_CLANG_DIAGNOSTIC_POP()
  477. #define C10_CLANG_DIAGNOSTIC_IGNORE(flag)
  478. #define C10_CLANG_HAS_WARNING(flag) 0
  479. #endif
  480. #ifdef __clang__
  481. #define C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED(warning) \
  482. _C10_PRAGMA_(clang diagnostic push) \
  483. _C10_PRAGMA_(clang diagnostic ignored "-Wunknown-warning-option") \
  484. _C10_PRAGMA_(clang diagnostic ignored warning)
  485. #define C10_DIAGNOSTIC_POP() _C10_PRAGMA_(clang diagnostic pop)
  486. #elif __GNUC__
  487. #define C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED(warning) \
  488. _C10_PRAGMA_(GCC diagnostic push) \
  489. _C10_PRAGMA_(GCC diagnostic ignored "-Wpragmas") \
  490. _C10_PRAGMA_(GCC diagnostic ignored warning)
  491. #define C10_DIAGNOSTIC_POP() _C10_PRAGMA_(GCC diagnostic pop)
  492. #else
  493. #define C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED(warning)
  494. #define C10_DIAGNOSTIC_POP()
  495. #endif
  496. #endif // C10_MACROS_MACROS_H_