Cytnx v1.0.0
Loading...
Searching...
No Matches
cytnx_error.hpp
Go to the documentation of this file.
1#ifndef CYTNX_CYTNX_ERROR_H_
2#define CYTNX_CYTNX_ERROR_H_
3
4#include <cstdio>
5#include <cstdlib>
6#include <cstring>
7#include <stdarg.h>
8
9#include <iostream>
10#include <stdexcept>
11#include <string>
12
13#if defined(__has_include)
14 #if __has_include(<execinfo.h>)
15 #include <execinfo.h>
16 #define CYTNX_HAS_EXECINFO 1
17 #endif
18#endif
19
20#ifndef CYTNX_HAS_EXECINFO
21 #define CYTNX_HAS_EXECINFO 0
22#endif
23
24// Full function signature for error reports.
25#if defined(_MSC_VER)
26 #define CYTNX_FUNC_NAME __FUNCSIG__
27#else
28 #define CYTNX_FUNC_NAME __PRETTY_FUNCTION__
29#endif
30
31namespace cytnx {
32
33 extern bool User_debug; // defined in src/Type.cpp
34
35 // Exception thrown by cytnx_error_msg. Derives std::logic_error for
36 // backward compatibility with existing catch/EXPECT_THROW sites.
37 class error : public std::logic_error {
38 public:
39 using std::logic_error::logic_error;
40 };
41
42 namespace internal {
43
44 inline std::string vformat_message(char const *format, va_list args) {
45 if (format == nullptr) return std::string();
46 va_list args_copy;
47 va_copy(args_copy, args);
48 const int n = std::vsnprintf(nullptr, 0, format, args_copy);
49 va_end(args_copy);
50 if (n < 0) return std::string(format);
51 std::string msg(static_cast<std::size_t>(n), '\0');
52 std::vsnprintf(msg.data(), msg.size() + 1, format, args);
53 return msg;
54 }
55
56 inline std::string compose_report(char const *kind, char const *func, char const *file,
57 int line, const std::string &msg) {
58 std::string out;
59 out.reserve(msg.size() + 256);
60 // kind/func/file come from macro literals / CYTNX_FUNC_NAME / __FILE__ (or
61 // std::source_location), so they are non-null in practice; fall back defensively so a
62 // misuse can never turn report composition itself into undefined behavior.
63 out += "\n# Cytnx ";
64 out += kind ? kind : "error";
65 out += " occur at ";
66 out += func ? func : "unknown";
67 out += "\n# ";
68 out += kind ? kind : "error";
69 out += ": ";
70 out += msg;
71 out += "\n# file : ";
72 out += file ? file : "unknown";
73 out += " (";
74 out += std::to_string(line);
75 out += ")";
76 return out;
77 }
78
80 if (!cytnx::User_debug) return;
81#if CYTNX_HAS_EXECINFO
82 std::cerr << "Stack trace:" << std::endl;
83 void *array[10];
84 const int size = backtrace(array, 10);
85 char **strings = backtrace_symbols(array, size);
86 if (strings != nullptr) {
87 for (int i = 0; i < size; i++) std::cerr << strings[i] << std::endl;
88 free(strings);
89 }
90#else
91 std::cerr << "Stack trace is unavailable on this platform/compiler." << std::endl;
92#endif
93 }
94
95 [[noreturn]] inline void error_msg_impl(char const *func, char const *file, int line,
96 char const *format, ...) {
97 va_list args;
98 va_start(args, format);
99 const std::string msg = vformat_message(format, args);
100 va_end(args);
101 const std::string report = compose_report("error", func, file, line, msg);
103 throw cytnx::error(report);
104 }
105
106 inline void warning_msg_impl(char const *func, char const *file, int line, char const *format,
107 ...) {
108 va_list args;
109 va_start(args, format);
110 const std::string msg = vformat_message(format, args);
111 va_end(args);
112 std::cerr << compose_report("warning", func, file, line, msg) << std::endl;
113 }
114
115 } // namespace internal
116} // namespace cytnx
117
118#define cytnx_error_msg(is_true, format, ...) \
119 do { \
120 if (is_true) \
121 ::cytnx::internal::error_msg_impl(CYTNX_FUNC_NAME, __FILE__, __LINE__, \
122 (format)__VA_OPT__(, ) __VA_ARGS__); \
123 } while (0)
124
125#define cytnx_warning_msg(is_true, format, ...) \
126 do { \
127 if (is_true) \
128 ::cytnx::internal::warning_msg_impl(CYTNX_FUNC_NAME, __FILE__, __LINE__, \
129 (format)__VA_OPT__(, ) __VA_ARGS__); \
130 } while (0)
131
132#if defined(UNI_GPU)
133
134 #include <cuda.h>
135 #include <cuda_runtime.h>
136 #include <cublas_v2.h>
137 #include <cusolverDn.h>
138 #include <cuComplex.h>
139 #include <curand.h>
140
141 #if defined(UNI_CUTENSOR)
142 #include <cutensor.h>
143 #endif
144
145 #ifdef __DRIVER_TYPES_H__
146static const char *_cudaGetErrorEnum(cudaError_t error) {
147 switch (error) {
148 case cudaSuccess:
149 return "cudaSuccess";
150
151 case cudaErrorMissingConfiguration:
152 return "cudaErrorMissingConfiguration";
153
154 case cudaErrorMemoryAllocation:
155 return "cudaErrorMemoryAllocation";
156
157 case cudaErrorInitializationError:
158 return "cudaErrorInitializationError";
159
160 case cudaErrorLaunchFailure:
161 return "cudaErrorLaunchFailure";
162
163 case cudaErrorPriorLaunchFailure:
164 return "cudaErrorPriorLaunchFailure";
165
166 case cudaErrorLaunchTimeout:
167 return "cudaErrorLaunchTimeout";
168
169 case cudaErrorLaunchOutOfResources:
170 return "cudaErrorLaunchOutOfResources";
171
172 case cudaErrorInvalidDeviceFunction:
173 return "cudaErrorInvalidDeviceFunction";
174
175 case cudaErrorInvalidConfiguration:
176 return "cudaErrorInvalidConfiguration";
177
178 case cudaErrorInvalidDevice:
179 return "cudaErrorInvalidDevice";
180
181 case cudaErrorInvalidValue:
182 return "cudaErrorInvalidValue";
183
184 case cudaErrorInvalidPitchValue:
185 return "cudaErrorInvalidPitchValue";
186
187 case cudaErrorInvalidSymbol:
188 return "cudaErrorInvalidSymbol";
189
190 case cudaErrorMapBufferObjectFailed:
191 return "cudaErrorMapBufferObjectFailed";
192
193 case cudaErrorUnmapBufferObjectFailed:
194 return "cudaErrorUnmapBufferObjectFailed";
195
196 case cudaErrorInvalidHostPointer:
197 return "cudaErrorInvalidHostPointer";
198
199 case cudaErrorInvalidDevicePointer:
200 return "cudaErrorInvalidDevicePointer";
201
202 case cudaErrorInvalidTexture:
203 return "cudaErrorInvalidTexture";
204
205 case cudaErrorInvalidTextureBinding:
206 return "cudaErrorInvalidTextureBinding";
207
208 case cudaErrorInvalidChannelDescriptor:
209 return "cudaErrorInvalidChannelDescriptor";
210
211 case cudaErrorInvalidMemcpyDirection:
212 return "cudaErrorInvalidMemcpyDirection";
213
214 case cudaErrorAddressOfConstant:
215 return "cudaErrorAddressOfConstant";
216
217 case cudaErrorTextureFetchFailed:
218 return "cudaErrorTextureFetchFailed";
219
220 case cudaErrorTextureNotBound:
221 return "cudaErrorTextureNotBound";
222
223 case cudaErrorSynchronizationError:
224 return "cudaErrorSynchronizationError";
225
226 case cudaErrorInvalidFilterSetting:
227 return "cudaErrorInvalidFilterSetting";
228
229 case cudaErrorInvalidNormSetting:
230 return "cudaErrorInvalidNormSetting";
231
232 case cudaErrorMixedDeviceExecution:
233 return "cudaErrorMixedDeviceExecution";
234
235 case cudaErrorCudartUnloading:
236 return "cudaErrorCudartUnloading";
237
238 case cudaErrorUnknown:
239 return "cudaErrorUnknown";
240
241 case cudaErrorNotYetImplemented:
242 return "cudaErrorNotYetImplemented";
243
244 case cudaErrorMemoryValueTooLarge:
245 return "cudaErrorMemoryValueTooLarge";
246
247 case cudaErrorInvalidResourceHandle:
248 return "cudaErrorInvalidResourceHandle";
249
250 case cudaErrorNotReady:
251 return "cudaErrorNotReady";
252
253 case cudaErrorInsufficientDriver:
254 return "cudaErrorInsufficientDriver";
255
256 case cudaErrorSetOnActiveProcess:
257 return "cudaErrorSetOnActiveProcess";
258
259 case cudaErrorInvalidSurface:
260 return "cudaErrorInvalidSurface";
261
262 case cudaErrorNoDevice:
263 return "cudaErrorNoDevice";
264
265 case cudaErrorECCUncorrectable:
266 return "cudaErrorECCUncorrectable";
267
268 case cudaErrorSharedObjectSymbolNotFound:
269 return "cudaErrorSharedObjectSymbolNotFound";
270
271 case cudaErrorSharedObjectInitFailed:
272 return "cudaErrorSharedObjectInitFailed";
273
274 case cudaErrorUnsupportedLimit:
275 return "cudaErrorUnsupportedLimit";
276
277 case cudaErrorDuplicateVariableName:
278 return "cudaErrorDuplicateVariableName";
279
280 case cudaErrorDuplicateTextureName:
281 return "cudaErrorDuplicateTextureName";
282
283 case cudaErrorDuplicateSurfaceName:
284 return "cudaErrorDuplicateSurfaceName";
285
286 case cudaErrorDevicesUnavailable:
287 return "cudaErrorDevicesUnavailable";
288
289 case cudaErrorInvalidKernelImage:
290 return "cudaErrorInvalidKernelImage";
291
292 case cudaErrorNoKernelImageForDevice:
293 return "cudaErrorNoKernelImageForDevice";
294
295 case cudaErrorIncompatibleDriverContext:
296 return "cudaErrorIncompatibleDriverContext";
297
298 case cudaErrorPeerAccessAlreadyEnabled:
299 return "cudaErrorPeerAccessAlreadyEnabled";
300
301 case cudaErrorPeerAccessNotEnabled:
302 return "cudaErrorPeerAccessNotEnabled";
303
304 case cudaErrorDeviceAlreadyInUse:
305 return "cudaErrorDeviceAlreadyInUse";
306
307 case cudaErrorProfilerDisabled:
308 return "cudaErrorProfilerDisabled";
309
310 case cudaErrorProfilerNotInitialized:
311 return "cudaErrorProfilerNotInitialized";
312
313 case cudaErrorProfilerAlreadyStarted:
314 return "cudaErrorProfilerAlreadyStarted";
315
316 case cudaErrorProfilerAlreadyStopped:
317 return "cudaErrorProfilerAlreadyStopped";
318
319 /* Since CUDA 4.0*/
320 case cudaErrorAssert:
321 return "cudaErrorAssert";
322
323 case cudaErrorTooManyPeers:
324 return "cudaErrorTooManyPeers";
325
326 case cudaErrorHostMemoryAlreadyRegistered:
327 return "cudaErrorHostMemoryAlreadyRegistered";
328
329 case cudaErrorHostMemoryNotRegistered:
330 return "cudaErrorHostMemoryNotRegistered";
331
332 /* Since CUDA 5.0 */
333 case cudaErrorOperatingSystem:
334 return "cudaErrorOperatingSystem";
335
336 case cudaErrorPeerAccessUnsupported:
337 return "cudaErrorPeerAccessUnsupported";
338
339 case cudaErrorLaunchMaxDepthExceeded:
340 return "cudaErrorLaunchMaxDepthExceeded";
341
342 case cudaErrorLaunchFileScopedTex:
343 return "cudaErrorLaunchFileScopedTex";
344
345 case cudaErrorLaunchFileScopedSurf:
346 return "cudaErrorLaunchFileScopedSurf";
347
348 case cudaErrorSyncDepthExceeded:
349 return "cudaErrorSyncDepthExceeded";
350
351 case cudaErrorLaunchPendingCountExceeded:
352 return "cudaErrorLaunchPendingCountExceeded";
353
354 case cudaErrorNotPermitted:
355 return "cudaErrorNotPermitted";
356
357 case cudaErrorNotSupported:
358 return "cudaErrorNotSupported";
359
360 /* Since CUDA 6.0 */
361 case cudaErrorHardwareStackError:
362 return "cudaErrorHardwareStackError";
363
364 case cudaErrorIllegalInstruction:
365 return "cudaErrorIllegalInstruction";
366
367 case cudaErrorMisalignedAddress:
368 return "cudaErrorMisalignedAddress";
369
370 case cudaErrorInvalidAddressSpace:
371 return "cudaErrorInvalidAddressSpace";
372
373 case cudaErrorInvalidPc:
374 return "cudaErrorInvalidPc";
375
376 case cudaErrorIllegalAddress:
377 return "cudaErrorIllegalAddress";
378
379 /* Since CUDA 6.5*/
380 case cudaErrorInvalidPtx:
381 return "cudaErrorInvalidPtx";
382
383 case cudaErrorInvalidGraphicsContext:
384 return "cudaErrorInvalidGraphicsContext";
385
386 case cudaErrorStartupFailure:
387 return "cudaErrorStartupFailure";
388
389 case cudaErrorApiFailureBase:
390 return "cudaErrorApiFailureBase";
391
392 /* Since CUDA 8.0*/
393 case cudaErrorNvlinkUncorrectable:
394 return "cudaErrorNvlinkUncorrectable";
395 default:
396 break;
397 }
398
399 return "<unknown>";
400}
401 #endif
402
403 #ifdef CUBLAS_API_H_
404// cuBLAS API errors
405static const char *_cudaGetErrorEnum(cublasStatus_t error) {
406 switch (error) {
407 case CUBLAS_STATUS_SUCCESS:
408 return "CUBLAS_STATUS_SUCCESS";
409
410 case CUBLAS_STATUS_NOT_INITIALIZED:
411 return "CUBLAS_STATUS_NOT_INITIALIZED";
412
413 case CUBLAS_STATUS_ALLOC_FAILED:
414 return "CUBLAS_STATUS_ALLOC_FAILED";
415
416 case CUBLAS_STATUS_INVALID_VALUE:
417 return "CUBLAS_STATUS_INVALID_VALUE";
418
419 case CUBLAS_STATUS_ARCH_MISMATCH:
420 return "CUBLAS_STATUS_ARCH_MISMATCH";
421
422 case CUBLAS_STATUS_MAPPING_ERROR:
423 return "CUBLAS_STATUS_MAPPING_ERROR";
424
425 case CUBLAS_STATUS_EXECUTION_FAILED:
426 return "CUBLAS_STATUS_EXECUTION_FAILED";
427
428 case CUBLAS_STATUS_INTERNAL_ERROR:
429 return "CUBLAS_STATUS_INTERNAL_ERROR";
430
431 case CUBLAS_STATUS_NOT_SUPPORTED:
432 return "CUBLAS_STATUS_NOT_SUPPORTED";
433
434 case CUBLAS_STATUS_LICENSE_ERROR:
435 return "CUBLAS_STATUS_LICENSE_ERROR";
436 }
437
438 return "<unknown>";
439}
440 #endif
441
442 #ifdef CUSOLVER_COMMON_H_
443// cuSOLVER API errors
444static const char *_cudaGetErrorEnum(cusolverStatus_t error) {
445 switch (error) {
446 case CUSOLVER_STATUS_SUCCESS:
447 return "CUSOLVER_STATUS_SUCCESS";
448 case CUSOLVER_STATUS_NOT_INITIALIZED:
449 return "CUSOLVER_STATUS_NOT_INITIALIZED";
450 case CUSOLVER_STATUS_ALLOC_FAILED:
451 return "CUSOLVER_STATUS_ALLOC_FAILED";
452 case CUSOLVER_STATUS_INVALID_VALUE:
453 return "CUSOLVER_STATUS_INVALID_VALUE";
454 case CUSOLVER_STATUS_ARCH_MISMATCH:
455 return "CUSOLVER_STATUS_ARCH_MISMATCH";
456 case CUSOLVER_STATUS_MAPPING_ERROR:
457 return "CUSOLVER_STATUS_MAPPING_ERROR";
458 case CUSOLVER_STATUS_EXECUTION_FAILED:
459 return "CUSOLVER_STATUS_EXECUTION_FAILED";
460 case CUSOLVER_STATUS_INTERNAL_ERROR:
461 return "CUSOLVER_STATUS_INTERNAL_ERROR";
462 case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
463 return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
464 case CUSOLVER_STATUS_NOT_SUPPORTED:
465 return "CUSOLVER_STATUS_NOT_SUPPORTED ";
466 case CUSOLVER_STATUS_ZERO_PIVOT:
467 return "CUSOLVER_STATUS_ZERO_PIVOT";
468 case CUSOLVER_STATUS_INVALID_LICENSE:
469 return "CUSOLVER_STATUS_INVALID_LICENSE";
470 }
471
472 return "<unknown>";
473}
474 #endif
475
476 #ifdef CURAND_H_
477// cuRAND API errors
478static const char *_cudaGetErrorEnum(curandStatus_t error) {
479 switch (error) {
480 case CURAND_STATUS_SUCCESS:
481 return "CURAND_STATUS_SUCCESS";
482 case CURAND_STATUS_VERSION_MISMATCH:
483 return "CURAND_STATUS_VERSION_MISMATCH";
484 case CURAND_STATUS_NOT_INITIALIZED:
485 return "CURAND_STATUS_NOT_INITIALIZED";
486 case CURAND_STATUS_ALLOCATION_FAILED:
487 return "CURAND_STATUS_ALLOCATION_FAILED";
488 case CURAND_STATUS_TYPE_ERROR:
489 return "CURAND_STATUS_TYPE_ERROR";
490 case CURAND_STATUS_OUT_OF_RANGE:
491 return "CURAND_STATUS_OUT_OF_RANGE";
492 case CURAND_STATUS_LENGTH_NOT_MULTIPLE:
493 return "CURAND_STATUS_LENGTH_NOT_MULTIPLE";
494 case CURAND_STATUS_DOUBLE_PRECISION_REQUIRED:
495 return "CURAND_STATUS_DOUBLE_PRECISION_REQUIRED";
496 case CURAND_STATUS_LAUNCH_FAILURE:
497 return "CURAND_STATUS_LAUNCH_FAILURE";
498 case CURAND_STATUS_PREEXISTING_FAILURE:
499 return "CURAND_STATUS_PREEXISTING_FAILURE";
500 case CURAND_STATUS_INITIALIZATION_FAILED:
501 return "CURAND_STATUS_INITIALIZATION_FAILED";
502 case CURAND_STATUS_ARCH_MISMATCH:
503 return "CURAND_STATUS_ARCH_MISMATCH";
504 case CURAND_STATUS_INTERNAL_ERROR:
505 return "CURAND_STATUS_INTERNAL_ERROR";
506 }
507
508 return "<unknown>";
509}
510 #endif
511
512 #ifdef UNI_CUTENSOR
513static const char *_cudaGetErrorEnum(cutensorStatus_t error) {
514 return cutensorGetErrorString(error);
515}
516 #endif
517
518 #ifdef __DRIVER_TYPES_H__
519 #ifndef DEVICE_RESET
520 #define DEVICE_RESET cudaDeviceReset();
521 #endif
522 #else
523 #ifndef DEVICE_RESET
524 #define DEVICE_RESET
525 #endif
526 #endif
527
528template <typename T>
529void check(T result, char const *const func, const char *const file, int const line) {
530 if (result) {
531 fprintf(stderr, "CUDA error at %s:%d code=%d(%s) \"%s\" \n", file, line,
532 static_cast<unsigned int>(result), _cudaGetErrorEnum(result), func);
533 DEVICE_RESET
534 // Make sure we call CUDA Device Reset before exiting
535 exit(EXIT_FAILURE);
536 }
537}
538
539 #ifdef __DRIVER_TYPES_H__
540 // This will output the proper CUDA error strings in the event that a CUDA host call returns an
541 // error
542 #define checkCudaErrors(val) check((val), #val, __FILE__, __LINE__)
543
544 #endif
545
546#endif // End of #if defined(UNI_GPU)
547
548#endif // CYTNX_CYTNX_ERROR_H_
Definition cytnx_error.hpp:37
void warning_msg_impl(char const *func, char const *file, int line, char const *format,...)
Definition cytnx_error.hpp:106
std::string vformat_message(char const *format, va_list args)
Definition cytnx_error.hpp:44
void error_msg_impl(char const *func, char const *file, int line, char const *format,...)
Definition cytnx_error.hpp:95
void print_backtrace_if_debug()
Definition cytnx_error.hpp:79
std::string compose_report(char const *kind, char const *func, char const *file, int line, const std::string &msg)
Definition cytnx_error.hpp:56
Definition Accessor.hpp:12
bool User_debug