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