Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that cuda::__throw_cuda_error works even on non CUDA compilers #3369

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
22 changes: 8 additions & 14 deletions libcudacxx/include/cuda/std/__exception/cuda_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
# pragma system_header
#endif // no system header

#if _CCCL_CUDA_COMPILER(CLANG)
# include <cuda_runtime_api.h>
#endif // _CCCL_CUDA_COMPILER(CLANG)

#include <cuda/std/__exception/terminate.h>

#if !_CCCL_COMPILER(NVRTC)
Expand All @@ -40,8 +36,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:
Expand All @@ -50,37 +45,36 @@ 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);),
((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:
_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();
}
# endif // _CCCL_NO_EXCEPTIONS
#endif // _CCCL_CUDA_COMPILER
#endif // _CCCL_NO_EXCEPTIONS

_LIBCUDACXX_END_NAMESPACE_CUDA

Expand Down
5 changes: 2 additions & 3 deletions libcudacxx/include/cuda/stream_ref
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ private:
} // cuda
*/

#include <cuda_runtime_api.h>
// cuda_runtime_api needs to come first

#include <cuda/std/detail/__config>

#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
Expand All @@ -51,6 +48,8 @@ private:
# pragma system_header
#endif // no system header

#include <cuda_runtime_api.h>

#include <cuda/std/__cuda/api_wrapper.h>
#include <cuda/std/__exception/cuda_error.h>
#include <cuda/std/cstddef>
Expand Down
18 changes: 18 additions & 0 deletions libcudacxx/test/public_headers_host_only/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand All @@ -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()

Expand Down
Loading