CUDA Runtime的current device与驱动上下文栈的交互机制是什么?
CUDA Runtime 与 Driver API 的状态交互规则
CUDA Runtime 有「当前设备」的概念,而 CUDA Driver 没有对应的设备概念,驱动侧采用上下文栈结构,栈顶的就是「当前上下文」,所有驱动API调用默认作用在当前上下文上。
1. 修改 Runtime 当前设备对驱动侧的影响
- Runtime 内部会为每个物理设备维护一个主上下文(Primary Context),这个上下文由 Runtime 托管,采用引用计数式生命周期管理,所有 Runtime API 默认都作用在当前设备对应的主上下文上。
- 调用
cudaSetDevice(设备ID)切换 Runtime 当前设备时,Runtime 底层会自动把新设备对应的主上下文设置为驱动上下文栈的栈顶,也就是驱动侧的当前上下文。如果该设备的主上下文还未初始化,Runtime 会自动完成初始化操作。 - 只要你没有手动操作过驱动上下文栈,Runtime 的当前设备对应的主上下文,永远和驱动侧的当前上下文保持一致。
2. 驱动API调用对 Runtime 当前设备的影响
分两种情况讨论:
- 如果你的驱动API操作的是 Runtime 托管的主上下文:比如你通过
cuCtxSetCurrent()或者cuCtxPushCurrent()把设备Y的主上下文设为驱动侧当前上下文,此时调用任何 Runtime API,Runtime 都会自动检测到当前激活的主上下文对应的设备ID,把自身的当前设备更新为Y。 - 如果你的驱动API操作的是自己通过
cuCtxCreate()创建的自定义上下文:Runtime 会忽略这类非托管上下文,调用 Runtime API 时,Runtime 会自动把自身维护的当前设备对应的主上下文压到驱动上下文栈顶,覆盖你手动设置的自定义上下文,后续驱动API调用也会默认作用在这个 Runtime 托管的主上下文上,直到你把手动push的自定义上下文pop出栈。
混合使用的注意事项
- 手动通过驱动API push的自定义上下文,使用完一定要调用
cuCtxPopCurrent()弹出栈,避免影响后续 Runtime API 的执行逻辑。 - 不要手动调用
cuCtxDestroy()释放 Runtime 托管的主上下文,会导致后续 Runtime API 调用抛出非法上下文错误。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

