3

与运行时 API 函数等效的 CUDA 驱动程序 API 是cudaSetDevice什么?

我正在研究驱动程序 API,但找不到等效函数。我能做的是

cuDeviceGet(&cuDevice, device_no);
cuCtxCreate(&cuContext, 0, cuDevice);

这是不等价的,因为除了设置设备之外,它还创建了一个上下文。运行时 APIcudaSetDevice本身不会创建上下文。在运行时 API 中,CUDA 上下文是使用第一个需要设备状态的 CUDA 调用隐式创建的。

这个问题的背景:CUDA-aware MPI (MVAPICH2 1.8/9) 初始化需要在MPI_init调用之前设置 CUDA 设备。使用 CUDA 运行时 API,这可以通过

cudaSetDevice(device_no);
MPI_init();

但是,我不想使用对 CUDA 运行时的调用,因为我的应用程序的其余部分纯粹使用驱动程序 API,并且我想避免也链接到运行时。

在 MPI 初始化之前创建上下文有什么问题?原则上什么都没有。只是想知道驱动程序 API 中是否有等效调用。

4

2 回答 2

5

您可以在有关驱动程序 API 的编程指南附录中找到相关信息,但简短版本如下:

  • cuCtxCreate充当第一个 cudaSetDevice调用(即它在驱动程序上下文堆栈上创建一个上下文)
  • cuCtxPushCurrent()andcuCtxPopCurrent()对(或取决于您使用的cuCtxSetCurrentAPI 版本)充当任何后续cudaSetDevice调用(即它推送或选择先前创建的上下文作为所有后续 API 调用的活动上下文,直到上下文从驱动程序上下文堆栈中弹出或取消选择)
于 2013-08-19T20:28:56.200 回答
0

实际上,cudaSetDevice()并不完全像创建来检索上下文一样,就好像cuCtxCreate()被调用了一样。它非常相似,但是CUDA 运行时 API 使用了一个特殊的上下文。此上下文称为设备的主要上下文。有特定的驱动程序 API 函数可用于处理此特殊上下文:

CUresult cuDevicePrimaryCtxGetState ( CUdevice dev, unsigned int* flags, int* active );
CUresult cuDevicePrimaryCtxRelease ( CUdevice dev );
CUresult cuDevicePrimaryCtxReset ( CUdevice dev );
CUresult cuDevicePrimaryCtxRetain ( CUcontext* pctx, CUdevice dev );
CUresult cuDevicePrimaryCtxSetFlags ( CUdevice dev, unsigned int  flags );

那么,为什么要实现 的等价物cudaSetDevice(),这将涉及(忽略错误检查)类似:

CUcontext* primary_context;
cuDevicePrimaryCtxRetain(&primary_context, device_id);
cuCtxSetCurrent(primary_context);

笔记:

  • 您应该在某个时候调用 Release 函数以减少引用计数;但是 - 在没有设置另一个当前上下文的情况下不要这样做。
  • 您可以替换-替换-替换当前上下文,或者推送然后最终从上下文堆栈中弹出当前上下文。替换工作在堆栈的顶部(所以它就像弹出,然后推送)。
于 2021-11-15T19:56:23.677 回答