ubuntu16.04 tensorflow c++编译及调用

时间:2020-9-1 作者:admin


优秀的参考文献:link

感谢作者!!!

写之前总结下我遇到的坑,一把辛酸泪!!
大坑1:
ubuntu16.04 tensorflow c++编译及调用
我查看了我的/usr/local/include…那个路径下有tensor_shape.h这个函数的,这个错误有人说是tensorflow_cc.so找不到link,有的人说link既然编译了tensorflow就顺便编译whl,然后卸载本身用pip install安装的tensorflow,这种办法我试了,还是报错undefined balabala一堆,我最终的解决方案是:linker时加上-fuse-ld=gold,我最后使用的这行语句是这样的:g++ -std=c++11 -fuse-ld=gold …

大坑2:

./third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1:42: fatal error: unsupported/Eigen/CXX11/Tensor: No such file or directory

这个原因大概率是Eigen没安装好或者没找到,我是因为没找到
大坑3:

This file was generated by an older version of protoc

这个报错原因是,tensorflow和protocbuf的版本不匹配!!一定要安装正确版本的protocbuf,我有种感觉这个protocbuf和tensorflow版本是对应好的,因为我安装3.6.1失败了,只有3.6.0安装成功了!!
坑4:
abseil库报错,link这个解决了问题,但是我后来重新配置了就没再报这个错误,我不知道是因为解决了其他错误顺道这个错误就没了,还是因为这个库所在的目录被我加入到搜索库中的原因,后来就没再报这个错误,先记录下!

还有的给忘了,主要时间花在这些上面了!!!

环境:
ubuntu16.04
python3.5
protocbuf 3.6.0
bazel 0.15.0
NCCL: 2.2.13
tensorflow-gpu=1.12
Eigen的版本:3.3.90

  1. 安装bazel
下载Bazel官网:
https://github.com/bazelbuild/bazel/releases
安装
./bazel-0.15.0-installer-linux-x86_64.sh
  1. 安装protocbuf
    我之前安装的版本是3.6.1然后报版本不匹配的错误!后来我才发现版本信息在源码里已经给出来了,按照给出来的版本信息装就好了!版本信息在源码tensorflow下的./tensorflow/workspace.bzl,编译tensorflow和c++主要用到的就是Eigen,protocbuf,bazel,记好这几个库的版本信息就好了!我在这个文件里找到了我要用的版本!
官网:
https://github.com/google/protobuf/releases
我下载的版本3.6.0
cd prtobuf-3.6.0
./configure
sudo make -j8
make check -j8
sudo make install
sudo ldconfig
查看版本信息:protoc --version
(这个过程还蛮久的!)

查看本机安装的protobuf版本的方法:

1. pip show protobuf
2. protoc  --version

这边我要附一个卸载protocbuf的方法:

sudo apt-get remove libprotobuf-dev
which protoc
这样删除我发现并没有删干净
sudo rm /usr/local/bin/protoc  //执行文件
sudo rm -rf /usr/local/include/google //头文件
sudo rm -rf /usr/local/lib/libproto* //库文件
这种办法才可以删的干净!!
  1. 安装Eigen,这个是c++的矩阵运行库
官网:
https://gitlab.com/libeigen/eigen/-/releases
我的版本3.3.90
tar -zxvf eigen-3.3.90.tar.gz
cd eigen-3.3.90/
mkdir build
cd build
cmake ..
sudo make
sudo make install
sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include

安装好了可以网上搜个小程序测试下有没有安装成功,感谢这个大佬帮我解答了为什么最后要复制到include库里,附链接link
sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include
4. 安装NCCL

官网:
https://developer.nvidia.com/nccl
我下载的2.2.13(给我眼睛都找瞎了才找到)
sudo dpkg -i nccl-repo-ubuntu1604-2.2.13-ga-cuda9.0_1-1_amd64.deb
sudo apt update
sudo apt install libnccl2 libnccl-dev
sudo cp /usr/lib/x86_64-linux-gnu/libnccl.so.2 /usr/local/cuda/lib
sudo cp /usr/include/nccl.h /usr/local/cuda/include/
  1. 编译tensorflow
    我下的是源码1.12版本
官网:
https://github.com/tensorflow/tensorflow/tags
tips:
这里也可以用git方法,然后切换分支,但是我更喜欢源码安装,就没选那种方法
./configure
这个过程我只记得一些没选默认的:
1. 我的ubuntu上有python3.5,python3.6,我想安装在3.5下,我就指定了安装目录:/usr/bin/python3.5
2. cuda那个我选了Y,因为我要用cuda,其他的都是默认或者n

下面就是编译了

正常人都是这么编译的:
bazel build --config=opt //tensorflow:libtensorflow_cc.so // 无显卡,cpu版本
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so // 有显卡
我看到人家说要加个参数,不然c++ imread()读图容易出问题,但是我搜了很久都没搜到人家混合一起的命令,可我还是加了,我的命令是这样的
bazel build --config=monolithic --config=cuda //tensorflow:libtensorflow_cc.so
这个过程差不多20多分钟吧,看到successful就是成功了,我编译了好几次,这边都没出过错!
后面我要pip install .whl所以这边我又编译了whl
bazel build --config=noaws //tensorflow/tools/pip_package:build_pip_package --verbose_failures --copt=-funsafe-math-optimizations --copt=-march=armv8-a --copt=-mtune=cortex-a53

到了这里人家博客都会说执行这个脚本./tensorflow/contrib/makefile/download_dependencies.sh下载需要的东西,我死活没成功!好在我后来发现这些库都可以自己下载!
不过在这边我又进行了一个操作,因为总是报错

/usr/local/include/tf/tensorflow/core/public/session.h:22:60: fatal error: tensorflow/core/framework/device_attributes.pb.h: No such file or directory

我一看这个文件device_attributes.pb.h在bazel-genfiles/tensorflow/core/framework下面有的啊!后来又报了一些错,我在bazel-genfiles/tensorflow/cc/ops下找到了,然后我把”tensorflow/bazel-genfiles/tensorflow/”中的cc和core文件夹中的内容覆盖掉了tensorflow/tensorflow/文件,敲的时候手都在抖!!!但是后来没报错了,哈哈哈哈哈!!!
然后就是建文件夹,挪文件

sudo mkdir /usr/local/include/tf
sudo cp -r bazel-genfiles/ /usr/local/include/tf/
sudo cp -r tensorflow /usr/local/include/tf/
sudo cp -r third_party /usr/local/include/tf/
sudo cp bazel-bin/tensorflow/libtensorflow_cc.so /usr/local/lib/
sudo cp bazel-bin/tensorflow/libtensorflow_framework.so /usr/local/lib

我测试环境是用的这个项目link

这里我将库路径加入搜索目录,就是将库目录加在文件/etc/ld.so.conf的后面
ubuntu16.04 tensorflow c++编译及调用
然后ldconfig
ldconfig -v出现刚刚加进去的路径,要是报错说ibtensorflow_cc.so:No such file or directory,就是上面挪文件没挪对,检查上面挪文件那部分了,直到gcc -ltensorflow_cc –verbose不报那种找不到什么tensorflow_cc.so的错误就成功了!

我跟我参考的链接有点不一样就是这边我的脚本是这样的:
ubuntu16.04 tensorflow c++编译及调用

SOURCE_DIR =./src
BIN_DIR = ./bin

CPP     = g++ -std=c++11 -fuse-ld=gold
LDFLAGS = -g -Wall -D_DEBUG -Wshadow -Wno-sign-compare -w
LDLIBS  = -L/usr/local/lib/
INCLUDES = -I/usr/local/include/tf -I/usr/local/include/eigen3
ACTUAL_LIBS = `pkg-config --cflags --libs protobuf` -ltensorflow_cc -ltensorflow_framework

INPUT_FILE = $(SOURCE_DIR)/main.cpp $(SOURCE_DIR)/ann_model_loader.cpp
OBJET_FILE = $(BIN_DIR)/tfcpp_demo

tfcpp_demo:
        $(CPP) -o $(OBJET_FILE) $(INCLUDES) $(LDFLAGS) $(LDLIBS) $(ACTUAL_LIBS) $(INPUT_FILE)

make之后就sh run.sh执行,可以输出结果,至此就弄好了!!!

这里我ubuntu默认的gcc版本是4.8,但是我看到官网上说ubuntu16.04需要的gcc版本是4.8,我又折腾了一波,切换gcc版本,参考链接link注意了别人合在一起,一条命令解决了,但是我只能分开才可以

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
下面是我的:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 101
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 101

g++也是一样的操作!!

这里还要附一个小插曲,因为我一直make报错,就是上面那个undefined错误,我检查了我其他的都没问题,跟人家不一样的就是编译tensorflow_cc.so时的命令,可是并没有报错,我就不想重新编译!然后我看到人家在ubuntu里cmake成成功,我就想着我现在也没弄好,还不如试试看,就看到了这个博客link,这人也很幸福,运行这个脚本是成功的./download_dependencies.sh,羡慕脸!!他的前面部分跟我是一样的,我就没管,我是接着那部分开始的,就是
接着在文件夹中建立一个CMakeList.txt文件,在文件中写入 这部分开始
新建CMakeLists.txt文件
我把我tensorflow1.12的源码拷贝到了main.cpp文件下,现在这个路径下有这些文件:

ubuntu16.04 tensorflow c++编译及调用

cmake_minimum_required(VERSION 3.11)
project(cpptensorflow)
set(CMAKE_CXX_STANDARD 11)
link_directories(/home/ubuntu/tensorflow-1.12.0/bazel-bin/tensorflow)
include_directories(
        /home/ubuntu/tensorflow-tutorial/cpp/src/tensorflow-1.12.0
        /home/ubuntu/tensorflow-tutorial/cpp/src/tensorflow-1.12.0/bazel-genfiles
        /home/ubuntu/tensorflow-tutorial/cpp/src/tensorflow-1.12.0/bazel-bin/tensorflow
        /usr/local/include/eigen3
)
add_executable(cpptensorflow main.cpp ann_model_loader.h model_loader_base.h ann_model_loader.cpp)
target_link_libraries(cpptensorflow tensorflow_cc tensorflow_framework)

这边也发生了点事,我的cmake版本是3.6,告诉我版本低,需要重新下载高版本的,我就看到了这个链接link这个人肯定是个大神,一点废话都没有,言简意赅,安装成功!!这个大神真是牛气啊!!!反手就是一个关注,期待大神多多更新,让我多学习学习!!!!
然后就是编译项目了

mkdir  build
cd  build
cmake ..
make 

接着运行

./cpptensorflow /home/ubuntu/tensorflow-tutorial/cpp/model/nn_model_frozen.pb

ubuntu16.04 tensorflow c++编译及调用
ubuntu16.04 tensorflow c++编译及调用
到此就成功了,那也说明我的tensorflow_cc.so文件编译的没有问题,然后开始找undefined的原因,后来发现g++编译linker时加上-fuse-ld=gold就好了,成功输出想要的结果!!
这下是真的成功了!
当然我自己的项目也配置成功了,写出来是用别人的项目记录自己的bug和一些心得!!

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。