PyTorch 中的“RuntimeError: CUDA error: device-side assert triggered”是什么意思?

新手上路,请多包涵

我看过很多针对特定案例特定问题的具体帖子,但没有基本的激励解释。这个错误是什么:

 RuntimeError: CUDA error: device-side assert triggered

意思?具体来说,触发的断言是什么,断言为什么在那里,我们如何反向工作来调试问题?

照原样,此错误消息在诊断任何问题时几乎没有用,因为它似乎在说“某处接触 GPU 的某些代码”有问题。 Cuda 的文档在这方面似乎也没有帮助,尽管我可能是错的。 https://docs.nvidia.com/cuda/cuda-gdb/index.html

原文由 Joseph Konan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

当 CUDA 设备代码运行时检测到设备端错误时,该错误将通过通常的 CUDA 运行时 API 错误报告机制报告。通常在设备代码中检测到的错误类似于非法地址(例如,尝试解除对无效指针的引用),但另一种类型是设备端断言。每当设备代码中出现 C/C++ assert() 并且断言条件为假时,就会生成此类错误。

此类错误是由特定内核引起的。 CUDA 中的运行时错误检查必然是异步的,但可能至少有 3 种可能的方法可以开始对此进行调试。

  1. 修改源代码以有效地将异步内核启动转换为同步内核启动,并在每次内核启动后进行严格的错误检查。这将识别导致错误的特定内核。此时,只需查看该内核代码中的各种断言可能就足够了,但您也可以使用下面的步骤 2 或 3。

  2. 使用 cuda-memcheck 运行您的代码。这是一个类似于“设备代码的 valgrind”的工具。当您使用 cuda-memcheck 运行代码时,它的运行速度往往会慢得多,但运行时错误报告会得到增强。通常最好使用 -lineinfo 编译代码。在这种情况下,当触发设备端断言时, cuda-memcheck 将报告断言所在的源代码行号,以及断言本身和为假的条件。您可以 在此处 查看使用它的演练(尽管有非法地址错误而不是 assert() ,但 assert() 的过程将是相似的。

  3. 也应该可以使用调试器。如果您使用诸如 cuda-gdb 之类的调试器(例如在 Linux 上),则调试器将具有回溯报告,该报告将指示断言所在的行,何时被命中。

如果从 python 脚本启动 CUDA 代码,则可以使用 cuda-memcheck 和调试器。

至此,您已经发现了断言是什么以及它在源代码中的位置。为什么它在那里不能一般地回答。这将取决于开发人员的意图,如果它没有被注释或以其他方式显而易见,您将需要一些方法以某种方式凭直觉来判断。 “如何向后工作”的问题也是一个通用的调试问题,并非特定于 CUDA。您可以在 CUDA 内核代码中使用 printf 以及像 cuda-gdb 这样的调试器来协助解决这个问题(例如,在断言之前设置断点,并检查机器状态 - 例如变量- 当断言即将被击中时)。

使用更新的 GPU,而不是 cuda-memcheck 你可能想要使用 compute-sanitizer 。它以 类似的方式 工作。

原文由 Robert Crovella 发布,翻译遵循 CC BY-SA 4.0 许可协议

当我将代码转移到 CPU 而不是 GPU 上工作时,出现以下错误:

IndexError: index 128 is out of bounds for dimension 0 with size 128

因此,也许代码中可能存在错误,出于某种奇怪的原因,该错误会作为 CUDA 错误出现。

原文由 Hrushi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题