如何通过CUDA内核的混淆符号名获取设备端指针?
CUDA内核设备端指针获取问题解答
问题背景
通过cuModuleLoad加载vecAdd内核的cubin文件,使用cuModuleGetFunction传入混淆符号名_Z6vecAddPdS_S_i可获取该内核的主机端存根并启动内核。基于此场景,提出以下两个问题:
- 是否仅通过该混淆符号名,就能获取vecAdd内核的设备端指针?
- 在将
vecAdd.cu以-rdc=true编译为vecAdd.o并与main.cu链接的场景下,能否无需知晓vecAdd的函数签名,获取其设备端函数指针?
问题1解答
仅通过混淆符号名调用cuModuleGetFunction,只能得到主机端的CUfunction类型存根,无法直接获取设备端指针。若要获取设备端指针,必须在拿到CUfunction后,额外调用cuFuncGetAttribute API,指定CU_FUNC_ATTRIBUTE_FUNC_PTR属性提取:
CUfunction vec_add_func; // 先通过符号名获取主机端存根 cuModuleGetFunction(&vec_add_func, cuda_module, "_Z6vecAddPdS_S_i"); uintptr_t device_ptr; // 提取设备端指针 cuFuncGetAttribute(&device_ptr, CU_FUNC_ATTRIBUTE_FUNC_PTR, vec_add_func);
上述代码中device_ptr即为vecAdd内核的设备端指针。
问题2解答
可以做到。在-rdc=true(可重定位设备代码)编译模式下,vecAdd内核会被编译为可重定位的设备符号,即使不知道函数签名,只要掌握其混淆后的符号名,依然可以通过以下流程获取设备端指针:
- 将链接后的可执行文件(或单独的
vecAdd.o,需通过cuModuleLoadDataFromFile加载)作为CUDA模块加载; - 调用
cuModuleGetFunction传入混淆符号名,拿到主机端CUfunction存根; - 通过
cuFuncGetAttribute提取设备端指针,步骤与问题1完全一致。
此外,也可借助系统动态链接API(如Linux的dlsym、Windows的GetProcAddress)直接定位到主机端的内核存根函数,再通过cuFuncGetAttribute转换为设备端指针——整个过程无需知晓函数签名,仅需符号名即可完成定位。
内容的提问来源于stack exchange,提问作者Abhishek Ghosh
相关产品推荐
相关产品推荐

