CUDA 流是否与设备关联?我如何获得流的设备?

Are CUDA streams device-associated? And how do I get a stream's device?

我有一个有人交给我的 CUDA 流 - cudaStream_t 值。 CUDA Runtime API 似乎没有说明如何获取与此流关联的设备的索引。

现在,我知道 cudaStream_t 只是一个指向驱动程序级流结构的指针,但我对深入研究驱动程序犹豫不决。有没有惯用的方法来做到这一点?或者有什么好的理由不想这样做?

编辑: 这个问题的另一个方面是,流是否真的以某种方式与设备相关联,CUDA 驱动程序本身可以在给定指向的情况下确定该设备的身份 -结构。

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

通过使用 cudaStreamQuery,您可以在您选择的设备上查询目标流,如果 returns cudaSuccesscudaErrorNotReady 这意味着流确实存在于该设备上,如果它 returns cudaErrorInvalidResourceHandle,则意味着它不存在。

是的,流是 device-specific。

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

现在,使用运行时 API,您不会“看到”上下文 - 每个设备只使用一个上下文(这是一个不错的想法,因为上下文很昂贵)。但是如果你考虑 driver API - 你 have:

CUresult cuStreamGetCtx ( CUstream hStream, CUcontext* pctx );

CUstreamcudaStream_t 是同一件事 - 一个指针。所以,你可以得到上下文。然后,您将该上下文设置或推送为当前上下文(阅读其他地方的相关信息),最后,您使用:

CUresult cuCtxGetDevice ( CUdevice* device ) 

获取当前上下文的设备。

所以,有点麻烦,但非常可行。


我轻松确定流设备的方法

我解决此问题的方法是 the (C++'ish) stream wrapper class 将设备保留为成员变量,这意味着您可以编写:

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的设备...)