CUDA:设备序号无效

Ste*_*fan 8 cuda

我有以下问题。我想让我的用户选择在哪个 GPU 上运行。所以我在我只有一个 GPU(设备 0)的机器上测试如果他们选择了一个不存在的设备会发生什么。

如果我这样做,cudaSetDevice(0);它会工作得很好。

如果我这样做:cudaSetDevice(1);它会崩溃invalid device ordinal(我可以处理这个,因为函数返回错误)。

如果我这样做:cudaSetDevice(0); cudaSetDevice(1);它会崩溃invalid device ordinal(我可以处理这个,因为函数返回错误)。

然而!如果我这样做:cudaSetDevice(1); cudaSetDevice(0);第二个命令返回成功,但在第一次计算时我尝试在我的 GPU 上计算它会崩溃invalid device ordinal。我无法处理这个,因为第二个命令没有返回错误!

在我看来,第一个 cudaSetDevice 会留下一些影响第二个命令的东西?

非常感谢!

解决方案:(感谢罗伯特·克罗维拉!)。我正在处理以下错误:

error = cudaSetDevice(1); 
if (error) { blabla }
Run Code Online (Sandbox Code Playgroud)

但显然你需要在 cudaSetDevice(1) 之后调用 cudaGetLastError() 因为否则错误消息不会从某些错误堆栈中删除并且它只是在我为另一个函数执行 cudaGetLastError() 的地方崩溃,即使没有错误这点。

hub*_*ubs 7

您必须首先检查系统中可用的 GPU 数量。可以通过使用cudaGetDeviceCount.

int deviceCount = 0;
cudaGetDeviceCount(&deviceCount);
Run Code Online (Sandbox Code Playgroud)

然后检查用户输入是否大于可用设备。

if (userDeviceInput < deviceCount)
{
  cudaSetDevice(userDeviceInput);
}
else
{
  printf("error: invalid device choosen\n");
}
Run Code Online (Sandbox Code Playgroud)

提醒一下,这cudaSetDevice是基于 0 索引的!因此我检查userDeviceInput < deviceCount

  • 如果你展示一个*完整*的例子,它会有所帮助。您的错误检查可能使用了`cudaPeekAtLastError()`,它*不*清除错误代码。它返回最后一个错误 - 每次您要求它时(例如在您的内核启动之后)。相反,`cudaGetLastError()` 将清除它返回的错误(即未来的检查将不再返回该错误,如果没有新的错误发生,它将返回 `cudaSuccess`)。这与 API 返回错误代码不同。如果您希望内核启动不会失败,请在它之前的某处执行 `cudaGetLastError`,但在非法的 `cudaSetDevice(1)` 调用之后。 (3认同)