cuda - 如何捕获或处理 CUDA 内核启动错误

标签 cuda error-checking

我使用 CUDA 工具包示例中的 checkCudaErrors 辅助函数。请参阅“helper_cuda.h”。我很困惑为什么 checkCudaErrors 没有捕获此示例中的启动错误。错误是启动的线程太多 (2048)。

从调试 (linux gdb) 中,控制台打印(红色的 stderr)“警告:检测到 Cuda API 错误:cudaLaunch 返回 (0x9)”。

而当我从 Bash shell 执行发布或调试构建时,checkCudaErrors 不会打印任何错误。

这是为什么?

我的期望是错误将在启动后立即在 D2H memcpy 调用中被捕获并打印。这是不正确的吗?

最小可重现示例:

#include <cuda.h>
#include "helper_cuda.h"

__global__ void BusyIncrementKernel( const size_t increments, float * result){
    float tmp = 0;
    for ( size_t i = 0; i < increments; ++i ){ tmp += 1; }
    const int j = threadIdx.x + blockIdx.x*blockDim.x;
    if ( j == 0 ){ *result = tmp; }
}

int main( int argc, char * argv[] ){
    unsigned int blockDim = 2048;
    dim3 block{ blockDim, 1, 1};
    dim3 grid{ 1, 1, 1};
    float * dResult;
    checkCudaErrors( cudaMalloc( &dResult, sizeof(float) ));
    BusyIncrementKernel<<< grid, block >>>( 10000000, dResult );
    float result;
    checkCudaErrors( cudaMemcpy( &result, dResult, sizeof(float), cudaMemcpyDeviceToHost ));
    checkCudaErrors( cudaFree( dResult ));
    checkCudaErrors( cudaDeviceSynchronize() );
    fprintf( stderr,"result: %f\n", result );
    return 0;
}

最佳答案

This answer by talonmies特别指出内核启动需要稍微不同的模式来处理。 The CUDA API documentation 3.2.9. on Error Checking解释了这一点。

This answer by Robert Crovella表示有两种错误类型,它们的不同之处在于 API 报告(返回)它们的方式*。

我的结果是;捕获内核启动错误的唯一方法是在启动调用后使用 cudaPeekAtLastError() 或 cudaGetLastError() 。这些是唯一返回启动错误代码的 API 函数。后续的其他API调用没有返回启动错误代码,也没有清除它;稍后可以通过 cudaPeekAtLastError 或 cudaGetLastError 获取。

关于cuda - 如何捕获或处理 CUDA 内核启动错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49488746/

相关文章:

c - 追踪 cuda 内核寄存器的使用

c++ - 一旦 cudaMalloc 返回内存不足,每个 cuda API 调用都会返回失败

c++ - C++如何防止在编译时调用一个以上的方法?

c - 在C中读取整数时对字符进行错误检查

java - 如何确保在 Apache Commons CLI 中提供所有参数?

c++ - 在 C++ 中通过错误检查将命令行 char 参数解析为 int

c++ - Cublas 矩阵 LU 分解

c++ - CUDA 计数、缩减和线程扭曲

c++ - 检查数组是否为 'right' (C++)

将 C 程序转换为 CUDA(最大缩减)