【问题标题】:How to check which CUDA error arises in which asynchronous CUDA call?如何检查在哪个异步 CUDA 调用中出现了哪个 CUDA 错误?
【发布时间】:2020-10-01 13:39:01
【问题描述】:

假设我们有以下情况:

launch_kernel_a<<<n_blocks, n_threads>>>(...);
launch_kernel_b<<<n_blocks, n_threads>>>(...);
cudaDeviceSynchronize();
if(cudaGetLastError() != CudaSuccess)
{
    // Handle error
    ...
}

我的理解是,在上面,任何一个内核异步执行过程中发生的执行错误都可能由cudaGetLastError()返回。在这种情况下,我如何确定是哪个内核导致在运行时发生错误?

【问题讨论】:

  • 在最一般的情况下,您不能。如果您愿意插入同步,那么本地化就变得容易了。如果您想使用调试器方法,您可以启用在故障点启动调试器,这样就可以清楚地确定是哪个内核导致了问题。您也可以使用方法here。如果您启动同一个内核的两个实例,即使该方法也无法正确本地化它。
  • 那么有没有办法在运行时定位错误呢?如果说我想重新启动失败的内核,可能使用不同的参数,没有办法确定哪个内核失败了,我必须假设在同步之间启动的所有内核都失败了?
  • 我不想重复自己。我已经把我知道的告诉了你。其他人可能有更好的建议。此外,您可能希望注意,在运行时以异步方式(即启动后,执行期间)失败的内核将破坏 CUDA 上下文。除非您终止并重新启动应用程序或take multiprocess steps,否则这样的上下文在运行时无法用于进一步的“重新启动”工作(或者实际上,任何 CUDA 活动)。
  • 谢谢,知道内核执行错误本质上是不可恢复的,这确实为我澄清了很多事情。我应该在发帖之前检查一下。很抱歉让你重复自己。

标签: asynchronous error-handling cuda


【解决方案1】:

我的理解是,在上述情况下,任一内核异步执行过程中发生的执行错误都可能由cudaGetLastError()返回。

没错。运行时 API 将返回遇到的最后一个错误。无法知道异步 API 调用序列中的哪个调用产生了错误。

在这种情况下,我如何确定是哪个内核导致在运行时发生错误?

你不能。您需要在两次内核启动之间进行某种额外的 API 调用来确定错误。最粗暴的方法是cudaDeviceSynchronize() 调用,尽管如果它们确实重叠,这会序列化操作(尽管我没有看到流使用,所以这里可能不会发生)。

如 cmets 中所述——大多数内核运行时错误会导致上下文破坏,因此如果您从第一个内核收到错误,则第二个内核将中止或拒绝运行,这可能对您的整个应用程序来说是致命的。

【讨论】:

    猜你喜欢
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2021-05-12
    • 1970-01-01
    • 2020-08-11
    相关资源
    最近更新 更多