编译PyTorch源码遇链接错误:C++与CUDA名称修饰不一致咨询
PyTorch源码编译链接错误问题解答
问题背景
从源码编译PyTorch时遇到链接错误,排查发现C++文件中定义的模板函数与CUDA文件中的声明生成了两个不同的名称修饰符号:
- C++定义:
_ZNK2at10TensorBase14const_data_ptrIdTnNSt9enable_ifIXntsr**3std**E10is_const_vIT_EEiE4typeELi0EEEPKS3_v - CUDA声明:
_ZNK2at10TensorBase14const_data_ptrIdTnNSt9enable_ifIXntsr**4__T0**E10is_const_vIT_EEiE4typeELi0EEEPKS3_v
二者仅加粗部分存在差异,但使用llvm-cxxfilt解修饰后,得到的函数名均为double const* at::TensorBase::const_data_ptr<double, 0>() const。
工具版本信息:
- clang:Ubuntu clang version 18.1.8
- NVCC:Cuda compilation tools, release 12.6, V12.6.85
- NVCC宿主编译器:上述clang 18.1.8
问题1:修饰名中的加粗部分是什么?为何解修饰后看不到它们?
- 加粗部分是命名空间的编码差异:
3std是clang对std命名空间的标准Itanium ABI编码(数字代表后续名称的长度,后跟名称本身);4__T0是NVCC编译CUDA代码时,对std命名空间使用的内部占位符编码。 - 解修饰后看不到是因为
llvm-cxxfilt会识别编译器内部的占位符(如__T0),将其还原为原本的std命名空间名称,所以最终显示的函数签名会忽略这些底层编码细节,呈现统一的结果。
问题2:为何两个不同的修饰符号解修饰后对应同一个函数名?
这是由于clang和NVCC在处理模板依赖的标准命名空间时,ABI编码规则存在细节差异:
- clang直接按照Itanium ABI标准对
std命名空间进行编码,生成3std; - NVCC在编译CUDA代码流程中,会将
std这类标准命名空间临时替换为内部占位符__T0,再进行编码生成4__T0。
虽然二者的修饰符号不同,但实际指向的是同一个模板函数实例,因此解修饰工具会将它们还原为完全一致的函数签名。
内容的提问来源于stack exchange,提问作者mibu
相关产品推荐
相关产品推荐

