-
Notifications
You must be signed in to change notification settings - Fork 1
/
cuda_error_handler.h
88 lines (72 loc) · 2.84 KB
/
cuda_error_handler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma once
#ifndef CUDA_ERROR_HANDLER_
#define CUDA_ERROR_HANDLER_
// CUDA Error handlers
// Author: Ugo Varetto
#include <cuda.h>
#include <sstream>
#include <stdexcept>
#include <iostream>
#include <cstdlib>
//Handle error conditions with or without exceptions (which are zero-cost, so no reason not to use them)
//In CUDA every function returns a status code.
//Error conditions are signalled by a status code other than 'cudaSuccess'
//Textual information can be obtained from an error code through a call
//to cudaGetErrorString.
//Note that in CUDA kernel launches are asynchronous and it is therefore
//possible only to detect errors which cause a failed kernel launch, errors
//generated during kernel execution are not reported.
//usage:
// w/ exceptions:
//try {
//...
// HANDLE_CUDA_ERROR( cudaMemcpy( ... ) );
//...
// LAUNCH_CUDA_KERNEL( kernel<<<...>>>(...) )
//} catch( const std::exception& e ) {
// std::cerr << "e.what()" << std::endl;
//}
//
// w/o exceptions:
// ...
// DIE_ON_CUDA_ERROR( cudaMemcpy( ... ) );
// ...
// DIE_ON_FAILED_KERNEL_LAUNCH( kernel<<<...>>>(...) )
//Note: 'inline' is required simply because the functions are defined inside an include;
// not adding it violates the one definition rule when multiple source file include
// this include file
inline void HandleCUDAError( cudaError_t err,
const char *file,
int line,
const char* msg = 0 ) {
if( err != cudaSuccess )
{
std::ostringstream ss;
ss << ( msg != 0 ? msg : "" ) << " File: " << file << ", Line: " << line << ", Error: " << cudaGetErrorString( err );
throw std::runtime_error( ss.str() );
}
}
inline void DieOnCUDAError( cudaError_t err,
const char *file,
int line,
const char* msg = 0 ) {
if( err != cudaSuccess )
{
std::cerr << ( msg != 0 ? msg : "" )
<< " File: "
<< file << ", Line: " << line << ", Error: " << cudaGetErrorString( err ) << std::endl;
exit( 1 );
}
}
#define HANDLE_CUDA_ERROR( err ) ( HandleCUDAError( err, __FILE__, __LINE__ ) )
#define DIE_ON_CUDA_ERROR( err ) ( DieOnCUDAError( err, __FILE__, __LINE__ ) )
// warning: since kernel execution is asynchronous this macro will only catch
// errors resulting from a failed kernel launch but the error generated
// during kernel execution
#define LAUNCH_CUDA_KERNEL( k ) \
k; \
HandleCUDAError( cudaGetLastError(), __FILE__, __LINE__, "(Kernel launch)" ); \
#define DIE_ON_FAILED_KERNEL_LAUNCH( k ) \
k; \
DieOnCUDAError( cudaGetLastError(), __FILE__, __LINE__, "(Kernel launch)" ); \
#endif //CUDA_ERROR_HANDLER_