Skip to content

Commit 04a0a05

Browse files
committed
fix cudapp.cuh
1 parent 1fe985e commit 04a0a05

File tree

1 file changed

+97
-14
lines changed

1 file changed

+97
-14
lines changed

examples/moderncuda/cudapp.cuh

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
#pragma once
22

3+
#include "debug.hpp"
4+
#include <cuda_runtime.h>
5+
#include <version>
36
#include <cstddef>
47
#include <cstdio>
58
#include <cstdlib>
69
#include <cstdarg>
7-
#include <cuda_runtime.h>
810
#include <memory>
911
#include <new>
1012
#include <string>
1113
#include <system_error>
1214
#include <utility>
1315
#include <vector>
16+
#if __cpp_lib_source_location
17+
#include <source_location>
18+
#endif
19+
// #if __cpp_lib_memory_resource
20+
// #include <memory_resource>
21+
// #endif
1422

1523
namespace cudapp {
1624

17-
std::error_category const &cudaErrorCategory() noexcept {
25+
inline std::error_category const &cudaErrorCategory() noexcept {
1826
static struct : std::error_category {
1927
char const *name() const noexcept override {
2028
return "cuda";
@@ -28,15 +36,40 @@ std::error_category const &cudaErrorCategory() noexcept {
2836
return category;
2937
}
3038

31-
std::error_code makeCudaErrorCode(cudaError_t e) noexcept {
39+
inline std::error_code makeCudaErrorCode(cudaError_t e) noexcept {
3240
return std::error_code(static_cast<int>(e), cudaErrorCategory());
3341
}
3442

35-
void throwCudaError(cudaError_t err, char const *file, int line) {
43+
inline void throwCudaError(cudaError_t err, char const *file, int line) {
3644
throw std::system_error(makeCudaErrorCode(err),
37-
std::string(file) + ":" + std::to_string(line));
45+
std::string(file ? file : "??") + ":" + std::to_string(line));
3846
}
3947

48+
struct CheckCuda {
49+
const char *file = nullptr;
50+
int line = 0;
51+
52+
#if __cpp_lib_source_location
53+
constexpr CheckCuda(std::source_location const &loc = std::source_location::current())
54+
: file(loc.file_name()), line(loc.line())
55+
{}
56+
#else
57+
#if defined(__GNUC__) && defined(__has_builtin)
58+
#if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
59+
constexpr CheckCuda(const char *file = __builtin_FILE(), int line = __builtin_LINE())
60+
: file(file), line(line)
61+
{}
62+
#endif
63+
#endif
64+
#endif
65+
66+
void operator=(cudaError_t err) {
67+
if (err != cudaSuccess) [[unlikely]] {
68+
::cudapp::throwCudaError(err, file, line);
69+
}
70+
}
71+
};
72+
4073
#define CHECK_CUDA(expr) \
4174
do { \
4275
cudaError_t err = (expr); \
@@ -47,7 +80,7 @@ void throwCudaError(cudaError_t err, char const *file, int line) {
4780

4881
struct CudaHostArena {
4982
static cudaError_t doMalloc(void **ptr, size_t size) noexcept {
50-
return cudaMallocHost(&ptr, size);
83+
return cudaMallocHost(ptr, size);
5184
}
5285

5386
static cudaError_t doFree(void *ptr) noexcept {
@@ -57,7 +90,7 @@ struct CudaHostArena {
5790

5891
struct CudaDeviceArena {
5992
static cudaError_t doMalloc(void **ptr, size_t size) noexcept {
60-
return cudaMalloc(&ptr, size);
93+
return cudaMalloc(ptr, size);
6194
}
6295

6396
static cudaError_t doFree(void *ptr) noexcept {
@@ -67,7 +100,7 @@ struct CudaDeviceArena {
67100

68101
struct CudaManagedArena {
69102
static cudaError_t doMalloc(void **ptr, size_t size) noexcept {
70-
return cudaMallocManaged(&ptr, size);
103+
return cudaMallocManaged(ptr, size);
71104
}
72105

73106
static cudaError_t doFree(void *ptr) noexcept {
@@ -423,7 +456,7 @@ struct CudaAllocator : private Arena {
423456

424457
T *allocate(size_t size) {
425458
void *ptr = nullptr;
426-
if (sizeof(T) <= 1 || size > std::numeric_limits<size_t>::max() /
459+
if (sizeof(T) > 1 && size > std::numeric_limits<size_t>::max() /
427460
sizeof(T)) [[unlikely]] {
428461
throw std::bad_array_new_length();
429462
}
@@ -439,21 +472,41 @@ struct CudaAllocator : private Arena {
439472
CHECK_CUDA(Arena::doFree(ptr));
440473
}
441474

475+
#if __cpp_constexpr_dynamic_alloc && __cpp_if_constexpr
442476
template <class... Args>
443-
static constexpr std::enable_if_t<sizeof...(Args)>
477+
static std::enable_if_t<sizeof...(Args)>
444478
construct(T *p, Args &&...args) noexcept(noexcept(
445-
::new(static_cast<void *>(p)) T(std::forward<Args>(args)...))) {
479+
std::construct_at(p, std::forward<Args>(args)...))) {
480+
std::construct_at(p, std::forward<Args>(args)...);
481+
}
482+
483+
static void
484+
construct(T *p) noexcept(noexcept(std::construct_at(p))) {
485+
if constexpr (!std::is_trivial_v<T>) {
486+
std::construct_at(p);
487+
}
488+
}
489+
490+
static void destroy(T *p) noexcept(noexcept(std::destroy_at(p))) {
491+
std::destroy_at(p);
492+
}
493+
#else
494+
template <class... Args>
495+
static std::enable_if_t<sizeof...(Args)>
496+
construct(T *p, Args &&...args) noexcept(noexcept(
497+
::new (static_cast<void *>(p)) T(std::forward<Args>(args)...))) {
446498
::new (static_cast<void *>(p)) T(std::forward<Args>(args)...);
447499
}
448500

449-
static constexpr void
450-
construct(T *p) noexcept(noexcept(::new(static_cast<void *>(p)) T)) {
501+
static void
502+
construct(T *p) noexcept(noexcept(::new (static_cast<void *>(p)) T)) {
451503
::new (static_cast<void *>(p)) T;
452504
}
453505

454-
static constexpr void destroy(T *p) noexcept(noexcept(p->~T())) {
506+
static void destroy(T *p) noexcept(noexcept(p->~T())) {
455507
p->~T();
456508
}
509+
#endif
457510

458511
template <class U>
459512
constexpr CudaAllocator(CudaAllocator<U> const &other) noexcept {}
@@ -487,6 +540,36 @@ __host__ __device__ static void printf(const char *fmt, ...) {
487540
using ::printf;
488541
#endif
489542

543+
template <class Vector>
544+
struct CudaVectorResizer {
545+
private:
546+
Vector &m_vec;
547+
size_t m_size;
548+
549+
public:
550+
explicit CudaVectorResizer(Vector &vec) noexcept
551+
: m_vec(vec), m_size(vec.size()) {}
552+
553+
CudaVectorResizer &operator=(CudaVectorResizer &&) = delete;
554+
555+
operator size_t &() noexcept {
556+
return m_size;
557+
}
558+
559+
operator size_t *() noexcept {
560+
return &m_size;
561+
}
562+
563+
~CudaVectorResizer() noexcept(noexcept(m_vec.resize(m_size))) {
564+
m_vec.resize(m_size);
565+
}
566+
};
567+
568+
#if __cpp_deduction_guides
569+
template <class Vector>
570+
CudaVectorResizer(Vector &vec) -> CudaVectorResizer<Vector>;
571+
#endif
572+
490573
// #if __cpp_lib_memory_resource
491574
// template <class Arena>
492575
// struct CudaResource : std::pmr::memory_resource, private Arena {

0 commit comments

Comments
 (0)