在tensorflow-gpu> = 1.15中使用用户运算符时未定义符号

时间:2019-12-06 00:55:04

标签: c++ tensorflow shared-libraries

大家。我写了一些用户运算符来扩展tensorflow,并尝试使用CMake将代码编译到不同的共享库中,以适合不同版本的tensorflow。

它在tensorflow-gpu <= 1.14时可以正常工作,但在1.15和2.0时不能正常工作。加载库时出现以下错误。

tensorflow.python.framework.errors_impl.NotFoundError: build/lib/libtensorflow_ctext.so: undefined symbol: _ZN10tensorflow12OpDefBuilder4AttrENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

我在1.14版和2.0版上尝试了nm build/lib/libtensorflow_ctext.so,两个共享库的中间都有这个未定义的符号。

U _ZN10tensorflow12OpDefBuilder4AttrENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

该程序似乎将在链接的Tensorflow框架库libtensorflow_framework.so中找到此符号。我在libtensorflow_framework.so.2中搜索了相似的符号,并发现了其中几个。

0000000000cacc50 T _ZN10tensorflow12OpDefBuilder10DeprecatedEiSs
0000000000cace00 T _ZN10tensorflow12OpDefBuilder10SetShapeFnESt8functionIFNS_6StatusEPNS_15shape_inference16InferenceContextEEE
0000000000cacb20 T _ZN10tensorflow12OpDefBuilder13ControlOutputESs
0000000000cac980 T _ZN10tensorflow12OpDefBuilder13SetIsStatefulEv
0000000000cac970 T _ZN10tensorflow12OpDefBuilder14SetIsAggregateEv
0000000000cac960 T _ZN10tensorflow12OpDefBuilder16SetIsCommutativeEv
0000000000cac990 T _ZN10tensorflow12OpDefBuilder27SetAllowsUninitializedInputEv
0000000000cacb50 T _ZN10tensorflow12OpDefBuilder3DocESs
0000000000caca90 T _ZN10tensorflow12OpDefBuilder4AttrESs
0000000000cacac0 T _ZN10tensorflow12OpDefBuilder5InputESs
0000000000cacaf0 T _ZN10tensorflow12OpDefBuilder6OutputESs
0000000000cac830 T _ZN10tensorflow12OpDefBuilderC1ESs
0000000000cac830 T _ZN10tensorflow12OpDefBuilderC2ESs
0000000000c702d0 W _ZN10tensorflow12OpDefBuilderD1Ev
0000000000c702d0 W _ZN10tensorflow12OpDefBuilderD2Ev

符号_ZN10tensorflow12OpDefBuilder4AttrESs看起来非常相似,但最后几个字母不同。我真的不知道那些“ ESs”和“ ENSt7”代表什么。

非常感谢我如何调试它的提示。这是构建我的共享库的命令(由cmake生成)

g++ -fPIC   -shared -Wl,-soname,libtensorflow_ctext.so -o lib/libtensorflow_ctext.so src/CMakeFiles/bp_par_2d.dir/bp_par_2d.cc.o src/CMakeFiles/bp_par_2d_sv.dir/bp_par_2d_sv.cc.o src/CMakeFiles/fp_par_2d.dir/fp_par_2d.cc.o src/CMakeFiles/filter.dir/filter.cc.o cuda/CMakeFiles/bp_par_2d_cu.dir/bp_par_2d.cu.o cuda/CMakeFiles/bp_par_2d_sv_cu.dir/bp_par_2d_sv.cu.o cuda/CMakeFiles/fp_par_2d_cu.dir/fp_par_2d.cu.o cuda/CMakeFiles/filter_cu.dir/filter.cu.o tensorflow/CMakeFiles/bp_par_2d_ops.dir/bp_par_2d_ops.cu.o tensorflow/CMakeFiles/bp_par_2d_sv_ops.dir/bp_par_2d_sv_ops.cu.o tensorflow/CMakeFiles/fp_par_2d_ops.dir/fp_par_2d_ops.cu.o tensorflow/CMakeFiles/ramp_filter_ops.dir/ramp_filter_ops.cu.o CMakeFiles/tensorflow_ctext.dir/cmake_device_link.o  -L/usr/lib/x86_64-linux-gnu/stubs -Wl,-rpath,/home/ltl/anaconda3/envs/tf_test/lib/python3.7/site-packages/tensorflow_core /home/ltl/anaconda3/envs/tf_test/lib/python3.7/site-packages/tensorflow_core/libtensorflow_framework.so.2 -lcudadevrt -lcudart_static -lrt -lpthread -ldl 

1 个答案:

答案 0 :(得分:1)

好,这个问题解决了。

我使用nm -C指令查看.so文件内部,发现在Tensorflow> = 1.15.0中,该函数定义为

0000000000caca90 T tensorflow::OpDefBuilder::Attr(std::string)

在Tensorflow <= 1.14.0中,该函数定义为

0000000000c96ed0 T tensorflow::OpDefBuilder::Attr(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)

因此,在编译共享库时,它们在_GLIBCXX_USE_CXX11_ABI上使用不同的设置。

为了保持一致并避免那些未定义的符号问题,我需要为Tensorflow的早期版本定义-D_GLIBCXX_USE_CXX11_ABI=1,为更高的版本定义-D_GLIBCXX_USE_CXX11_ABI=0