深度学习部署(十九): CUDA RunTime API_error

CUDA中的核函数执行是异步的,导致错误检测需要通过设备同步如cudaDeviceSynchronize来确保。错误分为可恢复和不可恢复,前者如参数配置错误,后者如内存访问越界。未同步时,cudaPeekAtLastError只能获取输入参数错误,而真正执行错误需在核函数完成后检查。示例代码展示了错误处理的方法及其影响。

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

知识点

  1. 若cuda核函数出错,由于他是异步的,立即执行cudaPeekAtLastError只会拿到对输入参数校验是否正确的状态,而不会拿到核函数是否执行正确的状态
  2. 因此需要等待核函数执行完毕后,才真的知道当前核函数是否出错,一般通过设备同步或者流同步进行等待
  3. 错误分为可恢复和不可恢复两种:
    • 可恢复:
      • 参数配置错误等,例如block越界(一般最大值是1024),shared memory大小超出范围(一般是48KB)
      • 通过cudaGetLastError可以获取错误代码,同时把当前状态恢复为success
      • 该错误在调用核函数后可以立即通过cudaGetLastError/cudaPeekAtLastError拿到
      • 该错误在下一个函数调用的时候会覆盖
    • 不可恢复:
      • 核函数执行错误,例如访问越界等等异常
      • 该错误则会传递到之后的所有cuda操作上
      • 错误状态通常需要等到核函数执行完毕才能够拿到,也就是有可能在后续的任何流程中突然异常(因为是异步的)

可恢复错误代码


#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>
using namespace std;

__global__ void func(float* ptr){

    int pos = blockIdx.x * blockDim.x + threadIdx.x;
    if(pos == 999){
        ptr[999] = 5;
    }
}

int main(){

    float* ptr = nullptr;
    cudaMalloc(&ptr, sizeof(float) * 1000);  // 为指针分配内存

    // 因为核函数是异步的,因此不会立即检查到他是否存在异常
    // func<<<100, 10>>>(ptr);
    func<<<100, 1050>>>(ptr);
    auto code1 = cudaPeekAtLastError();
    cout << cudaGetErrorString(code1) << endl;

    // 对当前设备的核函数进行同步,等待执行完毕,可以发现过程是否存在异常
    auto code2 = cudaDeviceSynchronize();
    cout << cudaGetErrorString(code2) << endl;

    // 异常会一直存在,以至于后续的函数都会失败
    float* new_ptr = nullptr;
    auto code3 = cudaMalloc(&new_ptr, 100);
    cout << cudaGetErrorString(code3) << endl;
    return 0;
}

输出:

invalid configuration argument
no error
no error

不可回复错误代码: 一般是指针, 除0这种错误

cudaDeviceSynchronize()函数会同步等待设备完成之前的所有任务并检查是否有错误发生,如果有错误会返回相应的错误码。所以使用cudaDeviceSynchronize()函数可以及时发现是否有错误发生,进而打印出错误信息。


#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>
using namespace std;

__global__ void func(float* ptr){

    int pos = blockIdx.x * blockDim.x + threadIdx.x;
    if(pos == 999){
        ptr[999] = 5;
    }
}

int main(){

    float* ptr = nullptr;
    // cudaMalloc(&ptr, sizeof(float) * 1000);  // 为指针分配内存

    // 因为核函数是异步的,因此不会立即检查到他是否存在异常
    func<<<100, 10>>>(ptr);
    // func<<<100, 1050>>>(ptr);
    auto code1 = cudaPeekAtLastError();
    cout << cudaGetErrorString(code1) << endl;

    // 对当前设备的核函数进行同步,等待执行完毕,可以发现过程是否存在异常
    auto code2 = cudaDeviceSynchronize();
    cout << cudaGetErrorString(code2) << endl;

    // 异常会一直存在,以至于后续的函数都会失败
    float* new_ptr = nullptr;
    auto code3 = cudaMalloc(&new_ptr, 100);
    cout << cudaGetErrorString(code3) << endl;
    return 0;
}

输出

no error
an illegal memory access was encountered
an illegal memory access was encountered
ffmpeg已安装,将自动为视频添加音频 ================================================== 环境检查: CUDA 版本: CUDA 6.5 cuDNN 版本: cuDNN 9.10.2 ONNX Runtime GPU 支持: 支持GPU: True, 但初始化失败: [ONNXRuntimeError] : 1 : FAIL : Load model from D:\Personal\Temp\tmpa584yr5l.onnx failed:system error number 13 ================================================== 尝试使用 CUDAExecutionProvider 进行GPU加速 2025-06-11 23:48:37.7860629 [E:onnxruntime:Default, provider_bridge_ort.cc:1992 onnxruntime::TryGetProviderInfo_CUDA] D:\a\_work\1\s\onnxruntime\core\session\provider_bridge_ort.cc:1637 onnxruntime::ProviderLibrary::Get [ONNXRuntimeError] : 1 : FAIL : LoadLibrary failed with error 126 "" when trying to load "D:\Program Files\python39\lib\site-packages\onnxruntime\capi\onnxruntime_providers_cuda.dll" 2025-06-11 23:48:37.7967453 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:965 onnxruntime::python::CreateExecutionProviderInstance] Failed to create CUDAExecutionProvider. Require cuDNN 9.* and CUDA 12.*, and the latest MSVC runtime. Please install all dependencies as mentioned in the GPU requirements page (https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html#requirements), make sure they're in the PATH, and that your GPU is supported. ONNX Runtime 使用的提供程序: ['CPUExecutionProvider'] 模型输入信息: Name: AnimeGANv3_input:0, Shape: [1, 'unk__1822', 'unk__1823', 3], Type: tensor(float) 模型输出信息: Name: generator_1/main/out_layer:0, Shape: ['unk__1824', 'unk__1825', 'unk__1826', 3], Type: tensor(float) 处理视频: 切片法区测试.mp4 使用FFmpeg进行视频编码
最新发布
06-12
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值