CUDA 流与设备相关吗?如何获取流的设备?

ein*_*ica 6 cuda multi-gpu cuda-streams

我有一个 CUDA 流,有人递给我 - 一个cudaStream_t值。CUDA运行时 API似乎没有指示我如何获取与该流关联的设备的索引。

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

编辑:这个问题的另一个方面是流是否确实与设备相关联,在这种方式中,CUDA 驱动程序本身可以根据给定的指向结构确定设备的标识。

ein*_*ica 2

是的,流是特定于设备的。

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

现在,使用运行时 API,您不会“看到”上下文 - 每个设备仅使用一个上下文。但如果你考虑驱动程序 API - 你会得到

CUresult cuStreamGetCtx ( CUstream hStream, CUcontext* pctx );
Run Code Online (Sandbox Code Playgroud)

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

CUresult cuCtxGetDevice ( CUdevice* device ) 
Run Code Online (Sandbox Code Playgroud)

获取当前上下文的设备。

所以,虽然有点麻烦,但还是可行的。


我轻松确定流设备的方法

我针对此问题的解决方法是让(C++ 风格)流包装类将(上下文句柄和)设备 ID 作为流包装对象的成员变量,这意味着您可以编写:

auto my_device = cuda::device::get(1);
auto my_stream = my_device.create_stream();
assert(my_stream.device() == my_device());
Run Code Online (Sandbox Code Playgroud)

并且不必担心它(+它不会触发额外的 API 调用,因为在构造时,我们知道当前上下文是什么以及它的设备是什么)。

注意:上面的代码片段适用于至少有两个 CUDA 设备的系统,否则不存在索引为 1 的设备...