编译tensorflow有专门的编译工具bazel,所以需要先安装bazel。我使用的是源码编译bazel(https://github.com/bazelbuild/bazel/releases)。
第一个坑:git clone bazel源码或者使用下载的bazel-0.21.0.tar.gz,这种源码里缺少生成需要的文件,所以需要下载的是bazel-0.21.0-dist.zip这种带有dist的源码包。编译命令简单,./compile.sh就可以了。这里需要的依赖工具有:pkg-config zip g++ zlib1g-dev unzip python python-numpy(python3-numpy) swig python-dev(python3-dev) openjdk-8-jdk,这些是安装页面提示的,全安了就行。生成的bazel在output/目录下,并且要把目录添加到PATH中。
第二个坑:git clone --recurse-submodules https://github.com/tensorflow/tensorflow,其中--recurse-submodules 参数是必须得, 用于获取 TesorFlow 依赖的 protobuf 库(这个是官方说明,如果不加貌似需要自己安装依赖的protobuf库:http://www.tensorfly.cn/tfdoc/get_started/os_setup.html,另一个:https://tensorflow.google.cn/install/source),从git上下载的tensorflow版本需要的bazel版本也比较高,所以需要切一下版本。
查看本地版本:git branch,查看远程分支:git branch -a,切换分支:git checkout -b “本地自己命名” “远程分支名”,如果不切分支,tensorflow和bazel版本不对应,无法编译。
第三个坑:下载cuda和cudnn,并安装,版本需要对应,需要注意的是cuda默认目录是/usr/local/cuda/,但是cudnn默认在/usr/目录下,所以需要把/usr/include下的cudnn.h拷贝到/usr/local/cuda/include下,把/usr/lib/x86_64-linux-gnu下的libcudnn相关的库都拷贝到/usr/local/cuda/lib64目录下。如果没有进行拷贝,会提示各种库没有,各种头文件找不到,真实是个大坑。
第四个坑:./configure时需要确认各种条件,这些条件我也没有全弄明白需要哪些,从网上查到的情况看,初级只需要cuda相关的选y,其他的都选n就可以,目录也只需要确认python、cuda、cudnn这些就可以了。
编译命令:
bazel build -c opt --config=cuda //tensorflow/cc:tutorials_example_trainer(例子,同时生成frame的so)
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so(这个是c++的so)
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_framework.so
更新:
1.编译自己的库,将项目目录拷贝到tensorflow/examples下,使用命令:
bazel build -c opt --config=cuda //tensorflow/examples/xxx/...进行编译,注意啦:自己的项目xxx目录后面要加...三个点,否则不知道为啥编译不过,可能是写的比较挫吧(>人<;)
bazel build -c opt --config=cuda //tensorflow/examples/xxx/... --linkopt=//home/ubuntu/myprojects/tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so 新版本貌似需要指定连接
项目中的BUILD一定要写好,需要编译的源文件要写全,否则编译完成了不报错,运行就苦恼了。
有的人使用编译选项--copt=-msse3 --copt=-msse4.1 --copt=-msse4.2 --copt=-mavx --copt=-mavx2 --copt=-mfma,目前了解的情况大概是这个是cpu架构支持的选项。如果有大神知道都代表什么意思希望能留言指点一下,谢谢!
2.ignoring visible gpu devices:0 ,with Cuda compute capability 7.0. The minimum required Cuda capability is 7.5,这个问题是编译tensorflow的时候的configure有一个配置:Please note that each additional compute capability significantly increases your build time and binary size. [Default is: 7.5]:需要写7.0(按不同使用的卡填写),默认的是7.5,所以设备跑不起来,而且跑起来之后自己的库也要重新编译。算力官网地址:https://developer.nvidia.com/cuda-gpus
2020.02.26更新:
3.tensorflow与bazel对应版本在tensorflow目录下有一个.bazelversion文件,里面写的就是需要的版本号,切换tensorflow版本分支后,.bazelversion内会有变化。
4.编译TensorFlow2.0及之后版本的时候命令略有不同需要添加--config=v2,例如
bazel build --config=opt --config=cuda --config=v2 //tensorflow:libtensorflow_framework.so
2020.04.03更新:
5.--cxxopt='-g' 可以用于编译debug版本,方便gdb查找,例如:bazel build -c opt --cxxopt='-g' --config=cuda //tensorflow/examples/xxx/... --linkopt=//home/ubuntu/myprojects/tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so
6.可以使用--retain-symbols-file和--version-script来限定对外开放的接口,防止接口名冲突导致的一系列问题。例如:
bazel build -c opt --config=cuda //tensorflow/examples/xxx/... --linkopt=//home/ubuntu/myprojects/tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so --linkopt=-Wl,--retain-symbols-file=/home/ubuntu/projects/tf/tensorflow/tensorflow/examples/model_classify/retain_symbols.sys --linkopt=-Wl,--version-script=/home/ubuntu/projects/tf/tensorflow/tensorflow/examples/model_classify/version_script.map
2020.05.15更新:
7.如果一个新的环境编译时自动下载特别慢,可以考虑使用proxy,但是有个问题可能不是每个人都会遇到,就是配置了代理之后,报错:HTTP/1.1 407 Proxy Authentication Required,这个问题基本确定是bazel的问题,所以搜索之后发现了这个:https://github.com/bazelbuild/bazel/issues/7487#issuecomment-466012513,bazel自己家的解决方法,先使用wget将下载失败的依赖包下载下来,这时候proxy是起作用的,速度很快,然后将所有需要的依赖包放到一个目录中,使用bazel的--distdir参数来指定本地依赖包目录,相当于离线,参考命令:
bazel build -c opt --config=cuda --distdir /home/test/projects/downloads //tensorflow/cc:tutorials_example_trainer
2020.05.21更新:
8.如果你的环境是arm64即aarch64的,那么可能会遇到其他奇特的问题,比如总有一些函数没有编译进库里,总是提示未定义函数等,稍微总结一点点,希望帮到大家。
首先,可能交叉编译环境不支持,所以要手动添加一下cpu类型,在tensorflow/third_party/gpus/crosstool目录下找到CROSSTOOL_hipcc.tpl,vi打开,找到
default_toolchain {cpu: "arm"toolchain_identifier: "local_linux"
}
在后面添加一个aarch64的:
default_toolchain {cpu: "aarch64"toolchain_identifier: "local_linux"
}
保存退出。
第二 ,还是这个目录,vi打开BUILD.tpl,找到标签cc_toolchain_suite下面的toolchains =中的"arm": ":cc-compiler-local",,在这个下面添加一行"aarch64": ":cc-compiler-local",,然后保存退出,如下:
cc_toolchain_suite(name = "toolchain",toolchains = {"local|compiler": ":cc-compiler-local","darwin|compiler": ":cc-compiler-darwin","x64_windows|msvc-cl": ":cc-compiler-windows","x64_windows": ":cc-compiler-windows","arm": ":cc-compiler-local","aarch64": ":cc-compiler-local","k8": ":cc-compiler-local","piii": ":cc-compiler-local","ppc": ":cc-compiler-local","darwin": ":cc-compiler-darwin",},
)
第三,有可能你会用到aws相关的,那么在tensorflow/third_party/aws目录下找到BUILD.bazel文件,vi打开,找到标签cc_library-->srcs = select-->"//conditions:default": [],修改为如下:
cc_library(name = "aws",srcs = select({"@org_tensorflow//tensorflow:linux_x86_64": glob(["aws-cpp-sdk-core/source/platform/linux-shared/*.cpp",]),"@org_tensorflow//tensorflow:darwin": glob(["aws-cpp-sdk-core/source/platform/linux-shared/*.cpp",]),"@org_tensorflow//tensorflow:linux_ppc64le": glob(["aws-cpp-sdk-core/source/platform/linux-shared/*.cpp",]),"@org_tensorflow//tensorflow:raspberry_pi_armeabi": glob(["aws-cpp-sdk-core/source/platform/linux-shared/*.cpp",]),#"//conditions:default": [],"//conditions:default": glob(["aws-cpp-sdk-core/source/platform/linux-shared/*.cpp",]),}) + glob([
2021.04.01更新:
ERROR: An error occurred during the fetch of repository 'io_bazel_rules_docker'
方法来自:https://blog.csdn.net/lsqtzj/article/details/108899430
目前遇到的坑就这些,已经编译出so了,能用,有新问题或新发现会在更新中顺序向下,待以后补充。