【问题标题】:CUDA: How to assert in kernel code?CUDA:如何在内核代码中断言?
【发布时间】:2011-07-04 02:54:58
【问题描述】:

CUDA 内核代码中断言的等效技术是什么?

CUDA 内核代码似乎没有断言。我想要一种在内核代码中轻松捕捉程序员错误的方法。一种机制,我可以设置需要为真的条件,当条件为假并显示错误消息时,内核应该退出。

【问题讨论】:

  • 你能在仿真模式下断言吗?
  • jmilloy:CUDA 3.x 不支持仿真模式。
  • 对于任何像我一样通过 Google 遇到此问题的人,现在可以在内核代码中断言: docs.nvidia.com/cuda/cuda-c-programming-guide/…
  • @Sam,您为什么不将此作为答案发布?很难注意到评论:其他答案会分散注意力。
  • @SergeRogatch Here 这是一个答案,但即使这样也不是被接受的!我认为旧问题的问题需要新的答案。

标签: assertion cuda


【解决方案1】:

对于 cc 2.x 或更高版本的设备,assertionvoid assert(int expression) 可以在内核中使用,这样一旦调用主机同步函数,带有expression == 0 的线程就会向 stderr 发送消息。

对于其他情况或无法使用断言时(例如在 MacOS 上),您将无法从内核向主机返回错误消息或错误代码。

相反,我会设置一个错误状态并从主机检查它。使用设备全局内存或(更好的)映射主机内存来存储错误状态,作为参数传递给每个内核调用。在内核中使用 if 语句,如果语句失败,则设置错误代码并返回。您将能够在内核调用后从主机检查错误代码,但请记住,您将在内核启动后同步主机和设备,然后再检查错误代码。我想这对于开发来说会很好,但对于生产来说就不行了。

关于直接从设备打印错误消息

  • 在 1.x、2.x 和 3.0 卡中,您可以使用仿真模式打印错误消息。
  • 在 3.1 版本中(在 fermi 上),显然您可以在内核中使用 printf 来打印错误消息。似乎它并不总是立即起作用,例如http://forums.nvidia.com/index.php?showtopic=182448

【讨论】:

    【解决方案2】:

    我想指出一个断言可能只发生在一个线程中,但是如果您决定提前终止该线程,它的缺失可能会导致其他错误(可能还有其他断言)稍后发生;可能导致内核完全崩溃并丢失 GPU 上的所有信息。

    此外,“Using assert within kernel invocation”给出的答案只有在断言直接在 __ global__ 函数中使用而不是在 __ device__ 函数内部某处更深的情况下才有效。

    我的建议是,即使断言失败,您也可以正常处理您的代码,但会留下错误消息。您可以使用映射的固定内存(将主机 RAM 内存映射到 GPU 地址空间)来存储错误代码/消息。这样,即使您的内核崩溃并且 GPU 被重置,您也可能会在该映射内存中获得有价值的信息。 如果我没记错的话,几乎所有 Compute Capability 1.1 及更高版本的设备都支持映射、固定内存。

    【讨论】:

      【解决方案3】:

      您可能会发现这很有帮助:

      Using assert within kernel invocation

      或者,您可以使用 cudaThreadSynchronize() 捕获cudaError,它为您提供了内核返回错误的大约 40 种不同原因之一。但大多数情况下,您可以使用内核中的 if/else 命令检查这些条件。

      【讨论】:

      • Jawad:在断言失败时从内核返回并不是很有用。但是,使用 printf() 很有用。谢谢! :-)
      • @Ashwin - 好吧,你不能从内核 printf 并且没有办法解决这个问题。
      • 你能在内核中将 cudaError 设置为自定义值吗?
      • Fermi 允许在内核中使用 printf。除此之外,您可以制作自定义枚举并返回任意数量的不同错误。
      猜你喜欢
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 2022-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多