运行时API应用程序中的cuda上下文创建和资源关联

运行时API应用程序中的cuda上下文创建和资源关联,cuda,cuda-context,Cuda,Cuda Context,我想了解cuda上下文是如何在cuda运行时API应用程序中创建并与内核关联的 我知道这是司机在引擎盖下做的。但我想了解创作的时间线 首先,我知道cudaRegisterFatBinary是第一个CUDAAPI调用,它在运行时注册了一个fatbin文件。接下来是一些cuda函数注册API,它们在驱动程序层调用cuModuleLoad。但是,如果我的Cuda运行时API应用程序调用cudaMalloc,那么指向该函数的指针将如何与上下文关联,我认为应该事先创建上下文。如何获得这个已经创建的上下文的

我想了解cuda上下文是如何在cuda运行时API应用程序中创建并与内核关联的

我知道这是司机在引擎盖下做的。但我想了解创作的时间线

首先,我知道cudaRegisterFatBinary是第一个CUDAAPI调用,它在运行时注册了一个fatbin文件。接下来是一些cuda函数注册API,它们在驱动程序层调用cuModuleLoad。但是,如果我的Cuda运行时API应用程序调用cudaMalloc,那么指向该函数的指针将如何与上下文关联,我认为应该事先创建上下文。如何获得这个已经创建的上下文的句柄并将未来的运行时API调用与之关联?请揭开内部工作的神秘面纱

引用NVIDIA在这方面的文档

CUDA运行时API调用在CUDA驱动程序API CUcontext上运行 已绑定到当前主机线程

如果不存在绑定到当前应用程序的CUDA驱动程序API CUcontext CUDA运行时API调用时的线程,该调用需要 然后CUDA运行时将隐式创建一个新的CUcontext 在执行调用之前

如果CUDA运行时创建CUcontext,则CUcontext将 使用CUDA运行时API指定的参数创建 功能cudaSetDevice、CUDASETDVALIDDEVICES、cudaSetDeviceFlags、, cudaGLSetGLDevice,CUDAD39SETDIREC3DDEVICE, cudaD3D10SetDirect3DDevice和cudaD3D11SetDirect3DDevice。注意 如果这些函数不可用,则cudaErrorSetOnActiveProcess将失败 当CUcontext绑定到当前主机线程时调用

CUcontext的生存期由引用计数管理 机制。CUcontext的引用计数最初设置为0, 并由cuCtxAttach递增,由cuCtxDetach递减

如果CUDA运行时创建了CUcontext,则CUDA运行时 将减少函数中该CUcontext的引用计数 cudaThreadExit。如果CUDA驱动程序API创建了CUcontext(或 由CUDA运行时API库的单独实例创建), 然后CUDA运行时将不会增加或减少引用 数一数那个超文本

所有CUDA运行时API状态(例如,全局变量的地址和 值)与其基础CUcontext一起移动。特别是,如果 CUcontext从一个线程移动到另一个线程(使用cuCtxPopCurrent) 然后所有CUDA运行时API状态将移动到 那根线也是

但我不明白的是cuda运行时是如何创建上下文的?为此使用了哪些API调用?nvcc编译器是在编译时插入一些API调用来执行此操作,还是完全在运行时完成?如果前者为真,那么此上下文管理使用哪些运行时API?这是真的,到底是怎么做的

如果一个上下文与一个主机线程相关联,我们如何访问这个上下文?它是否自动与线程处理的所有变量和指针引用关联


模块加载最终是如何在上下文中完成的?

CUDA运行时维护要加载的模块的全局列表,并在每次将DLL或.so加载到进程中时将其添加到该列表中。但在创建设备之前,不会实际加载模块

上下文创建和初始化由CUDA运行时“延迟”完成——每次调用cudaMemcpy()之类的函数时,它都会检查CUDA是否已初始化,如果尚未初始化,则会创建上下文(在以前由cudaSetDevice()指定的设备上,如果从未调用cudaSetDevice(),则在默认设备上)并加载所有模块。从那时起,上下文与该CPU线程关联,直到它被cudaSetDevice()更改

您可以使用驱动程序API中的上下文/线程管理函数,例如cuCtxPopCurrent()/cuCtxPushCurrent(),来使用来自不同线程的上下文

您可以调用cudaFree(0);强制执行此延迟初始化


我强烈建议在应用程序初始化时这样做,以避免竞争条件和未定义的行为。继续,在应用程序中尽早枚举和初始化设备;完成后,在CUDA 4.0中,您可以从任何CPU线程调用cudaSetDevice(),它将选择由初始化代码创建的相应上下文。

我尝试使用cudaFree(0)。但我仍然没有得到一个上下文。CuCtxPop返回空值。为什么会这样?在成功的cudaFree(0)之后,您肯定应该有一个当前上下文。您检查了返回值了吗?因此,在研究该问题后,我发现CudaFree(0)给了我一个无效的资源句柄错误。你知道为什么吗?如果你能运行其他CUDA程序(例如SDK示例),好的,我必须查看该程序来推测你的cudaFree(0)失败的原因。