CUDA从入门到放弃(九):CUDA错误处理(Error Handling)

cudaSuccess:表示操作成功,其值为0。
cudaErrorInvalidValue:表示函数接收到了一个无效的值,其值为1。
cudaErrorMemoryAllocation:表示内存分配失败,其值为2。
cudaErrorInitializationError:表示初始化错误,其值为3。
cudaErrorCudartUnloading:表示CUDA运行时正在卸载,其值为4。
……

当调用这类带返回码的CUDA函数时,我们通常会将返回的错误码与cudaSuccess进行比较,以判断操作是否成功。然而,仅仅记录错误码可能并不足以帮助我们迅速定位问题,因为错误码本身是一个数字,要理解其背后的含义,通常需要查阅文档。

为了更直观地记录错误信息,CUDA提供了两个非常有用的函数 cudaGetErrorName 和 cudaGetErrorString:

cudaGetErrorName:
__host____device__const char \*cudaGetErrorName(cudaError_t error)

cudaGetErrorName 函数接受一个cudaError_t类型的错误码作为参数,并返回与之对应的错误名称。如果传入的错误码不在CUDA定义的错误码列表中,它会返回字符串“unrecognized error code”。

cudaGetErrorString:
__host____device__const char \*cudaGetErrorString(cudaError_t error)

cudaGetErrorString 与cudaGetErrorName类似,但它返回的是关于该错误码的详细描述信息。同样,如果错误码无法识别,它会返回“unrecognized error code”。

通过使用这两个函数,我们可以在记录错误日志时包含更详细的错误信息,从而更快速地定位和解决问题。因此,在编写涉及CUDA操作的代码时,建议对每个可能返回错误码的API调用都进行错误检查,并在发现错误时调用这些函数以获取更具体的错误信息。

使用示例:

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda\_runtime.h> 
  
cudaError_t cuda\_check(cudaError_t error_code, int line)  
{  
    if (error_code != cudaSuccess)  
    {  
        printf("line: %d, error\_code: %d, error\_name: %s, error\_description: %s\n",  
                line, error_code, cudaGetErrorName(error_code), cudaGetErrorString(error_code));  
        exit(EXIT_FAILURE); // 如果出现错误,最好退出程序 
    }  
    return error_code;  
}  
  
int main()  
{  
    // host上申请内存空间 
    float \*p_host = (float \*)malloc(4 \* sizeof(float)); 
    memset(p_host, 0, 4 \* sizeof(float));
  
    // device上申请相同大小空间 
    float \*p_device;  
    cudaError_t error_code = cudaMalloc((void\*\*)&p_device, 4 \* sizeof(float));
    cuda\_check(error_code, \_\_LINE\_\_); 
  
    // 使用cudaMemset设置device内存为0 
    error_code = cudaMemset(p_device, 0, 4 \* sizeof(float)); // 修正:确保清零整个内存块 
    cuda\_check(error_code, \_\_LINE\_\_);  
  
    // host数据拷贝到device 
    error_code = cudaMemcpy(p_device, p_host, 4 \* sizeof(float), cudaMemcpyHostToDevice); // 修正:使用正确的方向参数 
    cuda\_check(error_code, \_\_LINE\_\_);  
  
    free(p_host); // 释放host内存 
  
    // 释放device内存 
    error_code = cudaFree(p_device);  
    cuda\_check(error_code, \_\_LINE\_\_);  
  
    return 0;  
}

2 不带返回码函数的错误检查

除了那些直接返回cudaError_t类型错误码的函数外,CUDA中确实存在一些不直接返回错误码的函数,特别是那些核函数(kernels),它们通常被设计为返回void类型。对于这类函数,如何进行错误检查就显得尤为重要。

对于熟悉Linux环境的开发者来说,$?这个变量应该不陌生,它用于获取上一个shell命令的退出状态码。在CUDA编程中,有一个类似的机制来检查不带返回码函数的执行结果,那就是cudaGetLastError 和 cudaPeekAtLastError函数, 这两函数不接受任何参数,并返回一个cudaError_t类型的错误码。如果自上次调用CUDA运行时函数以来没有发生错误,那么它将返回cudaSuccess。否则,它将返回与错误相对应的枚举值。

cudaGetLastError:
__host__ __device__ cudaError_t cudaGetLastError(void)

cudaGetLastError函数返回在主机线程中由CUDA Runtime库同一实例的任何运行时调用产生的最后一个错误,并将其重置为cudaSuccess。

cudaPeekAtLastError:
__host____device__cudaError_t cudaPeekAtLastError(void)

cudaGetLastError函数返回在主机线程中由CUDA Runtime库同一实例的任何运行时调用产生的最后一个错误。但是不会像cudaGetLastError()那样将错误重置为cudaSuccess。

为了有效使用cudaGetLastError进行错误检查,我们通常在执行不带返回码的函数后,立即调用它来检查是否有错误发生。如果有错误,我们可以使用之前提到的cudaGetErrorName和cudaGetErrorString函数来获取更详细的错误信息,以便于调试和解决问题。

使用示例:

#include <stdio.h> 
 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/b6aa5eb2c1f6462d484a584bcd91998b.png)

![img](https://img-blog.csdnimg.cn/img_convert/edaf5979cf55d019b26e4259f2163290.png)

![img](https://img-blog.csdnimg.cn/img_convert/8fc1ef8e644f128e07096f2f87935f55.png)

![img](https://img-blog.csdnimg.cn/img_convert/058a5d0dd3570cc51f5c56506357b034.png)

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**

小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**

![](https://img-blog.csdnimg.cn/img_convert/acb644cd6c5d651fe2fb8706c2fa9a12.jpeg)
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值