File indexing completed on 2026-04-17 08:35:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef VECGEOM_BASE_ASSERT_H_
0017 #define VECGEOM_BASE_ASSERT_H_
0018
0019 #include "VecGeom/base/Config.h"
0020 #include "VecGeom/base/Global.h"
0021
0022 #ifndef __CUDA_ARCH__
0023 #include <stdexcept>
0024 #include <sstream>
0025 #else
0026 #include <cassert>
0027 #endif
0028
0029
0030 #ifdef NDEBUG
0031 #define VECGEOM_DEBUG 0
0032 #define VECGEOM_DEVICE_DEBUG 0
0033 #else
0034 #define VECGEOM_DEBUG 1
0035 #define VECGEOM_DEVICE_DEBUG 1
0036 #endif
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #if defined(VECGEOM_ENABLE_CUDA)
0049 #define VECGEOM_DEVICE_PLATFORM cuda
0050 #define VECGEOM_DEVICE_PLATFORM_UPPER_STR "CUDA"
0051 #define VECGEOM_DEVICE_API_SYMBOL(TOK) cuda##TOK
0052 #elif defined(VECGEOM_ENABLE_HIP)
0053
0054 #define VECGEOM_DEVICE_PLATFORM hip
0055 #define VECGEOM_DEVICE_PLATFORM_UPPER_STR "HIP"
0056 #define VECGEOM_DEVICE_API_SYMBOL(TOK) hip##TOK
0057 #else
0058 #define VECGEOM_DEVICE_PLATFORM none
0059 #define VECGEOM_DEVICE_PLATFORM_UPPER_STR ""
0060 #define VECGEOM_DEVICE_API_SYMBOL(TOK) void
0061 #endif
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 #if defined(__CUDACC__) || defined(__HIP__)
0076 #define VECGEOM_DEVICE_SOURCE 1
0077 #elif defined(__DOXYGEN__)
0078 #define VECGEOM_DEVICE_SOURCE 0
0079 #endif
0080
0081 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
0082 #define VECGEOM_DEVICE_COMPILE 1
0083 #elif defined(__DOXYGEN__)
0084 #define VECGEOM_DEVICE_COMPILE 0
0085 #endif
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 #if defined(__clang__) || defined(__GNUC__)
0097
0098 #define VECGEOM_UNLIKELY(COND) __builtin_expect(!!(COND), 0)
0099 #else
0100
0101 #define VECGEOM_UNLIKELY(COND) (COND)
0102 #endif
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 #if !defined(__HIP__) && !defined(__CUDA_ARCH__)
0153
0154 #define VECGEOM_DEBUG_THROW_(MSG, WHICH) throw ::vecgeom::make_debug_error(#WHICH, MSG, __FILE__, __LINE__)
0155 #elif defined(__CUDA_ARCH__) && !defined(NDEBUG)
0156
0157 #define VECGEOM_DEBUG_THROW_(MSG, WHICH) assert(false && sizeof(#WHICH ": " MSG))
0158 #else
0159
0160
0161
0162 #define VECGEOM_DEBUG_THROW_(MSG, WHICH) ::vecgeom::device_debug_error(#WHICH, MSG, __FILE__, __LINE__)
0163 #endif
0164
0165 #define VECGEOM_DEBUG_FAIL(MSG, WHICH) \
0166 do { \
0167 VECGEOM_DEBUG_THROW_(MSG, WHICH); \
0168 ::vecgeom::unreachable(); \
0169 } while (0)
0170 #define VECGEOM_DEBUG_ASSERT_(COND, WHICH) \
0171 do { \
0172 if (VECGEOM_UNLIKELY(!(COND))) { \
0173 VECGEOM_DEBUG_THROW_(#COND, WHICH); \
0174 } \
0175 } while (0)
0176 #define VECGEOM_NOASSERT_(COND) \
0177 do { \
0178 if (false && (COND)) { \
0179 } \
0180 } while (0)
0181
0182 #if (VECGEOM_DEBUG && !VECGEOM_DEVICE_COMPILE) || (VECGEOM_DEVICE_DEBUG && VECGEOM_DEVICE_COMPILE)
0183 #define VECGEOM_ASSERT(COND) VECGEOM_DEBUG_ASSERT_(COND, internal)
0184 #define VECGEOM_ASSERT_UNREACHABLE() VECGEOM_DEBUG_FAIL("unreachable code point encountered", unreachable)
0185 #else
0186 #define VECGEOM_ASSERT(COND) VECGEOM_NOASSERT_(COND)
0187 #define VECGEOM_ASSERT_UNREACHABLE() ::vecgeom::unreachable()
0188 #endif
0189
0190 #if !VECGEOM_DEVICE_COMPILE
0191 #define VECGEOM_RUNTIME_THROW(WHICH, WHAT, COND) \
0192 throw ::vecgeom::make_runtime_error(WHICH, WHAT, COND, __FILE__, __LINE__)
0193 #else
0194 #define VECGEOM_RUNTIME_THROW(WHICH, WHAT, COND) \
0195 VECGEOM_DEBUG_FAIL("Runtime errors cannot be thrown from device code", unreachable);
0196 #endif
0197
0198 #if !VECGEOM_DEVICE_COMPILE
0199 #define VECGEOM_VALIDATE(COND, MSG) \
0200 do { \
0201 if (VECGEOM_UNLIKELY(!(COND))) { \
0202 std::ostringstream vg_runtime_msg_; \
0203 vg_runtime_msg_ MSG; \
0204 VECGEOM_RUNTIME_THROW("runtime", vg_runtime_msg_.str().c_str(), #COND); \
0205 } \
0206 } while (0)
0207 #else
0208 #define VECGEOM_VALIDATE(COND, MSG) \
0209 do { \
0210 if (VECGEOM_UNLIKELY(!(COND))) { \
0211 VECGEOM_RUNTIME_THROW("runtime", (::vecgeom::detail::StreamlikeIdentity {} MSG), #COND); \
0212 } \
0213 } while (0)
0214 #endif
0215
0216 #define VECGEOM_NOT_CONFIGURED(WHAT) VECGEOM_RUNTIME_THROW("not configured", WHAT, nullptr)
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 #if defined(VECGEOM_ENABLE_CUDA) || defined(VECGEOM_ENABLE_HIP)
0236 #define VECGEOM_DEVICE_API_CALL(STMT) \
0237 do { \
0238 using ErrT_ = VECGEOM_DEVICE_API_SYMBOL(Error_t); \
0239 ErrT_ result_ = VECGEOM_DEVICE_API_SYMBOL(STMT); \
0240 if (VECGEOM_UNLIKELY(result_ != VECGEOM_DEVICE_API_SYMBOL(Success))) { \
0241 result_ = VECGEOM_DEVICE_API_SYMBOL(GetLastError)(); \
0242 VECGEOM_RUNTIME_THROW(VECGEOM_DEVICE_PLATFORM_UPPER_STR, VECGEOM_DEVICE_API_SYMBOL(GetErrorString)(result_), \
0243 #STMT); \
0244 } \
0245 } while (0)
0246 #else
0247 #define VECGEOM_DEVICE_API_CALL(STMT) \
0248 do { \
0249 VECGEOM_NOT_CONFIGURED("CUDA or HIP"); \
0250 } while (0)
0251 #endif
0252
0253 namespace vecgeom {
0254
0255
0256
0257
0258 #ifndef __CUDA_ARCH__
0259 [[nodiscard]] std::logic_error make_debug_error(char const *which, char const *condition, char const *file, int line);
0260
0261 [[nodiscard]] std::runtime_error make_runtime_error(char const *which, char const *what, char const *condition,
0262 char const *file, int line);
0263 #endif
0264
0265
0266
0267
0268
0269
0270 [[noreturn]] inline VECCORE_ATT_HOST_DEVICE void unreachable()
0271 {
0272 #if (!defined(__CUDA_ARCH__) && (defined(__clang__) || defined(__GNUC__))) || defined(__NVCOMPILER) || \
0273 (defined(__CUDA_ARCH__) && CUDART_VERSION >= 11030) || defined(__HIP_DEVICE_COMPILE__)
0274 __builtin_unreachable();
0275 #elif defined(_MSC_VER)
0276 __assume(false);
0277 #else
0278 VECGEOM_UNREACHABLE;
0279 #endif
0280 }
0281
0282 #if defined(__CUDA_ARCH__) && defined(NDEBUG)
0283
0284 inline __attribute__((noinline)) __host__ __device__ void device_debug_error(char const *, char const *condition,
0285 char const *file, int line)
0286 {
0287 printf("%s:%u:\nvecgeom: internal assertion failed: %s\n", file, line, condition);
0288 __trap();
0289 }
0290 #elif defined(__HIP__)
0291
0292 inline __host__ void device_debug_error(char const *which, char const *condition, char const *file, int line)
0293 {
0294 throw make_debug_error(which, condition, file, line);
0295 }
0296
0297
0298
0299 inline __attribute__((noinline)) __device__ void device_debug_error(char const *, char const *condition,
0300 char const *file, int line)
0301 {
0302 printf("%s:%u:\nvecgeom: internal assertion failed: %s\n", file, line, condition);
0303 abort();
0304 }
0305 #endif
0306
0307 namespace detail {
0308
0309 struct StreamlikeIdentity {
0310 VECCORE_ATT_HOST_DEVICE operator char const *() const { return ""; }
0311 };
0312 inline VECCORE_ATT_HOST_DEVICE char const *operator<<(StreamlikeIdentity const &, char const *s) { return s; }
0313 }
0314
0315 }
0316
0317 #endif