根据CUDA文档所述:
- 如果通过驱动程序API创建并使上下文成为当前上下文,则随后的运行时调用将接管此上下文而不是创建新的上下文。
- 如果已初始化运行时(如CUDA Runtime中所述),则可以使用cuCtxGetCurrent()检索在初始化期间创建的上下文。此上下文可以由随后的驱动程序API调用使用。
我能够做到第一个要点。 我可以从cuda驱动程序创建上下文。 然后,我可以在不调用 cudaSetDevice()
的情况下使用cuda运行时函数,该函数会隐式地创建一个新的主上下文。
但是,我想使用第二个选项。 即首先初始化运行时,然后执行 cuCtxGetCurrent()
并在cuda驱动程序api中使用它。 这根本不起作用。 我总是会引发错误,称上下文已被销毁或无效。 我做错了什么?
以下是我的示例代码:
#define CUDA_DRIVER_API
#include <cuda.h>
#include <cuda_runtime.h>
#include <helper_cuda.h>
#include <iostream>
CUcontext check_current_ctx()
{
CUcontext context{0};
unsigned int api_ver;
checkCudaErrors(cuCtxGetCurrent(&context));
fprintf(stdout, "current context=%p\n", context);
checkCudaErrors( cuCtxGetApiVersion(context, &api_ver));
fprintf(stdout, "current context api version = %d\n", api_ver);
return context;
}
auto inital_runtime_context()
{
int current_device = 0;
int device_count = 0;
int devices_prohibited = 0;
CUcontext current_ctx{0};
cudaDeviceProp deviceProp;
checkCudaErrors(cudaGetDeviceCount(&device_count));;
if (device_count == 0) {
fprintf(stderr, "CUDA error: no devices supporting CUDA.\n");
exit(EXIT_FAILURE);
}
// Find the GPU which is selected by Vulkan
while (current_device < device_count) {
cudaGetDeviceProperties(&deviceProp, current_device);
if ((deviceProp.computeMode != cudaComputeModeProhibited)) {
checkCudaErrors(cudaSetDevice(current_device));
checkCudaErrors(cudaGetDeviceProperties(&deviceProp, current_device));
printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n",
current_device, deviceProp.name, deviceProp.major,
deviceProp.minor);
CUcontext current_ctx;
cuCtxGetCurrent(¤t_ctx);
std::cout << "current_ctx=" << current_ctx << "\n";
return current_device;
} else {
devices_prohibited++;
}
current_device++;
}
if (devices_prohibited == device_count) {
fprintf(stderr,
"CUDA error:"
" No Vulkan-CUDA Interop capable GPU found.\n");
exit(EXIT_FAILURE);
}
return -1;
}
void test_runtime_driver_op()
{
inital_runtime_context();
check_current_ctx();
}
它报告如下:
GPU Device 0: "GeForce RTX ..." with compute capability 7.5
current_ctx=0x6eb220
current context=0x6eb220
CUDA error at ... code=201(CUDA_ERROR_INVALID_CONTEXT) "cuCtxGetApiVersion(context, &api_ver)"
cudafree(0)
,以使运行时API创建上下文。有可能你现有的代码没有强制进行延迟上下文创建。 - talonmies