From 15fe5e06e5670ec477554a53dc7f2a3f4f7b8e80 Mon Sep 17 00:00:00 2001 From: Cedric Augonnet Date: Mon, 13 Jan 2025 16:59:04 +0100 Subject: [PATCH 1/6] Ensure that cuda::__throw_cuda_error works even on non CUDA compilers --- libcudacxx/include/cuda/std/__exception/cuda_error.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libcudacxx/include/cuda/std/__exception/cuda_error.h b/libcudacxx/include/cuda/std/__exception/cuda_error.h index 40af7d6c3e6..0a452ca10b0 100644 --- a/libcudacxx/include/cuda/std/__exception/cuda_error.h +++ b/libcudacxx/include/cuda/std/__exception/cuda_error.h @@ -40,8 +40,7 @@ _LIBCUDACXX_BEGIN_NAMESPACE_CUDA /** * @brief Exception thrown when a CUDA error is encountered. */ -#if _CCCL_HAS_CUDA_COMPILER -# ifndef _CCCL_NO_EXCEPTIONS +#ifndef _CCCL_NO_EXCEPTIONS class cuda_error : public ::std::runtime_error { private: @@ -64,11 +63,15 @@ class cuda_error : public ::std::runtime_error _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t __status, const char* __msg) { +# if _CCCL_HAS_CUDA_COMPILER NV_IF_ELSE_TARGET(NV_IS_HOST, (throw ::cuda::cuda_error(__status, __msg);), ((void) __status; (void) __msg; _CUDA_VSTD_NOVERSION::terminate();)) +# else + throw ::cuda::cuda_error(__status, __msg); +# endif // _CCCL_CUDA_COMPILER } -# else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv +#else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv class cuda_error { public: @@ -79,8 +82,7 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t, { _CUDA_VSTD_NOVERSION::terminate(); } -# endif // _CCCL_NO_EXCEPTIONS -#endif // _CCCL_CUDA_COMPILER +#endif // _CCCL_NO_EXCEPTIONS _LIBCUDACXX_END_NAMESPACE_CUDA From a3bd0de482608b5b2f2a7ece3e87e5927c8055d8 Mon Sep 17 00:00:00 2001 From: Cedric Augonnet Date: Mon, 13 Jan 2025 19:53:04 +0100 Subject: [PATCH 2/6] Revert "Ensure that cuda::__throw_cuda_error works even on non CUDA compilers" This reverts commit 15fe5e06e5670ec477554a53dc7f2a3f4f7b8e80. --- libcudacxx/include/cuda/std/__exception/cuda_error.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libcudacxx/include/cuda/std/__exception/cuda_error.h b/libcudacxx/include/cuda/std/__exception/cuda_error.h index 0a452ca10b0..40af7d6c3e6 100644 --- a/libcudacxx/include/cuda/std/__exception/cuda_error.h +++ b/libcudacxx/include/cuda/std/__exception/cuda_error.h @@ -40,7 +40,8 @@ _LIBCUDACXX_BEGIN_NAMESPACE_CUDA /** * @brief Exception thrown when a CUDA error is encountered. */ -#ifndef _CCCL_NO_EXCEPTIONS +#if _CCCL_HAS_CUDA_COMPILER +# ifndef _CCCL_NO_EXCEPTIONS class cuda_error : public ::std::runtime_error { private: @@ -63,15 +64,11 @@ class cuda_error : public ::std::runtime_error _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t __status, const char* __msg) { -# if _CCCL_HAS_CUDA_COMPILER NV_IF_ELSE_TARGET(NV_IS_HOST, (throw ::cuda::cuda_error(__status, __msg);), ((void) __status; (void) __msg; _CUDA_VSTD_NOVERSION::terminate();)) -# else - throw ::cuda::cuda_error(__status, __msg); -# endif // _CCCL_CUDA_COMPILER } -#else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv +# else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv class cuda_error { public: @@ -82,7 +79,8 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t, { _CUDA_VSTD_NOVERSION::terminate(); } -#endif // _CCCL_NO_EXCEPTIONS +# endif // _CCCL_NO_EXCEPTIONS +#endif // _CCCL_CUDA_COMPILER _LIBCUDACXX_END_NAMESPACE_CUDA From 98823feaebda567314805cb4361da80b65952430 Mon Sep 17 00:00:00 2001 From: Cedric Augonnet Date: Mon, 13 Jan 2025 19:59:33 +0100 Subject: [PATCH 3/6] Simple __throw_cuda_error which ignores its first argument but does not require defining the cudaError_t type to ignore it --- libcudacxx/include/cuda/std/__exception/cuda_error.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libcudacxx/include/cuda/std/__exception/cuda_error.h b/libcudacxx/include/cuda/std/__exception/cuda_error.h index 40af7d6c3e6..a1a970e620a 100644 --- a/libcudacxx/include/cuda/std/__exception/cuda_error.h +++ b/libcudacxx/include/cuda/std/__exception/cuda_error.h @@ -80,6 +80,16 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t, _CUDA_VSTD_NOVERSION::terminate(); } # endif // _CCCL_NO_EXCEPTIONS +#else +template +_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(dummy_t, [[maybe_unused]] const char* __msg) +{ +#ifndef _CCCL_NO_EXCEPTIONS + throw ::std::runtime_error(__msg); +#else + ::std::terminate(); +#endif +} #endif // _CCCL_CUDA_COMPILER _LIBCUDACXX_END_NAMESPACE_CUDA From 06a54a0cf764fab6cc059435e8f0a3825bb51e81 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 14 Jan 2025 09:24:14 +0100 Subject: [PATCH 4/6] Alway include cuda_runtime_api with stream_ref `cuda::stream_ref` does not work without at least including cuda_runtime_api.h We previously guarded this by using a cuda compiler but it should be possible to use this with just a c++ compiler. This makes it so and also adds stream_ref to the host compiler tests. The one caveat is that we need to ensure that we properly provide the cuda include path so the compiler finds cuda_runtime_api.h --- .../include/cuda/std/__exception/cuda_error.h | 22 ++++--------------- libcudacxx/include/cuda/stream_ref | 5 ++--- .../public_headers_host_only/CMakeLists.txt | 18 +++++++++++++++ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/libcudacxx/include/cuda/std/__exception/cuda_error.h b/libcudacxx/include/cuda/std/__exception/cuda_error.h index a1a970e620a..76a5b7b3353 100644 --- a/libcudacxx/include/cuda/std/__exception/cuda_error.h +++ b/libcudacxx/include/cuda/std/__exception/cuda_error.h @@ -22,9 +22,7 @@ # pragma system_header #endif // no system header -#if _CCCL_CUDA_COMPILER(CLANG) -# include -#endif // _CCCL_CUDA_COMPILER(CLANG) +#include #include @@ -40,8 +38,7 @@ _LIBCUDACXX_BEGIN_NAMESPACE_CUDA /** * @brief Exception thrown when a CUDA error is encountered. */ -#if _CCCL_HAS_CUDA_COMPILER -# ifndef _CCCL_NO_EXCEPTIONS +#ifndef _CCCL_NO_EXCEPTIONS class cuda_error : public ::std::runtime_error { private: @@ -68,7 +65,7 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t _ (throw ::cuda::cuda_error(__status, __msg);), ((void) __status; (void) __msg; _CUDA_VSTD_NOVERSION::terminate();)) } -# else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv +#else // ^^^ !_CCCL_NO_EXCEPTIONS ^^^ / vvv _CCCL_NO_EXCEPTIONS vvv class cuda_error { public: @@ -79,18 +76,7 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t, { _CUDA_VSTD_NOVERSION::terminate(); } -# endif // _CCCL_NO_EXCEPTIONS -#else -template -_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(dummy_t, [[maybe_unused]] const char* __msg) -{ -#ifndef _CCCL_NO_EXCEPTIONS - throw ::std::runtime_error(__msg); -#else - ::std::terminate(); -#endif -} -#endif // _CCCL_CUDA_COMPILER +#endif // _CCCL_NO_EXCEPTIONS _LIBCUDACXX_END_NAMESPACE_CUDA diff --git a/libcudacxx/include/cuda/stream_ref b/libcudacxx/include/cuda/stream_ref index a8b044909eb..857a35f6da4 100644 --- a/libcudacxx/include/cuda/stream_ref +++ b/libcudacxx/include/cuda/stream_ref @@ -38,9 +38,6 @@ private: } // cuda */ -#include -// cuda_runtime_api needs to come first - #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) @@ -51,6 +48,8 @@ private: # pragma system_header #endif // no system header +#include + #include #include #include diff --git a/libcudacxx/test/public_headers_host_only/CMakeLists.txt b/libcudacxx/test/public_headers_host_only/CMakeLists.txt index 57b6c70ede9..641d218b9d9 100644 --- a/libcudacxx/test/public_headers_host_only/CMakeLists.txt +++ b/libcudacxx/test/public_headers_host_only/CMakeLists.txt @@ -2,6 +2,12 @@ # without anything else but also pretents to be a std header add_custom_target(libcudacxx.test.public_headers_host_only) +if ("NVHPC" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + find_package(NVHPC) +else() + find_package(CUDAToolkit) +endif() + # Grep all public headers file(GLOB public_headers_host_only LIST_DIRECTORIES false @@ -10,6 +16,9 @@ file(GLOB public_headers_host_only "${libcudacxx_SOURCE_DIR}/include/cuda/std/*" ) +# We also want to test cuda/stream_ref with the host compiler only +list(APPEND public_headers_host_only "${libcudacxx_SOURCE_DIR}/include/cuda/stream_ref") + # mdspan is currently not supported on msvc outside of C++20 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" AND NOT "${CMAKE_CXX_STANDARD}" MATCHES "20") list(FILTER public_headers_host_only EXCLUDE REGEX "mdspan") @@ -34,6 +43,15 @@ function(libcudacxx_add_std_header_test header) endif() target_compile_definitions(headertest_std_${header_name} PRIVATE CCCL_IGNORE_DEPRECATED_CPP_DIALECT) + # We want to ensure that we can build stream_ref with a host compiler but we need cuda_runtime_api + if (${header_name} MATCHES "stream_ref") + if ("NVHPC" STREQUAL "${CMAKE_CXX_COMPILER_ID}") + target_link_libraries(headertest_std_${header_name} NVHPC::CUDART) + else() + target_link_libraries(headertest_std_${header_name} CUDA::cudart) + endif() + endif() + add_dependencies(libcudacxx.test.public_headers_host_only headertest_std_${header_name}) endfunction() From cb1346ddd5e9e93891c77c766947153d931a561f Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 14 Jan 2025 09:57:03 +0100 Subject: [PATCH 5/6] Make `__cuda/api_wrapper.h` safe to include from host TU --- libcudacxx/include/cuda/std/__cuda/api_wrapper.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libcudacxx/include/cuda/std/__cuda/api_wrapper.h b/libcudacxx/include/cuda/std/__cuda/api_wrapper.h index 61dc291b1ce..d6d6a9d256b 100644 --- a/libcudacxx/include/cuda/std/__cuda/api_wrapper.h +++ b/libcudacxx/include/cuda/std/__cuda/api_wrapper.h @@ -21,13 +21,11 @@ # pragma system_header #endif // no system header -#if _CCCL_CUDA_COMPILER(CLANG) +#if _CCCL_HAS_CUDA_COMPILER # include -#endif // _CCCL_CUDA_COMPILER(CLANG) -#include +# include -#if _CCCL_HAS_CUDA_COMPILER # define _CCCL_TRY_CUDA_API(_NAME, _MSG, ...) \ { \ const ::cudaError_t __status = _NAME(__VA_ARGS__); \ From d440fb457a95d815491ba78a510839c5d0ec0255 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Tue, 14 Jan 2025 10:08:18 +0100 Subject: [PATCH 6/6] Try to just use int for cuda_error --- libcudacxx/include/cuda/std/__cuda/api_wrapper.h | 6 ++++-- libcudacxx/include/cuda/std/__exception/cuda_error.h | 12 +++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libcudacxx/include/cuda/std/__cuda/api_wrapper.h b/libcudacxx/include/cuda/std/__cuda/api_wrapper.h index d6d6a9d256b..61dc291b1ce 100644 --- a/libcudacxx/include/cuda/std/__cuda/api_wrapper.h +++ b/libcudacxx/include/cuda/std/__cuda/api_wrapper.h @@ -21,11 +21,13 @@ # pragma system_header #endif // no system header -#if _CCCL_HAS_CUDA_COMPILER +#if _CCCL_CUDA_COMPILER(CLANG) # include +#endif // _CCCL_CUDA_COMPILER(CLANG) -# include +#include +#if _CCCL_HAS_CUDA_COMPILER # define _CCCL_TRY_CUDA_API(_NAME, _MSG, ...) \ { \ const ::cudaError_t __status = _NAME(__VA_ARGS__); \ diff --git a/libcudacxx/include/cuda/std/__exception/cuda_error.h b/libcudacxx/include/cuda/std/__exception/cuda_error.h index 76a5b7b3353..fdc32cf0571 100644 --- a/libcudacxx/include/cuda/std/__exception/cuda_error.h +++ b/libcudacxx/include/cuda/std/__exception/cuda_error.h @@ -22,8 +22,6 @@ # pragma system_header #endif // no system header -#include - #include #if !_CCCL_COMPILER(NVRTC) @@ -47,19 +45,19 @@ class cuda_error : public ::std::runtime_error char __buffer[256]; }; - static char* __format_cuda_error(::cudaError_t __status, const char* __msg, char* __msg_buffer) noexcept + static char* __format_cuda_error(const int __status, const char* __msg, char* __msg_buffer) noexcept { ::snprintf(__msg_buffer, 256, "cudaError %d: %s", __status, __msg); return __msg_buffer; } public: - cuda_error(::cudaError_t __status, const char* __msg, __msg_storage __msg_buffer = {0}) noexcept + cuda_error(const int __status, const char* __msg, __msg_storage __msg_buffer = {0}) noexcept : ::std::runtime_error(__format_cuda_error(__status, __msg, __msg_buffer.__buffer)) {} }; -_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t __status, const char* __msg) +_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(const int __status, const char* __msg) { NV_IF_ELSE_TARGET(NV_IS_HOST, (throw ::cuda::cuda_error(__status, __msg);), @@ -69,10 +67,10 @@ _CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t _ class cuda_error { public: - _LIBCUDACXX_HIDE_FROM_ABI cuda_error(::cudaError_t, const char*) noexcept {} + _LIBCUDACXX_HIDE_FROM_ABI cuda_error(const int, const char*) noexcept {} }; -_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(::cudaError_t, const char*) +_CCCL_NORETURN _LIBCUDACXX_HIDE_FROM_ABI void __throw_cuda_error(const int, const char*) { _CUDA_VSTD_NOVERSION::terminate(); }