【CUDA编程】【15】【3.Programming Interface】【3.2.CUDA Runtime】【3.2.12.Error Checking】

Error Checking

Posted by x-jeff on December 8, 2024

【CUDA编程】系列博客参考NVIDIA官方文档“CUDA C++ Programming Guide(v12.6)”
本文为原创文章,未经本人允许,禁止转载。转载请注明出处。

1.Error Checking

同步函数在任务完成后才返回,这意味着host可以在函数返回时确信任务已经成功或失败。异步函数(见:Asynchronous Concurrent Execution)会在任务开始后立即返回,而不会等待任务完成。host无法在函数返回时直接知道任务是否成功完成。如果device上发生了异步错误(例如kernel在执行过程中出现非法内存访问),host端在调用异步函数时并不会立即得知该错误。这些错误会被推迟到后续某个CUDA API调用(可能与错误的任务毫无关联)时才被报告。

因此,唯一可以检查异步错误的方法是在异步函数调用之后立即通过调用cudaDeviceSynchronize()(或使用Asynchronous Concurrent Execution中介绍的其他同步机制)进行同步,并检查由cudaDeviceSynchronize()返回的错误码。

运行时为每个host线程维护一个错误变量,该变量被初始化为cudaSuccess,每次发生错误(无论是参数验证错误还是异步错误)时都会被新的错误码所覆盖。cudaPeekAtLastError()返回该变量,而cudaGetLastError()返回该变量并将其重置为cudaSuccess

kernel启动不会返回任何错误码,因此需要在kernel启动后立即调用cudaPeekAtLastError()cudaGetLastError()来检索任何启动前的错误。为了确保由cudaPeekAtLastError()cudaGetLastError()返回的任何错误不是在kernel启动之前调用其他函数引起的,应在kernel启动前调用cudaGetLastError()将运行时错误变量设置为cudaSuccess。如果直接在kernel启动之后调用cudaPeekAtLastError()cudaGetLastError(),host线程可能无法捕获device上发生的错误,因为此时kernel任务可能还未完成。在调用cudaPeekAtLastError()cudaGetLastError()之前,必须确保device上的kernel任务已经完成,因此需要使用cudaDeviceSynchronize()等同步机制。

注意,由cudaStreamQuery()cudaEventQuery()返回的cudaErrorNotReady不被视为错误,因此不会被cudaPeekAtLastError()cudaGetLastError()报告。