为什么我的CUDA内核使用不同的数据集大小崩溃(未指定的启动失败)?

丹尼尔·乔万(Danieljovan)

我有一个内核,可以根据它们的位置(对角线或非对角线)来计算矩阵的不同元素。计算大小矩阵时,内核按预期工作:

  • 14 x 14(我知道这很小,没有正确使用GPU资源,但这纯粹是出于测试目的,以确保结果正确)
  • 118 x 118,以及
  • 300 x 300

但是,当我尝试计算大小为2383 x 2383的矩阵时,内核崩溃。具体来说,在cudaMemcpy()行上引发了错误“未指定的启动失败”,以将结果从设备返回到主机。通过研究,我了解到该错误通常是在内存访问超出范围的情况下发生的(例如在数组中),但是,我没有得到的是它适用于前三种情况,但不适用于2383 x 2383例。内核代码如下所示:

__global__ void createYBus(float *R, float *X, float *B, int numberOfBuses, int numberOfBranches, int *fromBus, int *toBus, cuComplex *y)
{
    int rowIdx = blockIdx.y*blockDim.y + threadIdx.y;
    int colIdx = blockIdx.x*blockDim.x + threadIdx.x;
    int index = rowIdx*numberOfBuses + colIdx;
    if (rowIdx<numberOfBuses && colIdx<numberOfBuses)
    {
        for (int i=0; i<numberOfBranches; ++i)
        {
            if (rowIdx==fromBus[i] && colIdx==fromBus[i]) { //diagonal element
                y[index] = cuCaddf(y[index], make_cuComplex((R[i]/((R[i]*R[i])+(X[i]*X[i]))), (-(X[i]/((R[i]*R[i])+(X[i]*X[i])))+ (B[i]/2))));
            }
            if (rowIdx==toBus[i] && colIdx==toBus[i]) { //diagonal element
                y[index] = cuCaddf(y[index], make_cuComplex((R[i]/((R[i]*R[i])+(X[i]*X[i]))), (-(X[i]/((R[i]*R[i])+(X[i]*X[i])))+ (B[i]/2))));
            }
            if (rowIdx==fromBus[i] && colIdx==toBus[i]) { //off-diagonal element
                y[index] = make_cuComplex(-(R[i]/((R[i]*R[i])+(X[i]*X[i]))), X[i]/((R[i]*R[i])+(X[i]*X[i])));
            }
            if (rowIdx==toBus[i] && colIdx==fromBus[i]) { //off-diagonal element
                y[index] = make_cuComplex(-(R[i]/((R[i]*R[i])+(X[i]*X[i]))), X[i]/((R[i]*R[i])+(X[i]*X[i])));
            }
        }
    }
}

全局内存分配是通过对cudaMalloc()的调用完成的。代码中的分配如下:

cudaStat1 = cudaMalloc((void**)&dev_fromBus, numLines*sizeof(int));
cudaStat2 = cudaMalloc((void**)&dev_toBus, numLines*sizeof(int));
cudaStat3 = cudaMalloc((void**)&dev_R, numLines*sizeof(float));
cudaStat4 = cudaMalloc((void**)&dev_X, numLines*sizeof(float));
cudaStat5 = cudaMalloc((void**)&dev_B, numLines*sizeof(float));
cudaStat6 = cudaMalloc((void**)&dev_y, numberOfBuses*numberOfBuses*sizeof(cuComplex));
cudaStat7 = cudaMalloc((void**)&dev_Pd, numberOfBuses*sizeof(float));
cudaStat8 = cudaMalloc((void**)&dev_Qd, numberOfBuses*sizeof(float));
cudaStat9 = cudaMalloc((void**)&dev_Vmag, numberOfBuses*sizeof(float));
cudaStat10 = cudaMalloc((void**)&dev_theta, numberOfBuses*sizeof(float));
cudaStat11 = cudaMalloc((void**)&dev_Peq, numberOfBuses*sizeof(float));
cudaStat12 = cudaMalloc((void**)&dev_Qeq, numberOfBuses*sizeof(float));
cudaStat13 = cudaMalloc((void**)&dev_Peq1, numberOfBuses*sizeof(float));
cudaStat14 = cudaMalloc((void**)&dev_Qeq1, numberOfBuses*sizeof(float));
...
...
cudaStat15 = cudaMalloc((void**)&dev_powerMismatch, jacSize*sizeof(float));
cudaStat16 = cudaMalloc((void**)&dev_jacobian, jacSize*jacSize*sizeof(float));
cudaStat17 = cudaMalloc((void**)&dev_stateVector, jacSize*sizeof(float));
cudaStat18 = cudaMalloc((void**)&dev_PQindex, jacSize*sizeof(int));

其中cudaStatN的类型为cudaError_t以捕获错误。最后的四个分配是在代码的后面完成的,并且是针对另一个内核的。但是,这些分配是在调用相关内核之前完成的。

启动参数如下:

dim3 dimBlock(16, 16); //number of threads 
dim3 dimGrid((numberOfBuses+15)/16, (numberOfBuses+15)/16);  //number of blocks

//launch kernel once data has been copied to GPU
createYBus<<<dimGrid, dimBlock>>>(dev_R, dev_X, dev_B, numberOfBuses, numLines, dev_fromBus, dev_toBus, dev_y);

//copy results back to CPU
cudaStat6 = cudaMemcpy(y_bus, dev_y, numberOfBuses*numberOfBuses*sizeof(cuComplex), cudaMemcpyDeviceToHost);
if (cudaStat6 != cudaSuccess) {
    cout<<"Device memcpy failed"<<endl;
    cout<<cudaGetErrorString(cudaStat6)<<endl;
    return 1;
}

我删除了时序代码,只是为了显示所使用的块和网格尺寸以及错误检查技术。

我还具有该函数的主机(C ++代码)版本,我将数据传递给两个函数,然后比较结果,首先,确保内核产生正确的结果,其次,在执行时间方面比较性能。我已经仔细检查了2383 x 2383情况的数据(正在从文本文件中读取数据并将其复制到全局内存中),但在数组访问/索引编制中未发现任何异常。

我使用的是Visual Studio 2010,因此尝试使用Nsight查找错误(我不太熟悉Nsight)。摘要报告概述指出:“报告了1个运行时API调用错误。(有关更多信息,请参阅CUDA运行时API调用报告。)在运行时API调用列表中,cudaMemcpy返回错误4-不确定线程​​ID( 5012)在表中具有任何意义-该数字随每次运行而变化。CUDAmemcheck工具(在命令行中)返回以下内容:

Thank you for using this program
========= Program hit cudaErrorLaunchFailure (error 4) due to "unspecified launch failure" on CUDA API call to cudaMemcpy.
=========     Saved host backtrace up to driver entry point at error
=========
========= ERROR SUMMARY: 1 error

我知道我的内核不是最高效的,因为有许多全局内存访问。为什么更大的矩阵会导致内核崩溃?是否缺少我缺少的数组访问权限?任何帮助将不胜感激。

丹尼尔·乔万(Danieljovan)

解决了问题。事实证明启用了WDDM TDR(超时检测恢复)并将延迟设置为2秒。这意味着如果内核执行时间超过2s,驱动程序将崩溃并恢复。这适用于图形和渲染(用于GPU的通用用途)。但是,在这种情况下,必须禁用TDR或增加延迟。通过将延迟增加到10s,崩溃错误“未指定的启动失败”不再出现,内核继续执行。

可以通过Nsight监视器中的Nsight选项或通过注册表(HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ GraphicsDrivers)-DWORDS Tdrdelay和Tdrlevel来完成TDR延迟(以及启用/禁用)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我在CUDA程序中得到“未指定的启动失败”,将2个矩阵相乘

来自分类Dev

为什么内核启动失败?

来自分类Dev

未指定的启动失败-CUDA中的并行扫描

来自分类Dev

为什么我的CUDA内核执行时间会随着连续启动而增加?

来自分类Dev

Memcpy上的未指定启动失败

来自分类Dev

Udacity并行编程,未指定启动失败

来自分类Dev

为什么Netbeans设计人员将JFrame大小设置为与我指定的大小不同?

来自分类Dev

为什么JMH使用不同的分叉?

来自分类Dev

为什么Spring会使用不同于指定语言的语言加载消息?

来自分类Dev

当我为vba使用相同的代码,相同的数据但使用不同的笔记本电脑时,为什么会得到不同的输出?

来自分类Dev

为什么systemctl用不同的参数启动docker

来自分类Dev

使用 NSOperationQueue 的 Crashlytics 崩溃(QOS:未指定)

来自分类Dev

为什么我会看到使用 js 服务器通过 php 发送事件的未指定 sse 错误?

来自分类Dev

[ubuntu 13.04]为什么我的git使用不同的密钥文件?

来自分类Dev

为什么对于函数的定义和声明,我可以使用不同的签名?

来自分类Dev

[ubuntu 13.04]为什么我的git使用不同的密钥文件?

来自分类Dev

为什么我无法在MySQL中使用不同的行获得结果?

来自分类Dev

为什么发布插件项目失败并显示RuntimeException:未指定发布存储库?

来自分类Dev

当未指定子域时,为什么HTTP-> HTTPS重定向在nodejs中失败?

来自分类Dev

如果我使用31个块,为什么减少CUDA失败?

来自分类Dev

为什么我的sqlite同时调用不同的线程?

来自分类Dev

为什么我用不同的线程生成相同的数字?

来自分类Dev

为什么dig用不同的方式回答我的查询?

来自分类Dev

POSIX为什么未指定`#!`语法的行为?

来自分类Dev

为什么我对CUDA数学库sqrt()函数的调用失败?

来自分类Dev

SSRS-使用不同日期的数据集(表)

来自分类Dev

在散点图中为 Iris 数据集使用不同的颜色

来自分类Dev

为什么我的AWS卷大小与实际大小不同?

来自分类Dev

为什么在冷启动后和锁定时,Linux Mint MATE使用不同的登录屏幕?一定要吗?

Related 相关文章

  1. 1

    为什么我在CUDA程序中得到“未指定的启动失败”,将2个矩阵相乘

  2. 2

    为什么内核启动失败?

  3. 3

    未指定的启动失败-CUDA中的并行扫描

  4. 4

    为什么我的CUDA内核执行时间会随着连续启动而增加?

  5. 5

    Memcpy上的未指定启动失败

  6. 6

    Udacity并行编程,未指定启动失败

  7. 7

    为什么Netbeans设计人员将JFrame大小设置为与我指定的大小不同?

  8. 8

    为什么JMH使用不同的分叉?

  9. 9

    为什么Spring会使用不同于指定语言的语言加载消息?

  10. 10

    当我为vba使用相同的代码,相同的数据但使用不同的笔记本电脑时,为什么会得到不同的输出?

  11. 11

    为什么systemctl用不同的参数启动docker

  12. 12

    使用 NSOperationQueue 的 Crashlytics 崩溃(QOS:未指定)

  13. 13

    为什么我会看到使用 js 服务器通过 php 发送事件的未指定 sse 错误?

  14. 14

    [ubuntu 13.04]为什么我的git使用不同的密钥文件?

  15. 15

    为什么对于函数的定义和声明,我可以使用不同的签名?

  16. 16

    [ubuntu 13.04]为什么我的git使用不同的密钥文件?

  17. 17

    为什么我无法在MySQL中使用不同的行获得结果?

  18. 18

    为什么发布插件项目失败并显示RuntimeException:未指定发布存储库?

  19. 19

    当未指定子域时,为什么HTTP-> HTTPS重定向在nodejs中失败?

  20. 20

    如果我使用31个块,为什么减少CUDA失败?

  21. 21

    为什么我的sqlite同时调用不同的线程?

  22. 22

    为什么我用不同的线程生成相同的数字?

  23. 23

    为什么dig用不同的方式回答我的查询?

  24. 24

    POSIX为什么未指定`#!`语法的行为?

  25. 25

    为什么我对CUDA数学库sqrt()函数的调用失败?

  26. 26

    SSRS-使用不同日期的数据集(表)

  27. 27

    在散点图中为 Iris 数据集使用不同的颜色

  28. 28

    为什么我的AWS卷大小与实际大小不同?

  29. 29

    为什么在冷启动后和锁定时,Linux Mint MATE使用不同的登录屏幕?一定要吗?

热门标签

归档