pytorch源码开发:在Ubuntu中的编译调试(C语言源码级调试)
下载
git clone --recursive https://github.com/pytorch/pytorch
cd pytorch
非C语言级调试版安装
如果不需要C语言高度,用anaconda安装,参考(https://github.com/pytorch/pytorch)过程如下,
sudo apt-get install cmake lmdb-utils
sudo apt-get install cmake-gui #(if you need GUI interface for cmake...)
conda create -n torchenv python=3.7
source activate torchenv
conda install numpy pyyaml mkl mkl-include setuptools scikit-build cffi typing pybind11
conda install cudnn (cudatoolkit: 9.2-0+cudnn:7.2.1-cuda9.2_0)
pip install ninjia (conda install ninja)(optional, warning: C++ will not be compiled incrementally)
conda install -c pytorch magma-cuda92 (optional, Add LAPACK support for the GPU if needed)
git clone --recursive https://github.com/pytorch/pytorch
cd pytorch
export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"}
python setup.py install, or for deveopers (python setup.py build develop)
官网的依赖都是使用conda,conda默认的安装都是非调试版的。另外还有一些常用包也列一下,根据需要自己装吧
conda install scikit-image pandas opencv cython
另外说明一下,如果你只是想安装pytorch使用,而不需要调试或查看任何源码或版本,那么下面这个安装方法最省事,
conda install -c pytorch pytorch
conda install -c pytorch torchvision
(不需要安装相关依赖的话,就使用pip install torchvision)
更具体的请参考:
https://pytorch.org/get-started/locally
https://anaconda.org/pytorch/pytorch
参考原文:https://blog.csdn.net/tanmx219/article/details/82831964
C语言级调试版
Python不一定要调试版,但我个人喜好就是弄个调试版的。
另外我补充一点,通过设置DEBUG=1,调试pytorch时gdb既能进入pytorch的C源码,也能进入python的源码,python不需要自己编译也是没有问题的(最初我以为这是必须的,后来发现直接用anacon的python编译pytorch一点问题都没有)至于为什么能进入python库的C源码,我也不知道,有时间得再细看一下pytorch编译部分,找到解压python源码包的那段估计就是了,。
在后面的描述中都不使用anaconda,而是假设使用python372来调试pytorch。python372是我自己编译安装的python调试开发版。关于如何安装调试版python, 以及如何让该版本独立另存,请参考前一个贴子:
https://blog.csdn.net/tanmx219/article/details/86518446
另外,调试最好和开发分开,不要和日常应用弄到一起,道理大家都明白的。
同样,因为这里不使用conda,而是我们前面编译好的pip372,相关指令如下,
$ sudo apt-get install cmake cmake-gui lmdb-utils
$ sudo -H pip372 install numpy pyyaml mkl mkl-include setuptools cffi typing \ pybind11 ninja
编译调试pytorch,注意这里需要sudo权限,否则会报错无法安装
cd pytorch
sudo python372 setup.py build develop
或者
sudo -H python372 setup.py build develop
如果你需要用gdb等工具调试,还需要打开DEBUG (-g)开关,详细原因请参考后面“问题”部分说明,我一般使用的命令
DEBUG=1 USE_OPENCV=1 USE_FFMPEG=1 USE_LMDB=1 USE_CUDA=1 USE_CUDNN=1(NO_CUDA=1)
sudo -H python setup.py build develop
这里的USE_OPENCV等就需要根据自己的实际情况取舍了,CUDA也要根据自己的实际机器来,默认这些都是OFF。
编译完后可能会出现一大堆问题,具体解决方案请参考后面的章节。一般在问题解决之后,需要重新再编译一次才行。
$ sudo python372 setup.py clean
$ sudo python372 setup.py build develop
问题
-- Could NOT find CUB (missing: CUB_INCLUDE_DIR)
之类的报错,我的主要包括下面这些设置,
pybind11_DIR
pybind11_INCLUDE_DIR
CUDNN_INCLUDE_DIR
CUDNN_LIBRARY
CUB_INCLUDE_DIR
DOXYGEN_EXECUTABLE
MPI_C_LIB_NAMES
MPI_C_HEADER_DIR
MPI_C_WORKS
MPI_CXX_LIB_NAMES
MPI_CXX_HEADER_DIR
MPI_CXX_WORKS
MPI_C_FOUND MPI_CXX_FOUND
此时可直接在环境变量中添加,如
$ sudo gedit ~/.bashrc
#在文件末尾添加下面的路径和变量,并保存
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
export pybind11_DIR="/home/matthew/dev/pytorch/third_party/pybind11/tools"
export pybind11_INCLUDE_DIR="/home/matthew/dev/pytorch/third_party/pybind11/include/pybind11"
export CUDNN_INCLUDE_DIR="/usr/local/cuda/include"
export CUDNN_LIBRARY="/usr/local/cuda/lib64/libcudnn.so"
export CUB_INCLUDE_DIR="/usr/local/cuda/include"
$ source ~/.bashrc
注意执行完上述指令后要重新打开一个终端才会起作用。另外~/.bashrc只影响当前用户(sudo -H python372 setup.py build develop),如果要给所有用户(sudo python372 setup.py build develop)添加,就要使用这个路径:
$ sudo gedit /etc/profile
#在文件末尾添加下面的路径和变量,并保存
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
export pybind11_DIR="/home/matthew/dev/pytorch/third_party/pybind11/tools"
export pybind11_INCLUDE_DIR="/home/matthew/dev/pytorch/third_party/pybind11/include/pybind11"
export CUDNN_INCLUDE_DIR="/usr/local/cuda/include"
export CUDNN_LIBRARY="/usr/local/cuda/lib64/libcudnn.so"
export CUB_INCLUDE_DIR="/usr/local/cuda/include"
$ source /etc/profile
完事后用
$ export -p
命令查看一下环境变量是否已经起作用了。
参考: https://blog.csdn.net/tanmx219/article/details/86534758
还有一个变量可以在编译前临时设置一下,不要放到/etc/profile中去,以免对其他程序造成影响(如果是我的话,这里会把变量名改成TORCH_DEBUG之类的,避免DEBUG这种过于通用的命名):
export DEBUG=1
export REL_WITH_DEB_INFO=1
我也是看了setup.py中的源码才知道C语言debug版本的源码调试需要这个开关,源码内容是
#### env.py ####
def check_env_flag(name, default=''):
return os.getenv(name, default).upper() in ['ON', '1', 'YES', 'TRUE', 'Y']
#### config.py ####
DEBUG = check_env_flag('DEBUG')
REL_WITH_DEB_INFO = check_env_flag('REL_WITH_DEB_INFO')
#### setup.py ####
if DEBUG:
if IS_WINDOWS:
extra_link_args.append('/DEBUG:FULL')
else:
extra_compile_args += ['-O0', '-g']
extra_link_args += ['-O0', '-g']
if REL_WITH_DEB_INFO:
if IS_WINDOWS:
extra_link_args.append('/DEBUG:FULL')
else:
extra_compile_args += ['-g']
extra_link_args += ['-g']
可见,export DEBUG=1, ON, YES, TRUE, 或Y的效果是相同的,都会开启DEBUG模式(编译和链接时的‘-g’开关)。
在不调试的情况下是release版本,为了追求性能优化而抛弃了调试信息。DEBUG版本为了追求更全面的调试信息而放弃了速度; 如果用户既需要调试代码,需要速度快一点,那么便可以开始考虑REL_WITH_DEB_INFO这个版本了。
关于各个模块的安装
pybind11
sudo -H pip372 install pybind11
CUDNN
参考:https://blog.csdn.net/tanmx219/article/details/86553485
如果只是要安装cudnn,python不用源码C语言调试的话,那么anaconda的命令仍然是首选,一条指令就搞定了,如下
conda install cudnn
安装OpneMPI
sudo apt-get install openmpi-bin openmpi-common openssh-client openssh-server
libopenmpi-dbg libopenmpi-dev
警告Warning
NO.1 host_defines.h:54:2: warning
In file included from /home/matthew/dev/pytorch/cmake/../third_party/eigen/Eigen/src/Core/util/ConfigureVectorization.h:374:0,
from /home/matthew/dev/pytorch/cmake/../third_party/eigen/Eigen/Core:22,
from /home/matthew/dev/pytorch/caffe2/utils/eigen_utils.h:6,
from /home/matthew/dev/pytorch/caffe2/operators/elementwise_ops.h:15,
from /home/matthew/dev/pytorch/caffe2/operators/abs_op.h:6,
from /home/matthew/dev/pytorch/caffe2/operators/abs_op.cu:1:
/usr/local/cuda/include/host_defines.h:54:2: warning: #warning "host_defines.h is an internal header file and must not be used directly. This file will be removed in a future CUDA release. Please use cuda_runtime_api.h or cuda_runtime.h instead." [-Wcpp]
该警告可以忽略,产生这个警告的原因是,pytorch/third_party/eigen/Eigen/src/Core/util/ConfigureVectorization.h:374行这里直接使用了定义
#if defined(EIGEN_HAS_CUDA_FP16)
#include <host_defines.h>
#include <cuda_fp16.h>
#endif
所以这个是eigen没有使用cuda_runtime_api.h 或 cuda_runtime.h 而直接引用了host_defines.h所引起的。
NO.2 WARNING: 'develop' is not building C++ code incrementally
because ninja is not installed. Run this to enable it:
> pip install ninja
===>>>
sudo -H pip372 install ninja
setup.py
pytorch使用了setuptools来编译安装torch,setup.py中真正执行编译的部分是函数def build_libs(libs),它通过
subprocess.call调用../tools/build_pytorch_libs.sh (在windows下是build_pytorch_libs.bat)来编译生成pytorch库文件。
后记
如果不是搞C语言源码调试的话,还是用anaconda吧,省掉的事情不是一点点。Linux里面的各种依赖太麻烦了。anacoda中可以非常轻松地进行python包的调试,不过安装时也要使用build develop。
如何使用gdb调试python,请参考Louie Lu的blog:A guide from parser to objects, observed using GDB
参考:http://lsi.ugr.es/jmantas/pdp/ayuda/datos/instalaciones/Install_OpenMPI_en.pdf
torch-cudnn参考:
https://www.cnblogs.com/darkknightzh/p/5668471.html (Ubuntu16 中安装torch版的cudnn)
https://github.com/NVIDIA/torch-cudnn
https://blog.csdn.net/Hungryof/article/details/51557666 (ubuntu下100%成功安装torch,同时配置cuda和cudnn)