1.Python
whl 文件和 egg 文件
可以执行和效率是两码事
setup.py用来编译和安装扩展模块。负责编译c++模块,封装成python可以调用的形式
所有能被整合或导入到其它python脚本的代码,都可以被称为扩展
Python调用C库比较简单,不经过任何封装打包成so,直接使用python的ctypes调用即可。
Python C++库 先将C++模块编译成动态链接库.so,再利用python模块ctypes进行调用
(1)C++类文件:pycallclass.cpp
(2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。
(3)Python调用动态库的文件:pycallclass.py
2.Pytorch扩展
torch的底层是由c语言编写。而到了pytorch这里,底层大部分的语言修改了一些,
但大部分依然是C,只是编译的环境由C转变为C++
因为效率以及速度-还有深度的自定义。
pytorch的C++ extension和python的c/c++ extension其实原理差不多,
本质上都是为了扩展各自的功能,也为了使程序运行更加有效率,
差别在于pytorch的C++ extension实施步骤
较python的c/c++ extension的要简化一些。
cat /usr/local/cuda/version.txt
CppExtension
CUDAExtension
用pybind11构建共享库形式的C++和CUDA扩展
第一步:使用C++编写算子的forward函数和backward函数
第二步:将该算子的forward函数和backward函数使用pybind11绑定到python上
第三步:使用setuptools/JIT/CMake编译打包C++工程为so文件
python 提供的setuptools来编译并加载 C++ 代码。
4.编译安装,在 python 中调用 C++ 扩展接口
训练端和部署端
一般的深度学习项目,
训练时为了加快速度,会使用多 GPU 分布式训练。
但在部署推理时,为了降低成本,
往往使用单个 GPU 机器甚至嵌入式平台(比如 NVIDIA Jetson)进行部署,
部署端也要有与训练时相同的深度学习环境
3.python的构建工具setup.py ,
在 setup.py 文件中写明依赖的库和版本,
然后到目标机器上使用 python setup.py install 安装
说明:
name 包名称 deform_conv
# 头文件目录 include_dirs
# 源代码目录 sources
# 这个 C++ 扩展被命名为 deform_conv,意思是说,
#在 python 中可以通过 deform_conv 模块来调用 C++ 函数
deform_conv.py 当作一般的 PyTorch 模块进行调用
setup.py中写这些信息,
我们使用setuptools去编译我们的C++代码,
CppExtension 和 BuildExtension 可以很方便地
实现对C++和Cuda的编译
封装调用这个扩展(extension)
ext_modules
是一个包含Extension实例的列表,Extension的定义也有一些参数
python setup.py build develop
python setup.py install
4.Python调用
包内的文件相互导入分两种,用绝对路径和相对路径,用.或者..都是相对路径
from . import x
当前目录下,而且要在当前目录下建立 __init__.py 文件
_C.cpython-36m-x86_64-linux-gnu.so
_C.cpython-36m-x86_64-linux-gnu.so
so,即Shared Object,共享对象。(在LINUX下,静态函数库是以.a作后缀的)
python setup.py install
python setup.py install,那么,foo.py就会被拷贝到python类路径下,可以被导入使用
5.异常解决
执行的python脚本。使用了相对引用方式 (类似 from .import x) 去引用包时,
可能会出现这个异常。ImportError: attempted relative import with no known parent package`【尝试相对导入,但不知道父包】。
python -m project.demos.demo
相对导入通过使用模块的 name 属性来确定模块在包层次结构中的位置