
背景
本文以PyTorch 1.0為基礎。PyTorch的編譯首先是python風格的編譯,使用了python的setuptools編譯系統。以最基本的編譯安裝指令python setup.py install 為例,這一編譯過程包含了如下幾個主要階段:
1,setup.py入口;
2,提前檢查依賴項;
3,使用cmake生成Makefile;
4,Make指令——中間源檔案的産生;
5,Make指令——編譯三方庫;
6,Make指令——生成靜态庫、動态庫、可執行檔案;
7,Make指令——拷貝檔案到合适路徑下;
8,setuptools之build_py;
9,setuptools之build_ext;
10,setuptools之install_lib。
setup.py入口
pytorch的編譯是從下面這條指令開始的:
python
這是典型的Python convention,使用python setuptools包中的setup函數來進行install。setup函數接收了幾個關鍵的東西:
1,package的名字,從環境變量裡取TORCH_PACKAGE_NAME的值,取不到的話就是"torch";
2,version,gemfield使用的時候版本為version = '1.1.0a0';
3,ext_modules,用來指定使用C/C++編寫的子產品,這個不像普通的python子產品那麼容易找到規律。畢竟用C/C++的時候,你得指定源檔案、編譯的參數、頭檔案路徑、連結庫路徑等(setuptools工具又不是神仙,它怎麼猜的出)。是以使用ext_modules keyword參數來指定所有需要這樣編譯的子產品,用一個list來描述,list中的每個元素是一個Extension執行個體,用來描述編譯C++所需要的源檔案、編譯的參數、頭檔案路徑、連結庫路徑等。PyTorch中,這樣的ext_modules有:
torch._C (源檔案為torch/csrc/stub.cpp,目的so為torch_python.so)
torch._dl(源檔案為torch/csrc/dl.c)
torch._nvrtc (源檔案為torch/csrc/nvrtc.cpp)
#以及3個caffe2擴充:
caffe2.python.caffe2_pybind11_state
caffe2.python.caffe2_pybind11_state_gpu
caffe2.python.caffe2_pybind11_state_hip
4,cmdclass,setup的操作參數,是一個字典:
'create_version_file': <class '__main__.create_version_file'>
'build': <class '__main__.build'>
'build_py': <class '__main__.build_py'>
'build_ext': <class '__main__.build_ext'>
'build_deps': <class '__main__.build_deps'>
'build_module': <class '__main__.build_module'>
'rebuild': <class '__main__.rebuild'>
'develop': <class '__main__.develop'>
'install': <class '__main__.install'>
'clean': <class '__main__.clean'>
'build_caffe2': <class '__main__.build_dep'>,
'rebuild_caffe2': <class '__main__.rebuild_dep'
因為我們執行的是python setup.py install,是以這裡将會調用__main__.install(中的run方法)。install所做的工作就是調用build_deps和install。Gemfield将在下面的章節中探讨。
5,packages,指定項目中python源代碼的路徑。通常使用find_packages() 預設在和setup.py同一目錄下搜尋各個含有 __init__.py的包;
6,entry_points使用python的機制來注冊你的指令,比如在PyTorch的setup.py中,entry_points如下所示:
entry_points = {
'console_scripts': [
'convert-caffe2-to-onnx = caffe2.python.onnx.bin.conversion:caffe2_to_onnx',
'convert-onnx-to-caffe2 = caffe2.python.onnx.bin.conversion:onnx_to_caffe2',
]
}
以convert-caffe2-to-onnx為例,setup.py會在PATH路徑下生成convert-caffe2-to-onnx檔案,這個檔案的内容如下:
#!/root/miniconda3/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'torch==1.1.0a0+ffd6138','console_scripts','convert-caffe2-to-onnx'
__requires__ = 'torch==1.1.0a0+ffd6138'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script.pyw?|.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('torch==1.1.0a0+ffd6138', 'console_scripts', 'convert-caffe2-to-onnx')()
)
7,package_data,指定将什麼檔案打包到package裡,使用這個參數一般是因為有些要打包的檔案是動态生成的(也就是執行setup.py過程中生成的)。在PyTorch裡,package_data主要是一些動态庫和頭檔案。
提前檢查依賴項
1,檢查以下三方庫的CMakeLists.txt:
"gloo", "CMakeLists.txt"
"pybind11", "CMakeLists.txt"
'cpuinfo', 'CMakeLists.txt'
'onnx', 'CMakeLists.txt'
'QNNPACK', 'CMakeLists.txt'
'fbgemm', 'CMakeLists.txt'
2,檢查必備的python 包
檢查yaml、typing是否能夠import。
使用cmake生成Makefile
使用tools/build_pytorch_libs.sh腳本來編譯。在預設情況下,PyTorch會使用下面的指令和環境變量來開始caffe2的編譯:
#command
bash ../tools/build_pytorch_libs.sh --use-cuda --use-fbgemm --use-nnpack --use-mkldnn --use-qnnpack caffe2
#env
CUDNN_VERSION: 7.4.1.5
HOSTNAME: skyweb
NVIDIA_REQUIRE_CUDA: cuda>=9.0
......
PYTORCH_PYTHON_LIBRARY: /root/miniconda3/lib/libpython3.7m.so.1.0
PYTORCH_PYTHON_INCLUDE_DIR: /root/miniconda3/include/python3.7m
PYTORCH_BUILD_VERSION: 1.1.0a0+ffd6138
CMAKE_PREFIX_PATH: /root/miniconda3/lib/python3.7/site-packages
VERBOSE_SCRIPT: 1
這個指令會建立torch/lib/tmp_install目錄,接着使用cmake工具生成Makefile:
cmake /home/gemfield/github/pytorch -DPYTHON_EXECUTABLE=/root/miniconda3/bin/python -DPYTHON_LIBRARY=/root/miniconda3/lib/libpython3.7m.so.1.0 -DPYTHON_INCLUDE_DIR=/root/miniconda3/include/python3.7m -DBUILDING_WITH_TORCH_LIBS=ON -DTORCH_BUILD_VERSION=1.1.0a0+ffd6138 -DCMAKE_BUILD_TYPE=Release -DBUILD_TORCH=ON -DBUILD_PYTHON=ON -DBUILD_SHARED_LIBS=ON -DBUILD_BINARY=OFF -DBUILD_TEST=ON -DINSTALL_TEST=ON -DBUILD_CAFFE2_OPS=ON -DONNX_NAMESPACE=onnx_torch -DUSE_CUDA=1 -DUSE_DISTRIBUTED=ON -DUSE_FBGEMM=1 -DUSE_NUMPY= -DNUMPY_INCLUDE_DIR= -DUSE_SYSTEM_NCCL=ON -DNCCL_INCLUDE_DIR=/usr/include -DNCCL_ROOT_DIR=/usr/ -DNCCL_SYSTEM_LIB=/usr/lib/x86_64-linux-gnu/libnccl.so.2.3.7 -DCAFFE2_STATIC_LINK_CUDA=0 -DUSE_ROCM=0 -DUSE_NNPACK=1 -DUSE_LEVELDB=OFF -DUSE_LMDB=OFF -DUSE_OPENCV=OFF -DUSE_QNNPACK=1 -DUSE_TENSORRT=OFF -DUSE_FFMPEG=OFF -DUSE_SYSTEM_EIGEN_INSTALL=OFF -DCUDNN_INCLUDE_DIR=/usr/include/ -DCUDNN_LIB_DIR=/usr/lib/x86_64-linux-gnu/ -DCUDNN_LIBRARY=/usr/lib/x86_64-linux-gnu/libcudnn.so.7 -DUSE_MKLDNN=1 -DNCCL_EXTERNAL=1 -DCMAKE_INSTALL_PREFIX=/home/gemfield/github/pytorch/torch/lib/tmp_install -DCMAKE_C_FLAGS= -DCMAKE_CXX_FLAGS= '-DCMAKE_EXE_LINKER_FLAGS= -Wl,-rpath,$ORIGIN ' '-DCMAKE_SHARED_LINKER_FLAGS= -Wl,-rpath,$ORIGIN ' -DTHD_SO_VERSION=1 -DCMAKE_PREFIX_PATH=/root/miniconda3/lib/python3.7/site-packages
cmake的關鍵configure資訊如下(Makefile等配置資訊會寫到build目錄下):
-- General:
-- BLAS : MKL
-- CXX flags : -Wno-deprecated -fvisibility-inlines-hidden -fopenmp -DUSE_FBGEMM -O2 -fPIC -Wno-narrowing -Wall -Wextra -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-unused-but-set-variable -Wno-maybe-uninitialized
-- Compile definitions : TH_BLAS_MKL;ONNX_NAMESPACE=onnx_torch;USE_GCC_ATOMICS=1;HAVE_MMAP=1;_FILE_OFFSET_BITS=64;HAVE_SHM_OPEN=1;HAVE_SHM_UNLINK=1;HAVE_MALLOC_USABLE_SIZE=1
-- CMAKE_PREFIX_PATH : /root/miniconda3/lib/python3.7/site-packages
......
-- Public Dependencies : Threads::Threads;caffe2::mkl;caffe2::mkldnn
-- Private Dependencies : qnnpack;nnpack;cpuinfo;fbgemm;fp16;gloo;aten_op_header_gen;onnxifi_loader;rt;gcc_s;gcc;dl
Make指令——中間源檔案的産生
cmake生成Makefile後,編譯系統接着調用make指令來進行編譯和install:
make install -j24
這個編譯過程一共産生兩種檔案(Linux上):
1,根據模闆生成源檔案,包含cpp檔案和Python 檔案(大部分是UT);
2,生成.o/.a檔案 、動态庫 .so檔案、可執行檔案。
1,ATen部分cpp檔案:
third_party/protobuf/src/google/protobuf/compiler/js/well_known_types_embed.cc
build/aten/src/ATen/CPUByteType.cpp
build/aten/src/ATen/CPUByteType.h
build/aten/src/ATen/CPUCharType.cpp
build/aten/src/ATen/CPUCharType.h
build/aten/src/ATen/CPUDoubleType.cpp
build/aten/src/ATen/CPUDoubleType.h
build/aten/src/ATen/CPUFloatType.cpp
build/aten/src/ATen/CPUFloatType.h
build/aten/src/ATen/CPUGenerator.h
build/aten/src/ATen/CPUHalfType.cpp
build/aten/src/ATen/CPUHalfType.h
build/aten/src/ATen/CPUIntType.cpp
build/aten/src/ATen/CPUIntType.h
build/aten/src/ATen/CPULongType.cpp
build/aten/src/ATen/CPULongType.h
build/aten/src/ATen/CPUShortType.cpp
build/aten/src/ATen/CPUShortType.h
build/aten/src/ATen/Declarations.yaml
build/aten/src/ATen/Functions.h
build/aten/src/ATen/LegacyTHCPUByteDispatcher.cpp
build/aten/src/ATen/LegacyTHCPUByteDispatcher.h
build/aten/src/ATen/LegacyTHCPUCharDispatcher.cpp
build/aten/src/ATen/LegacyTHCPUCharDispatcher.h
build/aten/src/ATen/LegacyTHCPUDoubleDispatcher.cpp
build/aten/src/ATen/LegacyTHCPUDoubleDispatcher.h
......
build/include/sleef.h
build/sleef/src/libm/include/renameavx2.h
build/sleef/src/libm/include/renameavx2128.h
build/sleef/src/libm/include/renamefma4.h
build/sleef/src/libm/include/renamesse4.h
build/sleef/src/libm/include/renamesse2.h
build/sleef/src/libm/include/renamedsp128.h
build/sleef/src/libm/dispsse.c
2,torch部分cpp檔案:
torch/csrc/nn/THNN.cpp
torch/csrc/nn/THCUNN.cpp
torch/csrc/autograd/generated/VariableType.h
torch/csrc/autograd/generated/VariableType_0.cpp
torch/csrc/autograd/generated/VariableType_1.cpp
torch/csrc/autograd/generated/VariableType_2.cpp
torch/csrc/autograd/generated/VariableType_3.cpp
torch/csrc/autograd/generated/VariableType_4.cpp
torch/csrc/autograd/generated/Functions.h
torch/csrc/autograd/generated/Functions.cpp
torch/csrc/autograd/generated/python_functions.h
torch/csrc/autograd/generated/python_functions.cpp
torch/csrc/autograd/generated/python_variable_methods.cpp
torch/csrc/autograd/generated/python_variable_methods_dispatch.h
torch/csrc/autograd/generated/python_torch_functions.cpp
torch/csrc/autograd/generated/python_torch_functions_dispatch.h
torch/csrc/autograd/generated/python_nn_functions.cpp
torch/csrc/autograd/generated/python_nn_functions.h
torch/csrc/autograd/generated/python_nn_functions_dispatch.h
torch/csrc/autograd/generated/variable_factories.h
torch/csrc/jit/generated/register_aten_ops_0.cpp
torch/csrc/jit/generated/register_aten_ops_1.cpp
torch/csrc/jit/generated/register_aten_ops_2.cpp
3,python檔案部分:
contrib/aten/__init__.py
contrib/aten/docs/__init__.py
contrib/aten/docs/sample.py
contrib/aten/gen_op.py
contrib/cuda-convnet2/__init__.py
contrib/cuda-convnet2/convdata.py
......
python/helpers/train.py
......
python/layers/batch_lr_loss.py
python/layers/batch_mse_loss.py
python/layers/batch_normalization.py
python/layers/batch_sigmoid_cross_entropy_loss.py
python/layers/batch_softmax_loss.py
python/layers/blob_weighted_sum.py
......
python/modeling/net_modifier.py
......
python/onnx/backend.py
......
python/predictor/mobile_exporter.py
......
quantization/server/utils.py
Make指令——編譯三方庫
在開始階段會編譯third_party目錄下的依賴包(基本是facebook和谷歌公司貢獻的)。
#Facebook開源的cpuinfo,檢測cpu資訊的
third_party/cpuinfo
#Facebook開源的神經網絡模型交換格式,
#目前Pytorch、caffe2、ncnn、coreml等都可以對接
third_party/onnx
#FB (Facebook) + GEMM (General Matrix-Matrix Multiplication)
#Facebook開源的低精度高性能的矩陣運算庫,目前作為caffe2 x86的量化運算符的backend。
third_party/fbgemm
#谷歌開源的benchmark庫
third_party/benchmark
#谷歌開源的protobuf
third_party/protobuf
#谷歌開源的UT架構
third_party/googletest
#Facebook開源的面向移動平台的神經網絡量化加速庫
third_party/QNNPACK
#跨機器訓練的通信庫
third_party/gloo
#Intel開源的使用MKL-DNN做的神經網絡加速庫
third_party/ideep
Make指令——生成靜态庫、動态庫、可執行檔案
編譯過程中生成的.a檔案:
lib/libprotobuf-lite.a
lib/libprotobuf.a
lib/libprotoc.a
lib/libclog.a
lib/libcpuinfo.a
lib/libqnnpack.a
lib/libcpuinfo_internals.a
lib/libpthreadpool.a
lib/libnnpack_reference_layers.a
lib/libnnpack.a
lib/libgtest.a
lib/libgtest_main.a
lib/libbenchmark.a
lib/libbenchmark_main.a
lib/libasmjit.a
lib/libfbgemm.a
lib/libgloo.a
lib/libgloo_cuda.a
lib/libgloo_builder.a
lib/libonnxifi_loader.a
lib/libonnx_proto.a
lib/libonnx.a
lib/libmkldnn.a
lib/libCaffe2_perfkernels_avx2.a
lib/libcaffe2_protos.a
lib/libsleef.a
lib/libCaffe2_perfkernels_avx.a
lib/libCaffe2_perfkernels_avx512.a
lib/libTHD.a
lib/libc10d.a
編譯過程生成的可執行檔案:
bin/js_embed
bin/protoc
bin/c10_TypeList_test
bin/c10_TensorTypeId_test
......
bin/c10_cuda_CUDATest
bin/mkrename
bin/mkdisp
bin/utility_ops_gpu_test
.....
bin/blob_gpu_test
bin/cuda_cudnn_test
bin/parallel_net_test
bin/operator_test
......
bin/test_jit
bin/test_api
......
bin/c10_utils_cpu_test
編譯過程中生成的.so動态庫:
lib/libonnxifi.so
lib/libonnxifi_dummy.so
lib/libc10.so
lib/libc10_cuda.so
lib/libcaffe2.so
lib/libcaffe2_gpu.so
python/caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so
python/caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so
lib/libshm.so
lib/libtorch.so
lib/libtorch_python.so
lib/libc10d_cuda_test.so
lib/libcaffe2_detectron_ops_gpu.so
lib/libcaffe2_module_test_dynamic.so
lib/libcaffe2_observers.so
其中:
1,lib/libc10.so由下列源檔案編譯生成:
c10/*.cpp
2,lib/libc10_cuda.so由下列源檔案編譯生成:
c10/cuda/CUDAStream.cpp
c10/cuda/impl/CUDAGuardImpl.cpp
c10/cuda/impl/CUDATest.cpp
3,lib/libshm.so由下列源檔案編譯生成:
torch/lib/libshm/core.cpp
4,lib/libcaffe2.so由下列源檔案編譯生成:
aten/*.cpp
caffe2/core/*.cpp
caffe2/operators/*.cpp
caffe2/utils/*.cpp
caffe2/onnx/*.cpp
caffe2/quantization/*.cpp
caffe2/sgd/*.cpp
...
5,lib/libcaffe2_gpu.so由下列源檔案編譯生成:
aten/src/TH/*
aten/src/THCUNN/*
aten/src/ATen/*
caffe2/operators/*.cu
caffe2/sgd/*cu
aten/src/ATen/cuda/*
aten/src/THC/*
aten/src/ATen/cudnn/*
caffe2/operators/*op_cudnn.cc
caffe2/operators/*_gpu.cc
...
6,caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so由下列源檔案編譯生成:
caffe2/python/pybind_state.cc
caffe2/python/pybind_state_dlpack.cc
caffe2/python/pybind_state_nomni.cc
caffe2/python/pybind_state_registry.cc
caffe2/python/pybind_state_int8.cc
caffe2/python/pybind_state_ideep.cc
7,caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so由下列源檔案編譯生成:
caffe2/python/pybind_state.cc
caffe2/python/pybind_state_dlpack.cc
caffe2/python/pybind_state_nomni.cc
caffe2/python/pybind_state_registry.cc
caffe2/python/pybind_state_int8.cc
caffe2/python/pybind_state_ideep.cc
caffe2/python/pybind_state_gpu.cc
8,lib/libtorch.so由下列源檔案編譯生成:
torch/csrc/autograd/*.cpp
torch/csrc/autograd/generated/*.cpp
torch/csrc/jit/*.cpp
torch/csrc/utils/*.cpp
torch/csrc/api/*.cpp
9,lib/libtorch_python.so由下列源檔案編譯生成:
torch/lib/THD/*.cpp
torch/lib/c10d/*.cpp
torch/csrc/*.cpp
torch/csrc/*.cpp
torch/csrc/autograd/generated/python_*.cpp
torch/csrc/autograd/python_*.cpp
torch/csrc/jit/*.cpp
torch/csrc/utils/*.cpp
torch/csrc/cuda/*.cpp
torch/csrc/distributed/*.cpp
注意libtorch_python.so編譯的時候也需要連結libtorch.so檔案。
Make指令——拷貝檔案到合适路徑下
這一步的核心工作就是使用make install來将make過程中産生的檔案:
pytorch/torch/lib/tmp_install/lib/libTHD.a
pytorch/torch/lib/tmp_install/lib/libasmjit.a
pytorch/torch/lib/tmp_install/lib/libc10.so
pytorch/torch/lib/tmp_install/lib/libc10_cuda.so
pytorch/torch/lib/tmp_install/lib/libc10d.a
pytorch/torch/lib/tmp_install/lib/libcaffe2.so
pytorch/torch/lib/tmp_install/lib/libcaffe2_detectron_ops_gpu.so
pytorch/torch/lib/tmp_install/lib/libcaffe2_gpu.so
pytorch/torch/lib/tmp_install/lib/libcaffe2_module_test_dynamic.so
pytorch/torch/lib/tmp_install/lib/libcaffe2_observers.so
pytorch/torch/lib/tmp_install/lib/libclog.a
pytorch/torch/lib/tmp_install/lib/libcpuinfo.a
pytorch/torch/lib/tmp_install/lib/libfbgemm.a
pytorch/torch/lib/tmp_install/lib/libgloo.a
pytorch/torch/lib/tmp_install/lib/libgloo_builder.a
pytorch/torch/lib/tmp_install/lib/libgloo_cuda.a
pytorch/torch/lib/tmp_install/lib/libmkldnn.a
pytorch/torch/lib/tmp_install/lib/libnnpack.a
pytorch/torch/lib/tmp_install/lib/libonnx.a
pytorch/torch/lib/tmp_install/lib/libonnx_proto.a
pytorch/torch/lib/tmp_install/lib/libonnxifi.so
pytorch/torch/lib/tmp_install/lib/libonnxifi_dummy.so
pytorch/torch/lib/tmp_install/lib/libonnxifi_loader.a
pytorch/torch/lib/tmp_install/lib/libprotobuf-lite.a
pytorch/torch/lib/tmp_install/lib/libprotobuf.a
pytorch/torch/lib/tmp_install/lib/libprotoc.a
pytorch/torch/lib/tmp_install/lib/libpthreadpool.a
pytorch/torch/lib/tmp_install/lib/libqnnpack.a
pytorch/torch/lib/tmp_install/lib/libshm.so
pytorch/torch/lib/tmp_install/lib/libsleef.a
pytorch/torch/lib/tmp_install/lib/libtorch.so
pytorch/torch/lib/tmp_install/lib/libtorch.so.1
pytorch/torch/lib/tmp_install/lib/libtorch_python.so
pytorch/torch/lib/tmp_install/lib/pkgconfig
pytorch/torch/lib/tmp_install/lib/python3.7
拷貝到pytorch/torch/lib目錄下。使用的是rsync指令:
rsync -lptgoD -r /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libTHD.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libasmjit.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libc10.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libc10_cuda.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libc10d.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcaffe2.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcaffe2_detectron_ops_gpu.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcaffe2_gpu.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcaffe2_module_test_dynamic.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcaffe2_observers.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libclog.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libcpuinfo.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libfbgemm.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libgloo.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libgloo_builder.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libgloo_cuda.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libmkldnn.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libnnpack.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libonnx.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libonnx_proto.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libonnxifi.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libonnxifi_dummy.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libonnxifi_loader.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libprotobuf-lite.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libprotobuf.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libprotoc.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libpthreadpool.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libqnnpack.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libshm.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libsleef.a /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libtorch.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libtorch.so.1 /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/libtorch_python.so /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/pkgconfig /home/gemfield/github/pytorch/torch/lib/tmp_install/lib/python3.7 .
setuptools之build_py
這個步驟就是來生成python的package的
Python部分,在這個階段,我們要做的工作主要就是拷貝檔案到符合package目錄規範的檔案夾裡:
1,拷貝一些cpp的header檔案到
build/lib.linux-x86_64-3.7;
2,拷貝一些py檔案到
build/lib.linux-x86_64-3.7;
3,拷貝一些可執行檔案到
build/lib.linux-x86_64-3.7;
4,拷貝一些cuda header檔案到
build/lib.linux-x86_64-3.7;
5,拷貝一些cmake檔案到
build/lib.linux-x86_64-3.7;
6,拷貝一些zip檔案到
build/lib.linux-x86_64-3.7;
7,拷貝一些so檔案到
build/lib.linux-x86_64-3.7: 動态庫so檔案比較重要,在build_py階段拷貝到build/lib.linux-x86_64-3.7的so檔案有:torch/lib/libcaffe2_module_test_dynamic.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libtorch.so.1 -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libonnxifi_dummy.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libtorch.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libc10.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libshm.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libcaffe2_observers.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libonnxifi.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libcaffe2.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libtorch_python.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libcaffe2_gpu.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libc10_cuda.so -> build/lib.linux-x86_64-3.7/torch/lib
torch/lib/libcaffe2_detectron_ops_gpu.so -> build/lib.linux-x86_64-3.7/torch/lib
setuptools之build_ext
這個步驟是用來編譯python的c/c++擴充插件的。先拷貝兩個共享庫到合适的目錄下:
1,拷貝caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so 到 build/lib.linux-x86_64-3.7/caffe2/python/caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so(位于
build/lib.linux-x86_64-3.7/caffe2/目錄下);
2,拷貝caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so到build/lib.linux-x86_64-3.7/caffe2/python/caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so(位于
build/lib.linux-x86_64-3.7/caffe2/目錄下)。
編譯torch._C子產品:使用c++11标準和_THP_CORE 、ONNX_NAMESPACE=onnx_torch宏,用torch/csrc/stub.cpp源檔案,連結libshm.so、libtorch_python.so、libcaffe2_gpu.so生成_C.cpython-37m-x86_64-linux-gnu.so 擴充插件(位于
build/lib.linux-x86_64-3.7/torch/目錄下):
gcc -pthread -B /root/miniconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/root/miniconda3/include/python3.7m -c torch/csrc/stub.cpp -o build/temp.linux-x86_64-3.7/torch/csrc/stub.o -D_THP_CORE -DONNX_NAMESPACE=onnx_torch -std=c++11 -Wall -Wextra -Wno-strict-overflow -Wno-unused-parameter -Wno-missing-field-initializers -Wno-write-strings -Wno-unknown-pragmas -Wno-deprecated-declarations -fno-strict-aliasing -Wno-missing-braces
g++ -pthread -shared -B /root/miniconda3/compiler_compat -L/root/miniconda3/lib -Wl,-rpath=/root/miniconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/torch/csrc/stub.o -L/home/gemfield/github/pytorch/torch/lib -L/usr/local/cuda/lib64 -lshm -ltorch_python -o build/lib.linux-x86_64-3.7/torch/_C.cpython-37m-x86_64-linux-gnu.so -Wl,--no-as-needed /home/gemfield/github/pytorch/torch/lib/libcaffe2_gpu.so -Wl,--as-needed -Wl,-rpath,$ORIGIN/lib
編譯torch._dl子產品: 使用torch/csrc/dl.c編譯出_dl.cpython-37m-x86_64-linux-gnu.so擴充插件(位于
build/lib.linux-x86_64-3.7/torch/目錄下):
gcc -pthread -B /root/miniconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/root/miniconda3/include/python3.7m -c torch/csrc/dl.c -o build/temp.linux-x86_64-3.7/torch/csrc/dl.o
gcc -pthread -shared -B /root/miniconda3/compiler_compat -L/root/miniconda3/lib -Wl,-rpath=/root/miniconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/torch/csrc/dl.o -o build/lib.linux-x86_64-3.7/torch/_dl.cpython-37m-x86_64-linux-gnu.so
編譯torch._nvrtc子產品: 使用c++11标準,用torch/csrc/nvrtc.cpp源檔案和_THP_CORE、ONNX_NAMESPACE=onnx_torch宏,并且連結libcuda.so、 -libnvrtc.so庫,進而生成_nvrtc.cpython-37m-x86_64-linux-gnu.so擴充插件(位于
build/lib.linux-x86_64-3.7/torch/目錄下):
gcc -pthread -B /root/miniconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/gemfield/github/pytorch -I/root/miniconda3/include/python3.7m -c torch/csrc/nvrtc.cpp -o build/temp.linux-x86_64-3.7/torch/csrc/nvrtc.o -D_THP_CORE -DONNX_NAMESPACE=onnx_torch -std=c++11 -Wall -Wextra -Wno-strict-overflow -Wno-unused-parameter -Wno-missing-field-initializers -Wno-write-strings -Wno-unknown-pragmas -Wno-deprecated-declarations -fno-strict-aliasing -Wno-missing-braces
g++ -pthread -shared -B /root/miniconda3/compiler_compat -L/root/miniconda3/lib -Wl,-rpath=/root/miniconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/torch/csrc/nvrtc.o -L/home/gemfield/github/pytorch/torch/lib -L/usr/local/cuda/lib64 -L/usr/local/cuda/lib64/stubs -o build/lib.linux-x86_64-3.7/torch/_nvrtc.cpython-37m-x86_64-linux-gnu.so -Wl,-rpath,$ORIGIN/lib -Wl,--no-as-needed -lcuda -lnvrtc
setuptools之install_lib
這一步完成了安裝。
1,拷貝共享庫到python lib路徑下:
libcaffe2_module_test_dynamic.so -> python3.7/site-packages/torch/lib
libtorch.so.1 -> /root/miniconda3/lib/python3.7/site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libonnxifi_dummy.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libtorch.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libc10.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libshm.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libcaffe2_observers.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/torch_shm_manager -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libonnxifi.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libcaffe2.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libtorch_python.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libcaffe2_gpu.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libc10_cuda.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/lib/libcaffe2_detectron_ops_gpu.so -> */site-packages/torch/lib
build/lib.linux-x86_64-3.7/torch/_dl.cpython-37m-x86_64-linux-gnu.so -> */site-packages/torch
build/lib.linux-x86_64-3.7/torch/_C.cpython-37m-x86_64-linux-gnu.so -> */site-packages/torch
build/lib.linux-x86_64-3.7/torch/_nvrtc.cpython-37m-x86_64-linux-gnu.so -> */site-packages/torch
build/lib.linux-x86_64-3.7/caffe2/python/caffe2_pybind11_state_gpu.cpython-37m-x86_64-linux-gnu.so -> */site-packages/caffe2/python
build/lib.linux-x86_64-3.7/caffe2/python/caffe2_pybind11_state.cpython-37m-x86_64-linux-gnu.so -> */site-packages/caffe2/python
2,拷貝header檔案到python路徑下;
3,拷貝py檔案到python路徑下;
4,安裝egg_info,也就是torch.egg-info:
running install_egg_info
running egg_info
writing torch.egg-info/PKG-INFO
writing dependency_links to torch.egg-info/dependency_links.txt
writing entry points to torch.egg-info/entry_points.txt
writing top-level names to torch.egg-info/top_level.txt
reading manifest file 'torch.egg-info/SOURCES.txt'
writing manifest file 'torch.egg-info/SOURCES.txt'
removing '/root/miniconda3/lib/python3.7/site-packages/torch-1.1.0a0+ffd6138-py3.7.egg-info' (and everything under it)
Copying torch.egg-info to /root/miniconda3/lib/python3.7/site-packages/torch-1.1.0a0+ffd6138-py3.7.egg-info
5,注冊entry_points:
Installing convert-caffe2-to-onnx script to /root/miniconda3/bin
Installing convert-onnx-to-caffe2 script to /root/miniconda3/bin
慶祝
這之後,你就可以愉快的import torch了。讓我們再次滿懷喜悅的回憶下,import的torch是怎麼得來的:
import
1,Python會找到sys.path中的torch目錄,然後找到其中的__init__.py;
2,在這個檔案中,會import torch._C,在Python3.7環境中,會加載torch目錄中的_C.cpython-37m-x86_64-linux-gnu.so 動态擴充庫;
3,_C.cpython-37m-x86_64-linux-gnu.so 動态庫是由源檔案torch/csrc/stub.cpp源檔案,并且連結libtorch.so、libshm.so、libtorch_python.so、libcaffe2.so、libcaffe2_gpu.so、libc10_cuda.so、libc10.so生成的;當然不止這些庫,還連結其它的三方庫,這裡gemfield隻列出了由PyTorch倉庫中編譯出來的庫。
另外,你也可以使用下面的指令佐證下:
[email protected]:~# ldd ./build/lib.linux-x86_64-3.7/torch/_C.cpython-37m-x86_64-linux-gnu.so | grep -i pytorch
libshm.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libshm.so (0x00007f3f848c0000)
libtorch_python.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libtorch_python.so (0x00007f3f83e55000)
libcaffe2_gpu.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libcaffe2_gpu.so (0x00007f3f7263b000)
libcaffe2.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libcaffe2.so (0x00007f3f6f57d000)
libc10.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libc10.so (0x00007f3f6f34e000)
libtorch.so.1 => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libtorch.so.1 (0x00007f3f6df54000)
libc10_cuda.so => /home/gemfield/github/pytorch/./build/lib.linux-x86_64-3.7/torch/lib/libc10_cuda.so (0x00007f3f68d61000)
4,而這裡列出來的libtorch.so、libshm.so、libtorch_python.so、libcaffe2.so、libcaffe2_gpu.so、libc10_cuda.so、libc10.so,已經由Gemfield在前文說明過了。