How to do error checking in CUDA(如何在CUDA里做错误检查)

https://codeyarns.com/2011/03/02/how-to-do-error-checking-in-cuda/

 

Error checks in CUDA code can help catch CUDA errors at their source. There are 2 sources of errors in CUDA source code:

  1. Errors from CUDA API calls. For example, a call to cudaMalloc() might fail.
  2. Errors from CUDA kernel calls. For example, there might be invalid memory access inside a kernel

在CUDA代码里,错误检查可以帮助找到CUDA代码里的错误,有两种从代码里产生的错误

  1. CUDA API调用错误。如,一个cudaMalloc()调用可能会失败。
  2. CUDA kernel调用错误。如,可能会在某个kernel的实现了访问了非法的内存。

 

All CUDA API calls return a cudaError value, so these calls are easy to check:

所有CUDA API调用都会返回一个cudaError值,所以这种调用非常容易检查。

if ( cudaSuccess != cudaMalloc( &fooPtr, fooSize ) )
    printf( "Error!\n" );

CUDA kernel invocations do not return any value. Error from a CUDA kernel call can be checked after its execution by calling cudaGetLastError():

CUDA kernel不返回任何值。从CUDA kernel调用产生的错误可以在该调用完毕后,从cudaGetLastError()中检查到。

fooKernel<<< x, y >>>(); // Kernel call
if ( cudaSuccess != cudaGetLastError() )
    printf( "Error!\n" );

These two types of checks can be elegantly wrapped up in two simple error-checking functions like this:

这两种检查可以非常优雅地封装在两个错误检查函数中,如下,

// Define this to turn on error checking
#define CUDA_ERROR_CHECK

#define CudaSafeCall( err ) __cudaSafeCall( err, __FILE__, __LINE__ )
#define CudaCheckError()    __cudaCheckError( __FILE__, __LINE__ )

inline void __cudaSafeCall( cudaError err, const char *file, const int line )
{
#ifdef CUDA_ERROR_CHECK
    if ( cudaSuccess != err )
    {
        fprintf( stderr, "cudaSafeCall() failed at %s:%i : %s\n",
                 file, line, cudaGetErrorString( err ) );
        exit( -1 );
    }
#endif

    return;
}

inline void __cudaCheckError( const char *file, const int line )
{
#ifdef CUDA_ERROR_CHECK
    cudaError err = cudaGetLastError();
    if ( cudaSuccess != err )
    {
        fprintf( stderr, "cudaCheckError() failed at %s:%i : %s\n",
                 file, line, cudaGetErrorString( err ) );
        exit( -1 );
    }

    // More careful checking. However, this will affect performance.
    // Comment away if needed.
    err = cudaDeviceSynchronize();
    if( cudaSuccess != err )
    {
        fprintf( stderr, "cudaCheckError() with sync failed at %s:%i : %s\n",
                 file, line, cudaGetErrorString( err ) );
        exit( -1 );
    }
#endif

    return;
}

Using these error checking functions is easy:

使用这两个错误检查函数非常简单:

CudaSafeCall( cudaMalloc( &fooPtr, fooSize ) );
 
fooKernel<<< x, y >>>(); // Kernel call
CudaCheckError();

These functions are actually derived from similar functions which used to be available in the cutil.h in old CUDA SDKs.

这两个函数实际上也是从简单的旧CUDA SDK里导出的

 

posted @ 2018-03-23 14:15  猫薄荷喂狗  阅读(4153)  评论(0编辑  收藏  举报