我看过很多针对特定案例特定问题的具体帖子,但没有基本的激励解释。这个错误是什么:
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 许可协议
当 CUDA 设备代码运行时检测到设备端错误时,该错误将通过通常的 CUDA 运行时 API 错误报告机制报告。通常在设备代码中检测到的错误类似于非法地址(例如,尝试解除对无效指针的引用),但另一种类型是设备端断言。每当设备代码中出现 C/C++
assert()
并且断言条件为假时,就会生成此类错误。此类错误是由特定内核引起的。 CUDA 中的运行时错误检查必然是异步的,但可能至少有 3 种可能的方法可以开始对此进行调试。
修改源代码以有效地将异步内核启动转换为同步内核启动,并在每次内核启动后进行严格的错误检查。这将识别导致错误的特定内核。此时,只需查看该内核代码中的各种断言可能就足够了,但您也可以使用下面的步骤 2 或 3。
使用
cuda-memcheck
运行您的代码。这是一个类似于“设备代码的 valgrind”的工具。当您使用cuda-memcheck
运行代码时,它的运行速度往往会慢得多,但运行时错误报告会得到增强。通常最好使用-lineinfo
编译代码。在这种情况下,当触发设备端断言时,cuda-memcheck
将报告断言所在的源代码行号,以及断言本身和为假的条件。您可以 在此处 查看使用它的演练(尽管有非法地址错误而不是assert()
,但assert()
的过程将是相似的。也应该可以使用调试器。如果您使用诸如
cuda-gdb
之类的调试器(例如在 Linux 上),则调试器将具有回溯报告,该报告将指示断言所在的行,何时被命中。如果从 python 脚本启动 CUDA 代码,则可以使用
cuda-memcheck
和调试器。至此,您已经发现了断言是什么以及它在源代码中的位置。为什么它在那里不能一般地回答。这将取决于开发人员的意图,如果它没有被注释或以其他方式显而易见,您将需要一些方法以某种方式凭直觉来判断。 “如何向后工作”的问题也是一个通用的调试问题,并非特定于 CUDA。您可以在 CUDA 内核代码中使用
printf
以及像cuda-gdb
这样的调试器来协助解决这个问题(例如,在断言之前设置断点,并检查机器状态 - 例如变量- 当断言即将被击中时)。使用更新的 GPU,而不是
cuda-memcheck
你可能想要使用compute-sanitizer
。它以 类似的方式 工作。