【问题标题】:CUDA: invalid device ordinalCUDA:无效的设备序号
【发布时间】:2014-03-04 15:16:45
【问题描述】:

我有以下问题。我想让我的用户选择在哪个 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 留下了一些影响第二个命令的东西?

非常感谢!

解决方案:(感谢 Robert Crovella!)。 我正在处理以下错误:

error = cudaSetDevice(1); 
if (error) { blabla }

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

【问题讨论】:

    标签: cuda


    【解决方案1】:

    您必须首先检查系统中有多少 GPU 可用。可以使用cudaGetDeviceCount

    int deviceCount = 0;
    cudaGetDeviceCount(&deviceCount);
    

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

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

    提醒cudaSetDevice是0-index-based!因此我检查userDeviceInput &lt; deviceCount

    【讨论】:

    • 是的,这是避免它的好方法。我想知道为什么它不起作用。
    • 如果你展示一个完整的例子会很有帮助。您的错误检查可能使用了cudaPeekAtLastError(),它不会清除错误代码。它返回最后一个错误 - 每次你要求它时(比如在你的内核启动之后)。相反,cudaGetLastError() 将清除它返回的错误(即,未来的检查将不再返回该错误,如果没有发生新错误,它将返回 cudaSuccess)。这与 API 返回错误代码不同。如果您希望内核启动不会失败,请在它之前的某个位置执行cudaGetLastError,但在非法的cudaSetDevice(1) 调用之后。
    • 我应该说“如果您希望内核启动不出现失败...”
    • @Robert,您可以将此作为答案发布,以便我接受吗?因为你显然是正确的 :) 非常感谢!
    • 我相信集线器的回答加上我的评论会得到很好的回应。如果你愿意,欢迎你接受。仅我的评论,如果没有您实际显示您正在详细执行的错误检查类型,可能没有多大意义。我们已经可以看到我的评论是错误的,因为您没有使用cudaPeekAtLastError。您的问题缺乏清晰的示例,因此任何人都难以回答。
    猜你喜欢
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多