cuda异常后内存数据的状态

States of memory data after cuda exceptions

CUDA 文档没有明确说明 CUDA 应用程序抛出异常后内存数据如何变化。

例如,内核启动(动态)遇到异常(例如 Warp Out-of-range Address),当前内核启动将停止。在此之后,设备上的数据(例如 __device__ 变量)是否仍会保留或与异常一起被删除?

一个具体的例子是这样的:

  1. CPU 启动内核
  2. 内核更新__device__变量A的值为5然后崩溃
  3. CPU memcpy 从设备到主机的 variableA 的值,在这种情况下 CPU 得到的值是多少,5 还是其他值?

有人可以说明这背后的基本原理吗?

如果出现破坏 CUDA 上下文的 CUDA 错误,则行为未定义。

这种类型的错误很明显,因为它是 "sticky",这意味着一旦它发生,每个 CUDA API 调用都会 return 该错误,直到上下文被破坏。

非粘性错误在被 cuda API 调用 return 后自动清除(cudaPeekAtLastError 除外)。任何 "crashed kernel" 类型错误(无效访问、未指定的启动失败等)都将是粘性错误。在您的示例中,第 3 步将(总是)return cudaMemcpy 调用的结果出现 API 错误,以将变量 A 从设备传输到主机,因此 cudaMemcpy 操作未定义且不可靠——就好像 cudaMemcpy 操作也以某种未指定的方式失败了。

由于损坏的 CUDA 上下文的行为是未定义的,因此没有任何分配内容的定义,或者通常在此类错误后机器的状态。

非粘性错误的一个示例可能是尝试 cudaMalloc 比设备内存中可用的数据更多的数据。这样的操作将 return 内存不足错误,但该错误将在 returned 后被清除,后续(有效)cuda API 调用可以成功完成,无需 return出错了。非粘性错误不会破坏 CUDA 上下文,并且 cuda 上下文的行为与从未请求过无效操作完全相同。

粘性和非粘性错误之间的区别在许多已记录的错误代码 descriptions 中都有提及,例如:

非粘性、非 cuda 上下文损坏:

cudaErrorMemoryAllocation = 2 The API call failed because it was unable to allocate enough memory to perform the requested operation.

粘性,cuda 上下文损坏:

cudaErrorMisalignedAddress = 74 The device encountered a load or store instruction on a memory address which is not aligned. The context cannot be used, so it must be destroyed (and a new one should be created). All existing device memory allocations from this context are invalid and must be reconstructed if the program is to continue using CUDA.

请注意,cudaDeviceReset() 本身不足以将 GPU 恢复到正常的功能行为。为了实现这一点,"owning" 进程也必须终止。参见 here