lamppp
Loading...
Searching...
No Matches
assert.hpp
1#pragma once
2
3#include <cassert>
4#include <iostream>
5#include <stdexcept>
6#include <sstream>
7
8#ifdef ENABLE_CUDA
9#include <cuda_runtime.h>
10#endif
11
12namespace lmp {
13namespace detail {
14
15template<typename Derived>
17 BaseStream() = default;
18public:
19 template<class T>
20 Derived& operator<<(T&& v) {
21 os_ << std::forward<T>(v);
22 return static_cast<Derived&>(*this);
23 }
24protected:
25 std::ostringstream os_;
26friend Derived;
27};
28
29class CheckStream : public BaseStream<CheckStream> {
30public:
31 CheckStream(const char* file, int line, const char* func, const char* expr) {
32 os_ << "Lamppp: Runtime error thrown at " << file << ':' << line
33 << " in " << func << ". CHECK(" << expr << ") failed: ";
34 }
35
36 [[noreturn]] void trigger() const {
37 std::cerr << os_.str() << std::endl;
38 throw std::runtime_error(os_.str());
39 }
40};
41
42#ifdef LMP_DEBUG
43
44class AssertStream : public BaseStream<AssertStream> {
45public:
46 AssertStream(const char* file, int line, const char* func, const char* expr) {
47 os_ << "Lamppp: Internal assertion failure at " << file << ':' << line
48 << " in " << func << ". ASSERT(" << expr << ") failed: ";
49 }
50
51 [[noreturn]] void trigger() const {
52 std::cerr << os_.str() << std::endl;
53 std::terminate();
54 }
55};
56
57#ifdef ENABLE_CUDA
58class CudaAssertStream : public BaseStream<CudaAssertStream> {
59public:
60 CudaAssertStream(const char* file, int line, const char* func, cudaError_t err) {
61 os_ << "Lamppp: CUDA error at " << file << ':' << line
62 << " in " << func << ". Error: " << cudaGetErrorString(err) << ". ";
63 }
64
65 [[noreturn]] void trigger() const {
66 std::cerr << os_.str() << std::endl;
67 std::terminate();
68 }
69};
70#endif
71
72#endif
73
74struct Voidify {
75 template<class T>
76 void operator&(T&& stream) const {
77 stream.trigger();
78 }
79};
80
81} // namespace detail
82} // namespace lmp
83
84#define LMP_CHECK(cond) \
85 (cond) ? (void)0 : ::lmp::detail::Voidify() & ::lmp::detail::CheckStream(__FILE__, __LINE__, __func__, #cond)
86
87#ifdef LMP_DEBUG
88
89#define LMP_INTERNAL_ASSERT(cond) \
90 (cond) ? (void)0 : ::lmp::detail::Voidify() & ::lmp::detail::AssertStream(__FILE__, __LINE__, __func__, #cond)
91
92
93#ifdef ENABLE_CUDA
94
95namespace lmp::detail {
96
97inline cudaError_t& cuda_assert_last_error() {
98 static thread_local cudaError_t last{};
99 return last;
100}
101
102template<class F>
103inline bool cuda_assert_once(F&& f) {
104 cuda_assert_last_error() = f();
105 return cuda_assert_last_error() != cudaSuccess;
106}
107
108}
109
110#define LMP_CUDA_INTERNAL_ASSERT(call) \
111 if (const cudaError_t LMP_CUDA_ERROR = (call); LMP_CUDA_ERROR == cudaSuccess) \
112 ; \
113 else \
114 ::lmp::detail::Voidify() & \
115 ::lmp::detail::CudaAssertStream(__FILE__, __LINE__, __func__, \
116 LMP_CUDA_ERROR)
117
118#define LMP_CUDA_CHECK(call) \
119 if (const cudaError_t LMP_CUDA_ERROR = (call); LMP_CUDA_ERROR == cudaSuccess) \
120 ; \
121 else \
122 ::lmp::detail::Voidify() & \
123 ::lmp::detail::CudaAssertStream(__FILE__, __LINE__, __func__, \
124 LMP_CUDA_ERROR)
125#endif
126
127
128#define LMP_PRINT(fmt, ...) \
129 fprintf(stderr, "[%s:%d] %s: " fmt "\n", __FILE__, __LINE__, __func__, \
130 ##__VA_ARGS__)
131
132#else
133
134namespace lmp::detail {
136 template<typename T> NullStream& operator<<(T&&) { return *this; }
137 void trigger() const {}
138};
139
140}
141#define LMP_INTERNAL_ASSERT(cond) \
142 true ? (void)0 : ::lmp::detail::Voidify() & ::lmp::detail::NullStream()
143#define LMP_CUDA_INTERNAL_ASSERT(call) \
144 true ? (void)0 : ::lmp::detail::Voidify() & ::lmp::detail::NullStream()
145#define LMP_CUDA_CHECK(call) \
146 (call) ? (void)0 : ::lmp::detail::Voidify() & ::lmp::detail::NullStream()
147
148#endif
Definition assert.hpp:16
Definition assert.hpp:29
Definition assert.hpp:135
Definition assert.hpp:74