CUDA流设备是否关联?我如何获得一条流';谁的设备?

CUDA流设备是否关联?我如何获得一条流';谁的设备?,cuda,multi-gpu,Cuda,Multi Gpu,我有一个CUDA流,有人递给我-一个cudaStream\u t值。似乎没有指示如何获取与此流关联的设备的索引 现在,我知道cudaStream\u t只是一个指向驱动程序级流结构的指针,但我不太愿意深入研究驱动程序。有没有一种惯用的方法可以做到这一点?或者有什么好的理由不想这么做 编辑:这个问题的另一个方面是,流是否真的与设备相关联,CUDA驱动程序本身是否能够根据指向结构确定设备的身份。关于显式流,这取决于实现(据我所知)没有API向用户提供这种潜在的查询功能;我不知道驱动程序在这方面可以为

我有一个CUDA流,有人递给我-一个
cudaStream\u t
值。似乎没有指示如何获取与此流关联的设备的索引

现在,我知道
cudaStream\u t
只是一个指向驱动程序级流结构的指针,但我不太愿意深入研究驱动程序。有没有一种惯用的方法可以做到这一点?或者有什么好的理由不想这么做


编辑:这个问题的另一个方面是,流是否真的与设备相关联,CUDA驱动程序本身是否能够根据指向结构确定设备的身份。

关于显式流,这取决于实现(据我所知)没有API向用户提供这种潜在的查询功能;我不知道驱动程序在这方面可以为您提供什么功能,但是,您可以随时查询流

通过使用cudaStreamQuery,您可以在所选设备上查询目标流,如果它返回cudaSuccess或cudaErrorNotReady,则表示该设备上确实存在该流,如果它返回cudaErrorInvalidResourceHandle,则表示不存在该流

是的,流是特定于设备的。 在CUDA中,流特定于上下文,而上下文特定于设备

现在,使用运行时API,您不需要“查看”上下文——每个设备只使用一个上下文(这是一个不错的想法,因为上下文很昂贵)。但是如果你考虑驱动程序API——你:

CUstream
cudaStream\t
是一个指针。因此,您可以获得上下文。然后,设置或推送该上下文为当前上下文(请阅读其他地方的相关内容),最后,使用:

CUresult cuCtxGetDevice ( CUdevice* device ) 
获取当前上下文的设备

所以,有点麻烦,但很可行


轻松确定流设备的方法 我的解决方法是将设备作为成员变量,这意味着您可以编写:

auto my_device = cuda::device::get(1);
auto my_stream = my_device.create_stream(); /* using some default param values here */
assert(my_stream.device() == my_device());

不用担心。(当然,上面的代码片段适用于至少有2个CUDA设备的系统,否则没有索引为1的设备…

我不是CUDA驱动程序专家,也没有多GPU编程的实际经验。但我希望每个CUDA流都特定于特定的CUDA上下文。我还希望每个GPU都有自己的CUDA上下文。这意味着CUDA流句柄在设备之间不是唯一的,只是对于每个给定的设备是唯一的。因此,您可能需要在应用程序中传递一对{device number,stream handle}。@njuffa:如果CUDA流是特定于上下文的,而上下文是特定于设备的,这不意味着CUDA流句柄在设备之间是唯一的吗?也许我没有听你说……跨所有设备的唯一流句柄意味着流句柄有一个全局“命名空间”。我认为这是不存在的。因此,如果假设有两个GPU,每个GPU都有自己的上下文。在每个上下文中创建的第一个流可能会获得句柄值1。有人将值为1的流句柄传递给您的代码。它属于哪个设备?我们不知道。@njuffa:
cudaStream\u t
s是指向结构的指针,而不是整数句柄(如CUDA设备标识符)。是什么让你相信这些是非唯一句柄?@RobertCrovella很公平。在选择了设备n'的情况下查询设备n的流时,我保证从该设备n获取CudaErrorNoReady吗?如果所选设备n恰好存在一个cudaStreamQuery或CudaErrorNoReady,则将为正在查询的流返回其中一个装置。前者表明关联流的所有操作都已完成,而后者则表明未完成;无论如何,这两种方法中的任何一种都表明流存在。如果您在一个流上获得cudaErrorInvalidResourceHandle,则表示该流根本不存在。但是,该流能否在两个设备上“存在”?更具体地说,假设在内部,流值只是其设备流数组的索引。因此,流0将始终存在于所有设备上。我会从所有GPU获得CUDASUCCESS吗。。。关于我的最后一条评论。从CUDA开始,哇,API的一些遗留方面令人痛苦。您完全可以期望流能够告诉您它来自哪个设备,但它并不存在。还有NppStreamContext,这是您必须用于具有NPP的流的内容,但需要手动初始化,如8个结构字段。包括设备。当我拿着一条小溪。感谢您开始并继续致力于我希望NVIDIA提供的库:-)。哈哈,我不知道-NPP不受欢迎吗?如果您想在GPU上执行常见操作(例如为图像添加通道或调整图像大小),但还不习惯编写自己的内核,您会使用什么?不幸的是,我在nVidia不认识任何人,但如果有任何机会,我仍然会支持。@aggieNick02:啊,好吧,你在做图像方面的工作。别介意我的评论,我把核电站错当成了别的东西。
auto my_device = cuda::device::get(1);
auto my_stream = my_device.create_stream(); /* using some default param values here */
assert(my_stream.device() == my_device());