// -*- C++ -*- //===---------------------------- test_macros.h ---------------------------===// // // 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 // SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// // Modifications Copyright (c) 2024-2026 Advanced Micro Devices, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #ifndef SUPPORT_TEST_MACROS_HPP #define SUPPORT_TEST_MACROS_HPP #include #include #include // Use the CCCL compiler detection #define TEST_COMPILER(...) _CCCL_COMPILER(__VA_ARGS__) #define TEST_CUDA_COMPILER(...) _CCCL_CUDA_COMPILER(__VA_ARGS__) #define TEST_HAS_CUDA_COMPILER _CCCL_HAS_CUDA_COMPILER() // Use the CCCL diagnostic suppression #define TEST_DIAG_SUPPRESS_CLANG(...) _CCCL_DIAG_SUPPRESS_CLANG(__VA_ARGS__) #define TEST_DIAG_SUPPRESS_GCC(...) _CCCL_DIAG_SUPPRESS_GCC(__VA_ARGS__) #define TEST_DIAG_SUPPRESS_NVHPC(...) _CCCL_DIAG_SUPPRESS_NVHPC(__VA_ARGS__) #define TEST_DIAG_SUPPRESS_MSVC(...) _CCCL_DIAG_SUPPRESS_MSVC(__VA_ARGS__) #define TEST_NV_DIAG_SUPPRESS(...) _CCCL_BEGIN_NV_DIAG_SUPPRESS(__VA_ARGS__) // Use the CCCL C++ dialect detection #define TEST_STD_VER _CCCL_STD_VER // Use the CCCL constexpr macros #define TEST_CONSTEXPR_CXX20 _CCCL_CONSTEXPR_CXX20 #define TEST_CONSTEXPR_CXX23 _CCCL_CONSTEXPR_CXX23 #if defined(__HIPCC__) // This is not mutually exclusive with other compilers, as NVCC uses a host // compiler. # define TEST_COMPILER_HIPCC #endif #if defined(__HIPCC_RTC__) # define TEST_COMPILER_HIPRTC #endif // NOTE(HIP/AMD): temporary WAR due to incompatibility with rocThrust for some macros #ifndef NV_IF_TARGET #define NV_IF_TARGET NV_IF_TARGET_LIBHIPCXX #endif #ifndef NV_IS_HOST #define NV_IS_HOST NV_IS_HOST_LIBHIPCXX #endif #ifndef NV_IS_DEVICE #define NV_IS_DEVICE NV_IS_DEVICE_LIBHIPCXX #endif // Use the CCCL global variable hack #define TEST_GLOBAL_VARIABLE static _CCCL_GLOBAL_VARIABLE #if defined(_CCCL_BUILTIN_IS_CONSTANT_EVALUATED) # define TEST_IS_CONSTANT_EVALUATED() cuda::std::is_constant_evaluated() #else # define TEST_IS_CONSTANT_EVALUATED() false #endif #if TEST_STD_VER >= 2023 # define TEST_IS_CONSTANT_EVALUATED_CXX23() TEST_IS_CONSTANT_EVALUATED() #else // ^^^ C++23 ^^^ / vvv C++20 vvv # define TEST_IS_CONSTANT_EVALUATED_CXX23() false #endif // ^^^ TEST_STD_VER <= 2020 // Attempt to deduce the GLIBC version #if _CCCL_HAS_INCLUDE() || defined(__linux__) # include # if defined(__GLIBC_PREREQ) # define TEST_HAS_GLIBC # define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor) # endif #endif #if defined(TEST_COMPILER_HIPRTC) # define NEW_IS_NOEXCEPT_HIPRTC noexcept #else # define NEW_IS_NOEXCEPT_HIPRTC #endif // TEST_COMPILER_HIPRTC // Sniff out to see if the underling C library has C11 features // Note that at this time (July 2018), MacOS X and iOS do NOT. // This is cribbed from __config; but lives here as well because we can't assume libc++ #if defined(__linux__) // This block preserves the old behavior used by include/__config: // _LIBCUDACXX_GLIBC_PREREQ would be defined to 0 if __GLIBC_PREREQ was not // available. The configuration here may be too vague though, as Bionic, uClibc, // newlib, etc may all support these features but need to be configured. # if defined(TEST_GLIBC_PREREQ) # if TEST_GLIBC_PREREQ(2, 17) # define TEST_HAS_TIMESPEC_GET # define TEST_HAS_C11_FEATURES # endif # elif defined(_LIBCUDACXX_HAS_MUSL_LIBC) # define TEST_HAS_C11_FEATURES # define TEST_HAS_TIMESPEC_GET # endif #endif #if !_CCCL_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) && !defined(__GXX_RTTI) # define TEST_HAS_NO_RTTI #endif #ifndef TEST_HAS_NO_EXCEPTIONS # if (_CCCL_COMPILER(MSVC) && _HAS_EXCEPTIONS == 0) || (!_CCCL_COMPILER(MSVC) && !__EXCEPTIONS) // Catches all non // msvc based // compilers # define TEST_HAS_NO_EXCEPTIONS # endif #endif // !TEST_HAS_NO_EXCEPTIONS #if TEST_CUDA_COMPILER(NVCC) || TEST_COMPILER(NVRTC) || defined(TEST_COMPILER_HIPCC) || defined(TEST_COMPILER_HIPRTC) # define TEST_HAS_NO_EXCEPTIONS #endif #ifndef TEST_HAS_NO_EXCEPTIONS # define TEST_THROW(...) throw __VA_ARGS__ #else # define TEST_THROW(...) assert(#__VA_ARGS__) #endif #if _CCCL_HAS_FEATURE(address_sanitizer) || _CCCL_HAS_FEATURE(memory_sanitizer) || _CCCL_HAS_FEATURE(thread_sanitizer) # define TEST_HAS_SANITIZERS #endif #define TEST_IGNORE_NODISCARD (void) #if TEST_COMPILER(MSVC) # include template inline void DoNotOptimize(Tp const& value) { const volatile void* volatile unused = __builtin_addressof(value); static_cast(unused); _ReadWriteBarrier(); } #else // ^^^ TEST_COMPILER(MSVC) ^^^ / vvv !TEST_COMPILER(MSVC) vvv template __host__ __device__ inline void DoNotOptimize(Tp const& value) { asm volatile("" : : "r,m"(value) : "memory"); } template __host__ __device__ inline void DoNotOptimize(Tp& value) { # if TEST_COMPILER(CLANG) asm volatile("" : "+r,m"(value) : : "memory"); # else asm volatile("" : "+m,r"(value) : : "memory"); # endif } #endif // !TEST_COMPILER(MSVC) // NVCC can't handle static member variables, so with a little care // a function returning a reference will result in the same thing #ifdef __CUDA_ARCH__ # define _STATIC_MEMBER_IMPL(type) __shared__ type v; #else # define _STATIC_MEMBER_IMPL(type) static type v; #endif #define STATIC_MEMBER_VAR(name, type) \ __host__ __device__ static type& name() \ { \ _STATIC_MEMBER_IMPL(type); \ return v; \ } template __host__ __device__ constexpr bool unused(T&&...) { return true; } #ifdef __HIP_PLATFORM_AMD__ #if defined(__GFX9__) #if !defined(__gfx90a__) and !defined(__gfx906__) and !defined(__gfx908__) #define LIBHIPCXX_SUPPORTS_MANAGED_MEMORY_ATOMIC_FETCH #endif #endif #endif #endif // SUPPORT_TEST_MACROS_HPP