我一直在研究一个CUDA程序,该程序随机地与unspecified launch failure
一起崩溃。通过仔细调试,我定位了哪个内核失败,而且只有在CUDA内核中调用了某些超越函数时才会发生失败(例如sinf()
或atanhf()
)。
这使我编写了一个更简单的程序(见下文),以确认这些超越函数确实引起了一个问题,看起来确实如此。当我编译并运行下面的代码时,它反复调用内核使用tanh和atanh,有时候程序会工作,有时会打印Error with Kernel
以及来自驱动程序的消息: / p>
NVRM:XiD(0000:01:00):13,0002 000000 000050c0 00000368 00000000 0000080
关于频率,它可能会在我运行可执行文件的50%时间内崩溃。
从我在网上看到的,听起来XiD 13
类似于基于主机的seg故障。但是,鉴于数组索引,我无法看出情况如何。此外,如果我用其他函数替换内核中的超越函数(例如重复的浮点减法和加法),程序不会崩溃。也就是说,我没有得到XiD错误消息,程序最终返回正确的atanh值(0.7)。
我在Ubuntu 11.10 x64桌面上运行cuda-5.0。驱动程序版本是304.54,我使用的是GeForce 9800 GTX。
我倾向于说这是硬件问题或驱动程序错误。奇怪的是,来自nvidia的示例应用程序运行良好,可能是因为它们不使用受影响的超越函数。
潜在重要信息的最后一点是,如果我运行我的主项目或cuda-memcheck下的此测试程序,它会报告没有错误,并且永远不会崩溃。老实说,我只是在cuda-memcheck下运行我的项目,但性能打击使它变得不切实际。
在此提前感谢您的任何帮助/见解。如果任何人拥有9800 GTX并且愿意运行此代码以查看它是否有效,那将非常感激。
#include <iostream>
#include <stdlib.h>
using namespace std;
__global__ void test_trans (float *a, int length) {
if ((threadIdx.x + blockDim.x*blockIdx.x) < length) {
float temp=0.7;
for (int i=0;i<100;i++) {
temp=atanh(temp);
temp=tanh(temp);
}
a[threadIdx.x+ blockDim.x*blockIdx.x] = atanh(temp);
}
}
int main () {
float *array_dev;
float *array_host;
unsigned int size=10000000;
if (cudaSuccess != cudaMalloc ((void**)&array_dev, size*sizeof(float)) ) {
cerr << "Error with memory Allocation\n"; exit (-1);}
array_host = new float [size];
for (int i=0;i<10;i++) {
test_trans <<< size/512+1, 512 >>> (array_dev, size);
if (cudaSuccess != cudaDeviceSynchronize()) {
cerr << "Error with kernel\n"; exit (-1);}
}
cudaMemcpy (array_host, array_dev, sizeof(float)*size, cudaMemcpyDeviceToHost);
cout << array_host[size-1] << "\n";
}
编辑:我放弃了这个项目几个月,但昨天更新到驱动程序版本319.23后,我不再遇到这个问题了。我认为我描述的问题一定是修复过的错误。希望这会有所帮助。
答案 0 :(得分:1)
提问者确定这是一个由较新的CUDA版本修复的临时问题。请参阅原始问题的编辑。