cudaGetErrorString与cudaGetLastError组合运用

本文介绍了如何在CUDA编程中利用cudaGetLastError和cudaGetErrorString进行错误检查和调试。这两个函数可以帮助开发者在运行时捕获CUDA API错误和核函数错误。cudaGetLastError返回上一个CUDA API调用的错误状态,而cudaGetErrorString将错误代码转换为可读的错误信息字符串。在核函数前后使用这两个函数,结合cudaDeviceSynchronize进行同步,可以有效地检测并定位错误。对于大型项目,建议通过宏定义进行代码优化,以提高调试效率。在发布版本时,可以通过预编译条件移除这些调试代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cudaGetErrorString与cudaGetLastError组合运用

前言

在利用集成开发环境(如:visual studio)编写CUDA代码时,编译时是分开编译的,CUDA部分用的是nvcc编译器,这样VS就无法反馈我们CUDA代码的错误,有时候造成了不可避免的内存泄露或者程序出错,自己都不知道,只能一个断点一个断点调试。因此,CUDA也提供了一些函数可以捕捉到error,让我们Debug的时候更方便一点。

cudaGetLastError

通过翻阅CUDA手册,我们可知宿主线程维护着一个初始化为cudaSuccess的cudaError_t类型变量,但出现错误时,该变量都会被错误代码替换。在调用cudaGetLastError()时,就会返回此变量,并将其置为cudaSucess。即返回的是cudaGetLastError()上面代码的错误。
也就是cudaGetLastError可以返回一个变量,该变量存储的是错误代码的信息

cudaGetErrorString

__host__​__device__​const char* 	cudaGetErrorString ( cudaError_t error )

该函数的参数为一个存储错误代码的cudaError_t变量,返回的是该变量对应的错误信息,以字符串的形式接收。

使用方法

1、用于有不需要同步的runtime Api
cudaMalloc(...)
printf("cudaMalloc function : %s\n",cudaGetErrorString(cudaGetLastError()));

这样就可查看cudaMalloc函数是否运行成功。
其实每个runtime API函数都有一个cudaError_t的返回值,我们可以直接将其与cudaSuccess比较即可,可以自己实现一个简单的检查错误。有一些runtime API会自己报错,无需我们检查。

2、用于查找核函数是否有错误(主要功能,CUDA手册介绍的)

核函数不会也不能返回任何错误代码,所以我们必须在核函数启动之后调用cudaGetLastError来检索核函数是否启动成功。同时,我们也还需在核函数启动之前也调用cudaGetLastError来确保启动前的错误变量为cudaSuccess,排除核函数以外的错误信息。
** 由于核函数的启动是异步的,所以需要在启动之后和调用cudaGetLastError之间进行同步 **,否则将无法得到正确的信息。
例如:

printf("befor kernel function : %s\n",cudaGetErrorString(cudaGetLastError()));
kernelfunction<< <...,...> >>();
cudaDeviceSynchronize();//这个同步不能省略
printf("after kernel function : %s\n",cudaGetErrorString(cudaGetLastError()));

这样我们就可以判断核函数启动是否成功了。

3、用于查找其它库的函数是否有错误

当运用到其它库时,也可以使用此方法知道该函数是否运行成功,使用方法和runtime API一样。但是无法准确知道到底时什么错误原因。最好还是用该库对应的错误变量,然后比对该类型的枚举代表的是什么意思。
例如:cublas库的函数返回的变量为cublasStatus_t类型,是个枚举类型。

typedef enum{
    CUBLAS_STATUS_SUCCESS         =0,
    CUBLAS_STATUS_NOT_INITIALIZED =1,
    CUBLAS_STATUS_ALLOC_FAILED    =3,
    CUBLAS_STATUS_INVALID_VALUE   =7,
    CUBLAS_STATUS_ARCH_MISMATCH   =8,
    CUBLAS_STATUS_MAPPING_ERROR   =11,
    CUBLAS_STATUS_EXECUTION_FAILED=13,
    CUBLAS_STATUS_INTERNAL_ERROR  =14,
    CUBLAS_STATUS_NOT_SUPPORTED   =15,
    CUBLAS_STATUS_LICENSE_ERROR   =16
} cublasStatus_t;

通过这个来比对,具体的错误是什么。然后想知道字面上是代表是什么含义的话,可以翻阅CUDA手册。

最后(优化)

如果在大项目里面使用该方法Debug,无疑是很冗长的,所以需要我们对其进行优化。我们可以将其写成宏定义,抽象出其中重复的部分,写成一个宏,然后再封装成一个比较简洁的宏,这样代码就清晰许多。
我们知道这些调试代码会对程序的运行速度大打折扣,所以当发布release版本时,可以将其去掉。这个操作可以用到预编译去完成,我们只需要在Debug模式下调试即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值