5

我一直在研究一个 CUDA 程序,该程序随机崩溃unspecified launch failure,相当频繁。通过仔细调试,我定位了哪个内核出现故障,而且只有在 CUDA 内核中调用某些超越函数时才会发生故障(例如sinf()atanhf())。

这导致我编写了一个更简单的程序(见下文),以确认这些超越函数确实导致了问题,看起来确实如此。当我编译并运行下面的代码时,它只是反复调用使用 tanh 和 atanh 的内核,反复地,有时程序可以工作,有时它会打印Error with Kernel出来自驱动程序的一条消息:

NVRM: XiD (0000:01:00): 13, 0002 000000 000050c0 00000368 00000000 0000080

关于频率,它可能在我运行可执行文件的 50% 的时间里崩溃。

从我在网上阅读的内容来看,这听起来XiD 13类似于基于主机的段错误。但是,考虑到数组索引,我看不出这是怎么回事。此外,如果我用其他函数(例如重复的浮点减法和加法)替换内核中的超越函数,程序不会崩溃。也就是说,我没有收到 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 后,我不再遇到这个问题。我认为我描述的问题一定是一个已修复的错误。希望这可以帮助。

4

1 回答 1

1

提问者确定这是由较新的 CUDA 版本修复的临时问题。请参阅对原始问题的编辑。

于 2013-07-13T12:23:15.890 回答