我有一个CUDA代码,其工作原理如下:
cpyDataGPU --> CPU
while(nsteps){
cudaKernel1<<<,>>>
function1();
cudaKernel2<<<,>>>
}
cpyDataGPU --> CPU
并且function1就是这样:
function1{
cudaKernel3<<<,>>>
cudaKernel4<<<,>>>
cpyNewNeedDataCPU --> GPU // Error line
cudaKernel5<<<,>>>
}
根据cudaMemcpy documentation,此函数可以产生4个不同的错误代码:“cudaSuccess”,“cudaErrorInvalidValue”,“cudaErrorInvalidDevicePointer”和“cudaErrorInvalidMemcpyDirection”。
但是,我收到以下错误:“cudaErrorLaunchFailure”:“执行内核时设备发生异常。常见原因包括解除引用无效设备指针和访问超出范围的共享内存。直到cudaThreadExit(设备无法使用)调用。所有现有的设备内存分配都是无效的,如果程序要继续使用CUDA,则必须重建。“
有没有人知道我为什么会收到这个错误? 我做错了什么?
在以前的内核调用之后复制数据CPU - &gt; GPU是否有意义?问题是,我必须在每个步骤复制这些数据,因为它可能会在每个“while”步骤中发生变化。
提前做了很多!!
答案 0 :(得分:5)
您链接的文档也说:
请注意,此函数还可能返回先前异步启动的错误代码。
当您调用cudaMemcpy()
时,程序将等待所有前面的GPU工作完成(请记住内核启动是异步的),然后检查状态并在一切正常时执行memcpy。但是,在这种情况下,你的一个内核失败了。
此错误的最常见原因是越界访问,非常类似于x86领域中的段错误。
cudaErrorLaunchFailure:执行内核时设备发生异常。常见原因包括解除引用无效设备指针和访问超出范围的共享内存。在调用cudaThreadExit()之前,不能使用该设备。所有现有设备内存分配均无效,如果程序要继续使用CUDA,则必须重建。
最简单的调试方法是使用cuda-memcheck。或者,您可以通过在每次启动内核后调用cudaDeviceSynchronize()
并检查返回值来确定哪个内核失败。
答案 1 :(得分:2)
您是否在调用内核后检查错误状态?因为(几乎?)所有cuda调用可能会从先前失败的调用或内核返回错误。由于您的启动失败,我怀疑复制之前的一个内核是错误的真正来源。