使用CUDA主上下文调用cuvidGetDecoderCaps报错101的原因
问题分析与解决
核心原因
你遇到的cudaErrorInvalidDevice(错误码101)问题,本质是CUDA Runtime API与Driver API的上下文交互细节没处理到位:
cudaSetDevice是Runtime API接口,它会初始化指定设备并创建Runtime主上下文,但这个上下文并不会自动完成Driver API层面的线程绑定(虽然Runtime和Driver上下文是共享的,但部分Driver API/Video Codec SDK函数需要显式的Driver上下文绑定);- 你用
cuCtxGetCurrent查到的上下文是Runtime创建的主上下文,但cuvidGetDecoderCaps作为Video Codec SDK的函数,对上下文的绑定要求更严格,仅靠Runtime的隐式上下文无法满足。
解决方案
不需要纠结是否必须显式创建上下文,而是要统一使用Driver API完成设备初始化和上下文绑定,或者显式将Runtime创建的上下文同步到Driver API层面。推荐两种可行方案:
方案1:全程使用Driver API初始化
替换cudaSetDevice为Driver API的设备初始化流程,确保上下文被正确绑定:
// 初始化CUDA Driver API CheckCudaErrors(cuInit(0)); CUdevice device; // 获取设备0 CheckCudaErrors(cuDeviceGet(&device, 0)); CUcontext cuda_context = nullptr; // 创建显式上下文并绑定到当前线程 CheckCudaErrors(cuCtxCreate(&cuda_context, 0, device)); // 检查上下文 if (cuda_context == nullptr) { LOG(ERROR) << "cuda context is nullptr"; return -1; } else { LOG(INFO) << "cuda context is not nullptr"; } // 调用cuvidGetDecoderCaps CUVIDDECODECAPS decode_caps = {}; decode_caps.eCodecType = cudaVideoCodec_HEVC; decode_caps.eChromaFormat = cudaVideoChromaFormat_420; decode_caps.nBitDepthMinus8 = 0; CheckCudaErrors(cuvidGetDecoderCaps(&decode_caps));
方案2:显式同步Runtime上下文到Driver API
如果你想保留cudaSetDevice的使用,需要在调用cuvidGetDecoderCaps前,显式将Runtime的主上下文设置为Driver API的当前上下文:
CheckCudaErrors(cudaSetDevice(0)); // 显式获取Runtime的主上下文,并设置为Driver API的当前上下文 CUcontext cuda_context = nullptr; CheckCudaErrors(cuCtxGetApiCUDAContext(&cuda_context, 0)); CheckCudaErrors(cuCtxSetCurrent(cuda_context)); // 后续调用不变 if (cuda_context == nullptr) { LOG(ERROR) << "cuda context is nullptr"; return -1; } else { LOG(INFO) << "cuda context is not nullptr"; } CUVIDDECODECAPS decode_caps = {}; decode_caps.eCodecType = cudaVideoCodec_HEVC; decode_caps.eChromaFormat = cudaVideoChromaFormat_420; decode_caps.nBitDepthMinus8 = 0; CheckCudaErrors(cuvidGetDecoderCaps(&decode_caps));
额外排查点
如果以上方案仍报错,需要确认:
- 你的GPU型号是否支持HEVC硬件解码;
- CUDA驱动和Video Codec SDK版本是否匹配(建议使用最新兼容版本)。
内容的提问来源于stack exchange,提问作者375
相关产品推荐
相关产品推荐

