我再次继承了看起来可疑的代码;基本上是这样的:
(void) nppiFilter...(...);
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
{
std::cerr << cudaGetErrorString(err);
}我们忽略NPP错误,而是检查CUDA错误。
首先,NPP是否将CUDA错误标志设置为错误?我很确定答案是“没有显式的”,所以这段代码将错过NPP唯一的错误,但我想检查一下。
第二,是否有必要检查这两个错误,还是这足以:
NppStatus nppErr = nppiFilter...(...);
if (nppErr != NPP_NO_ERROR)
{
std::cerr << "NPP error " << nppErr;
}还是我应该检查一下以防万一?有一个NPP_CUDA_KERNEL_EXECUTION_ERROR告诉我,也许检查cudaGetLastError()是有用的,但它是吗?
发布于 2018-05-22 01:09:45
首先,NPP是否将CUDA错误标志设置为错误?
不,不需要。CUDA错误状态可以由NPP执行的内容设置,但NPP没有专门设置CUDA错误状态。
还是我应该检查一下以防万一?
只要检查NPP的状态就足够了。但是,如果您想要进行额外的调试分析,也检查CUDA错误状态可能是有用的。事实上,当我寻找更多的线索时,我经常运行cuda-memcheck。唯一正常的价值是提供“额外的线索”。
一个安全的假设是,许多CUDA库可能具有异步启动工作的功能。也就是说:即使在函数将控制权返回给CPU线程之后,底层GPU活动仍可能发生。在这种情况下,预期是设计良好的库在执行后续库调用或CUDA API调用(可能是从设备到主机检索计算的数据)时,“稍后”会捕获由于异步活动而产生的错误。
在这种情况下,无论如何您都无法依赖函数返回值。因此,在整个程序中仔细检查错误是最安全的选择,这包括库API级别(例如NPP)和CUDA API级别。但出于生产目的,我只是在每一次机会时进行测试,不一定建议您插入额外的检查,例如:
error = cudaGetLastError();(除非它立即遵循CUDA API调用,这是您的策略**)
我也不建议任意插入:
error = cudaDeviceSynchronize();但是,如果您正在设计一个库,您可能希望在函数的条目中对上述类型进行某种显式错误检查。
这显然是某种程度上的意见问题。您可能希望进行错误检查到一个极端的水平。只要您不插入同步调用以检查错误,它就不会对您的程序产生太大影响。
我上面的评论主要是关于我将如何编写生产代码。为了学习的目的,或者当您在编写代码时遇到问题时,通常最好是使用very rigorous about error checking,并插入额外的错误检查以捕获异步错误,以便将错误定位到特定的函数。
**你不妨插入:
error = cudaGetLastError();在每次内核调用之后,在代码中。这将捕获在启动时可以检测到的任何内核错误,例如不正确的网格尺寸。这种类型的调用应该相对轻量级。
https://stackoverflow.com/questions/50458216
复制相似问题