目录

一、SPEC

1. 参数

2. 返回值cudaSuccess、cudaErrorInvalidValue、cudaErrorNotSupported

3. 说明通过 **funcPtr 返回请求标志对应的 CUDA 驱动程序函数地址。

4. 注意:强烈不建议在 CUDA 定义类型与驱动程序 API 版本间混用不同版本,此类操作可能导致未定义行为。更多信息参见此处。

二、核心概念与工作原理

三、主要应用场景

四、重要注意事项

五、替代与相关函数:

六、总结


一、SPEC

__host__​cudaError_t cudaGetDriverEntryPoint ( 
const char* symbol, 
void** funcPtr, 
unsigned long long flags, 
cudaDriverEntryPointQueryResult ** driverStatus = NULL )

cudaGetDriverEntryPoint 函数的主要作用是在运行时动态获取CUDA驱动API函数的入口地址。这在需要精确控制CUDA驱动版本或使用较新驱动特性的高级编程场景中非常有用。

1. 参数

参数作用说明
symbol输入。要查找的驱动程序 API 函数的基名。例如,对于驱动程序 API cuMemAlloc_v2,symbol 应为 cuMemAlloc。请注意,该 API 将使用最新api name。
funcPtr用于存储请求驱动程序函数指针的位置
flags指定搜索选项的标志位
driverStatus可选位置,用于存储从驱动程序查找符号的状态。可能值请参见cudaDriverEntryPointQueryResult。


2. 返回值
cudaSuccess、cudaErrorInvalidValue、cudaErrorNotSupported

3. 说明
通过 **funcPtr 返回请求标志对应的 CUDA 驱动程序函数地址。

对于请求的驱动程序符号,若该符号引入的 CUDA 版本小于或等于当前 CUDA 运行时版本,API 将返回对应版本驱动程序函数的函数指针。

API 返回的指针需转换为与 API 头文件中请求驱动程序函数定义匹配的函数指针类型。函数指针的typedef定义可从对应的typedefs头文件获取。例如cudaTypedefs.h包含cuda.h中定义的驱动程序API函数指针typedef。

若请求的驱动程序函数在平台上不受支持、CUDA运行时版本不存在兼容的ABI驱动函数,或驱动程序符号无效,则API将返回cudaSuccess并将返回的funcPtr设为NULL。

同时会将可选参数driverStatus设置为cudaDriverEntryPointQueryResult中的任一值,含义如下:

cudaDriverEntryPointSuccess根据输入参数成功找到请求符号且pfn有效
cudaDriverEntryPointSymbolNotFound未找到请求符号
cudaDriverEntryPointVersionNotSufficent找到请求符号但当前运行时版本(CUDART_VERSION)不支持

请求标志可选值:

cudaEnableDefault默认模式。若代码使用 --default-stream 线程级编译标志编译或定义了宏 CUDA_API_PER_THREAD_DEFAULT_STREAM,则等效于 cudaEnablePerThreadDefaultStream;否则等效于 cudaEnableLegacyStream。
cudaEnableLegacyStream启用对所有匹配请求驱动程序符号名称的驱动程序符号搜索,但不包含对应的线程级版本。
cudaEnablePerThreadDefaultStream将启用对所有匹配请求驱动程序符号名称的驱动程序符号的搜索,包括线程版本。若未找到线程版本,API 将返回驱动程序函数的旧版。


4. 注意:
强烈不建议在 CUDA 定义类型与驱动程序 API 版本间混用不同版本,此类操作可能导致未定义行为。更多信息参见此处。

需注意,若此调用尝试初始化内部 CUDA RT 状态,该函数还可能返回 cudaErrorInitializationError、cudaErrorInsufficientDriver 或 cudaErrorNoDevice 错误。

根据 cudaStreamAddCallback 的规定,回调函数中不得调用任何 CUDA 函数。此类情况下可能(但不保证)返回 cudaErrorNotPermitted 作为诊断信息。

二、核心概念与工作原理

理解这个函数,可以从以下几个方面入手:

  • 动态获取函数指针:该函数允许你获取指定CUDA驱动API函数的指针,之后你可以通过该指针直接调用对应的驱动函数。这类似于操作系统API(如POSIX的dlsym或Windows的GetProcAddress)中获取函数地址的操作。
  • 处理驱动API的版本化:CUDA驱动API函数可能存在多个版本(例如cuMemAlloccuMemAlloc_v2),新版本通常在函数签名或语义上有所变化。cudaGetDriverEntryPoint 能根据你请求的CUDA版本,返回对应且ABI兼容的函数指针。你需要将返回的指针转换为正确的函数类型(例如PFN_cuMemAlloc_v3020)再使用。
  • 灵活的符号查找:你可以通过设置不同的标志(如cudaEnableLegacyStreamcudaEnablePerThreadDefaultStream)来指导函数查找符号的行为,例如指定查找与每线程默认流(Per-Thread Default Stream)相关的版本。

三、主要应用场景

cudaGetDriverEntryPoint 通常在以下情况被使用:

  • 使用新版驱动的旧工具包:当你的程序使用旧版CUDA工具包编译,但希望在支持新驱动API的新版NVIDIA驱动环境下运行时,可以通过此函数访问新的驱动功能。
  • 精确控制API版本:如果你需要确保使用特定版本的驱动API(例如为了兼容性或特定行为),此函数可以帮你获取指定版本的函数指针。
  • 按需加载驱动函数:某些情况下,你可能希望延迟加载或仅在某些条件下加载特定的CUDA驱动API,以优化性能或处理可选的依赖。

四、重要注意事项

使用该函数时,请注意以下几点:

  • 错误处理:如果请求的驱动函数在当前平台不被支持、没有ABI兼容的版本或者符号无效,函数将返回 cudaErrorSymbolNotFound务必检查返回值以确保成功。
  • 版本指定:你需要准确指定与你期望函数行为兼容的CUDA版本。如果指定的版本无效(例如,请求一个在指定版本之后才引入的符号),函数可能返回错误。
  • 函数指针转换:获取函数指针后,必须将其转换到与目标驱动函数签名严格匹配的正确函数指针类型(通常借助 cudaTypedefs.h 中定义的typedef,例如 PFN_cuMemAlloc_v3020)才能调用。错误的转换会导致未定义行为。

下面的流程图总结了一次典型的 cudaGetDriverEntryPoint 调用过程:

五、替代与相关函数:

cuGetProcAddress

六、总结

cudaGetDriverEntryPoint 是CUDA编程中一个用于运行时动态绑定特定版本驱动API的高级工具。它在处理跨版本兼容性、精确控制驱动API行为或按需加载驱动功能时非常有用。使用时请务必注意错误检查正确的函数指针转换

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐