CUDA 流是不是与设备相关?以及如何获得流的设备?
Posted
技术标签:
【中文标题】CUDA 流是不是与设备相关?以及如何获得流的设备?【英文标题】:Are CUDA streams device-associated? And how do I get a stream's device?CUDA 流是否与设备相关?以及如何获得流的设备? 【发布时间】:2015-10-07 02:43:26 【问题描述】:我有一个 CUDA 流,有人交给我 - 一个 cudaStream_t
值。 CUDA Runtime API 似乎没有表明我如何获取与此流关联的设备的索引。
现在,我知道cudaStream_t
只是一个指向驱动程序级流结构的指针,但我不愿过多地深入研究驱动程序。有没有一种惯用的方法来做到这一点?还是有什么不想做的充分理由?
编辑:这个问题的另一个方面是流是否真的与设备相关联,在这种方式下,CUDA 驱动程序本身可以在给定指向结构的情况下确定设备的身份。 p>
【问题讨论】:
我不是 CUDA 驱动专家,也没有多 GPU 编程的实践经验。但我希望每个 CUDA 流都特定于特定的 CUDA 上下文。我还希望每个 GPU 都有自己的 CUDA 上下文。这意味着 CUDA 流句柄在设备之间不是唯一的,只是对于每个给定的设备都是唯一的。因此,您可能需要在应用中传递一对 device number, stream handle。 @njuffa:如果 CUDA 流是特定于上下文的,并且如果上下文是特定于设备的,这是否意味着 CUDA 流句柄是跨设备唯一的?也许我没有关注你…… 跨所有设备的唯一流句柄意味着流句柄的全局“命名空间”。我认为不存在。因此,如果您假设有两个 GPU,每个都有自己的上下文。在每个上下文中创建的第一个流可能会获得句柄值 1。有人将值为 1 的流句柄传递给您的代码。它属于哪个设备?我们不知道。 @njuffa:cudaStream_t
s 是指向结构的指针,而不是整数句柄(如 CUDA 设备标识符)。是什么让您相信这些不是唯一的句柄?
@RobertCrovella 够公平的。
【参考方案1】:
关于显式流,这取决于实现(据我所知)没有 API 向用户提供这种潜在的查询能力;我不知道驱动程序在这方面可以为您提供哪些功能,但是您始终可以查询流。
通过使用cudaStreamQuery,您可以在您选择的设备上查询您的目标流,如果返回cudaSuccess或cudaErrorNotReady,则表示该流该设备上确实存在,如果它返回 cudaErrorInvalidResourceHandle,则表示它不存在。
【讨论】:
在选择设备 n' 的情况下查询来自设备 n 的流时,我能保证获得 cudaErrorNotReady 吗? 如果您选择的设备恰好存在正在查询的流,则肯定会返回 cudaStreamQuery 或 cudaErrorNotReady 之一。前者表明对关联流的所有操作都已完成,而后者表明未完成;无论如何,两者中的任何一个都表明流存在。如果您在流上得到 cudaErrorInvalidResourceHandle,则意味着该流根本不存在。 但是流可以“存在”在两个设备上吗?更具体地说,假设在内部,流值只是其设备流数组的索引。因此,流 0 将始终存在于所有设备上。我会从所有具有该 cudaStream_t 的 GPU 获得 cudaSucces 吗? ping...关于我的最后一条评论。【参考方案2】:是的,流是特定于设备的。
在 CUDA 中,流特定于上下文,而上下文特定于设备。
现在,使用运行时 API,您不会“看到”上下文 - 每个设备只使用一个上下文(这是一个好主意,因为上下文很昂贵)。但是如果你考虑驱动 API - 你have:
CUresult cuStreamGetCtx ( CUstream hStream, CUcontext* pctx );
CUstream
和 cudaStream_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());
不必担心。 (当然上面的sn -p是针对至少有2个CUDA设备的系统,否则没有index为1的设备……)
【讨论】:
刚开始使用 CUDA,哇,API 的一些遗留方面令人痛苦。您完全希望流能够告诉您它来自哪个设备,但它不存在。还有 NppStreamContext,它是你必须使用 NPP 的流,但需要像 8 个结构字段一样手动初始化。包括设备。当我拿着流。感谢您开始并继续开发我希望 NVIDIA 提供的库:-)。 哈哈,我不知道——NPP不流行了吗?如果您想在 GPU 上进行常见操作(例如向图像添加通道或调整图像大小)但又不习惯编写自己的内核,您会使用什么?不幸的是,我在 nVidia 不认识任何人,但如果有机会,我仍然会提倡。 @aggieNick02:啊,好吧,你正在处理图像。别管我的评论,我把 NPP 误认为是别的东西了。以上是关于CUDA 流是不是与设备相关?以及如何获得流的设备?的主要内容,如果未能解决你的问题,请参考以下文章