文章目录
- 前言
- 1.CUDA程序运行时的错误检测
- 检测运行错误的头文件
- 检查运行时的CUDA的api函数
- 检查运行时的CUDA的核函数
- CUDA-MEMCHECK工具
- 总结
前言
CUDA程序运行时的错误检测
1.CUDA程序运行时的错误检测
检测运行错误的头文件
像一些日志文件,一般检测错误都会编写一个头文件来包含要检测错误api运行的代码。在基础的cuda程序api的运行检错中,前面已经了解了基本所有的cuda的api的返回值都有一个是否成功使用的cudaError_t结构的标志信息,成功调用返回cudaSuccess。所以,可以根据返回值,在头文件上定义一个宏函数来检查cuda程序运行是否出错。
#pragma once
#include<stdio.h>
#define CHECK(call) \
do \
{\
const cudaError_t error_code = call; \
if(error_code != cudaSuccess) \
{\
printf("cuda error"); \
printf(" File: %s\n",__FILE__); \
printf(" Line: %d\n",__LINE__); \
printf(" Error code: %d\n",error_code); \
printf(" Error text: %s\n",cudaGetErrorString(error_code)); \
exit(1); \
}\
} while(0);
(1)#pragma once是一个预处理指令,作用和条件编译命令#ifndef作用一样,但更加简洁。
(2)宏函数CHECK的参数是cuda运行时api函数。
(3)预编译器有预定义的宏:
__FILE__ // 获取当前文件名
__func__ // 获取当前函数名
__LINE__ // 获取当前行号
__DATE__ // 获取当前日期
__TIME__ // 获取当前时间
__WORDSIZE // 获取当前编译器的位数,适合用来显示警告、错误信息。
(4)宏函数中不使用do while语句也可以,但在某些情况下不安全。
检查运行时的CUDA的api函数
在源程序中包含编写的头文件,头文件名为了区分,一般命名为xxx.cuh。直接将调用cuda运行时的api函数作为参数传入头文件的CHECK宏函数中即可,如:
// 分配设备内存
double *d_x,*d_y,*d_z;
// printf("%p",d_x);
CHECK(cudaMalloc((void **)&d_x,M));
CHECK(cudaMalloc((void **)&d_y,M));
CHECK(cudaMalloc((void **)&d_z,M));
// 将某些数据从主机复制到设备上
CHECK(cudaMemcpy(d_x,h_x,M,cudaMemcpyHostToDevice));
CHECK(cudaMemcpy(d_y,h_y,M,cudaMemcpyHostToDevice));
// 数组求和
const int block_size = 128;
const int gride_size = N/block_size;
add<<<gride_size,block_size>>>(d_x,d_y,d_z);
CHECK(cudaMemcpy(h_z,d_z,M,cudaMemcpyHostToDevice));
若程序报错,会显示如下信息:
检查运行时的CUDA的核函数
上述的方法因为核函数没有返回值,所以不能直接像上面那样使用。在cuda的api里,有方法可以捕捉到核函数可能发生的错误。
cudaGetLastError():
注意:此函数还可能返回以前异步启动的错误代码。
所以,在后面检查时还要检查是否同步主机与设备,如:
// 数组求和
const int block_size = 1240; // 最大限制是1024
const int gride_size = N/block_size;
add<<<gride_size,block_size>>>(d_x,d_y,d_z);
// 检查核函数的调用
CHECK(cudaGetLastError());
CHECK(cudaDeviceSynchronize()); // 可用可不用,后面的隐式的起到了同步主机与设备的作用
// 将某些数据从设备复制到主机上,这个数据传输函数隐式的起到了同步主机与设备的作用,所以后面用不用cudaDeviceSynchronize都可以
CHECK(cudaMemcpy(h_z,d_z,M,cudaMemcpyDeviceToHost));
check(h_z,N);
使用显示的同步主机与设备的cudaDeviceSynchronize(),报错位置比较精确。
检查到错误的报错信息:
CUDA-MEMCHECK工具
cuda提供了CUDA-MEMCHECK的一个工具集,由cuda-memcheck命令来检查内存的错误。
通过-h可以发现,检查内存的主要是:
总结
cuda程序错误的检查基本方法
参考:
如博客内容有侵权行为,可及时联系删除!
CUDA 编程:基础与实践
https://docs.nvidia.com/cuda/
https://docs.nvidia.com/cuda/cuda-runtime-api
https://github.com/brucefan1983/CUDA-Programming