CUDA运行时API错误30:重复的内核调用

时间:2012-08-30 16:01:39

标签: cuda

我最近开始学习CUDA,我偶然发现了一个我无法理解的非常奇怪的行为。

我的代码基本上计算了一个简单的atomicAdd内核的平均执行时间。为了实现这一点,我在循环中调用内核以获得更好的平均值。我在循环中包含设备内存分配和副本,因为我想在执行时间估计中包含它。问题是,如果循环中的运行次数太高,程序通常会因运行时API错误30而失败。

我怀疑我的内存访问可能有问题,所以我在程序上运行memcheck无济于事。显然没有内存错误。此外,如果只运行几次内核,则没有问题,这似乎也表明内核不是问题。只有当我连续过于频繁地称它为有问题时才会这样。

我的代码的骨架如下:

for(int i = 0; i < runs; i++)
{


    //////////////////////////////////
    // Copy memory from Host to Device
    //////////////////////////////////

    cutilSafeCallNoSync( cudaMemcpy(dev_waveforms, waveforms, num_wf * wf_length *  sizeof(float), 
                        cudaMemcpyHostToDevice) );
    cutilSafeCallNoSync( cudaMemcpy(dev_delays, delays, num_wf * sizeof(int), 
                        cudaMemcpyHostToDevice) );




    ////////////////////////
    // Kernel Call
    ////////////////////////

    kernel_wrapper<float>(dev_waveforms, dev_focused, dev_delays, 
                    wf_length, num_wf, threads, blocks, kernel); 

    //copy back to host memory.
    cutilSafeCallNoSync( cudaMemcpy(focused, dev_focused, J * wf_length * sizeof(float), 
        cudaMemcpyDeviceToHost) );

}

同样,如果运行足够大,这只会失败。还有其他一些奇怪的事情发生了,但我现在就把它留在这里。

哦,我正在使用Visual Studio 2010在Windows 7上进行开发。我的GPU也充当了我的视频卡,我担心这可能会产生奇怪的效果。

提前致谢!

3 个答案:

答案 0 :(得分:2)

Windows 7驱动程序可能会将多个命令批量处理到单个提交中,以解决WDDM增加的驱动程序开销(与WDDM之前的驱动程序相比,例如Win XP)。因此,即使单个内核没有超过监视程序,也可以像这样循环运行。您可以调用cudaDeviceSynchronize(),因为@RogerDahl建议尝试解决它(可能只有每N次迭代)。

或者在Linux上运行。

修改 运行时错误30是未知错误。如果这是一个看门狗定时器超时,我会期望cudaErrorLaunchTimeout(错误6)。由于您没有提供完整的代码,因此很难说是导致错误的原因。我怀疑你的内核代码中有一个错误。

答案 1 :(得分:1)

我遇到了同样的错误,发现我的内核实际上超出了我分配的内存。由于您将缓冲区加倍并且问题消失了,我预计您可能会遇到同样的问题。

我的问题是我的数学错误,以确定要启动多少个线程和块。我的发射量是我预期的八倍。在我的内核中,用于确定给定线程应该处理哪个元素的数学运算导致访问我的数组之外的方式。

确保检查每个线程正在使用的数组的哪个元素,以防止执行将访问/修改数组外部内存的线程。

答案 2 :(得分:1)

对于其他任何人来这篇文章寻找答案,为什么你收到错误30消息:

如果您不小心将CPU变量作为GPU 设备功能的参数之一,您也会收到此错误。这是我遇到这个问题最常见的原因。您会想到,经过多次意外地将变量的cpu副本作为您将要学习的参数放置,但是... ...

确保您设备的所有参数都有效: myDeviceFunciont&lt;&lt;&lt; 1,N&gt;&gt;&gt;(argument1,argument2,argument3)

是GPU变量(即:您在cudaMalloc&amp; cudaMemcpy中用于在GPU上分配内存的变量)