setup.py中cmd_class的用法以及pytorch的build_ext

205 阅读2分钟

网上关于这个的中英文资料极少,于是python和C++联合编程的时候如果遇到符号链接等问题就会很抓狂,以下为几篇个人认为比较好的blog:

  • 1. cmd_class怎么用

dankeder.com/posts/addin…

下面为该网页的截图: lQLPJxqfmgd_tTvNI_PNCjywLGEQit4qtY8FmdG05FWXAA_2620_9203.png

上面的blog和下面截图配合看更佳~~

image.png

  • 2. pytorch的build_ext讲解:

pytorch官网中,对写extension作了详细介绍:

pytorch.org/tutorials/a…

pytorch.org/docs/stable…

注意到setup中,ext_modules要是CUDAExtension或者CppExtension,build_ext必须是torch.utils.cpp_extension.BuildExtension。

build_ext对应的类用于生成编译extension的命令。

shwina.github.io/custom-comp…

其中CUDAExtension和CppExtension其实很好理解,都是返回了setuptools.Extension的函数,无非是在里面连接了torch库、include了torch头文件等操作。

而torch.utils.cpp_extension.BuildExtension则没那么好理解了,下面对其进行介绍。

首先看其继承关系:distutils.core.Command → disutils.command.build_ext → setuptools.command.build_ext → BuildExtension。

distutils.core.Command就是命令要继承的父类(如上面的blog所示),因此绕来绕去BuildExtension依然是普通的命令。

既然是普通的命令,那么其最重要的,就是如上面的blog所示的三个函数:

  • initialize_options
  • finalize_options
  • run

disutils.command.build_ext和setuptools.command.build_ext的用法在网上资料很少很少。

torch.utils.cpp_extension.BuildExtension类中,主要override了build_extensions函数,没有override最关键的run函数。

setuptools.command.build_ext类中override了run函数,其中调用了 disutils.command.build_ext的run函数,

而disutils.command.build_ext的run函数则调用了self.build_extensions函数。

请注意继承关系。。。。

由于build_extensions被torch.utils.cpp_extension.BuildExtension重写了,因此最终还是调用了torch.utils.cpp_extension.BuildExtension的BuildExtension函数。

这就是torch.utils.cpp_extension.BuildExtension中BuildExtension函数的逻辑。

而torch.utils.cpp_extension.BuildExtension中BuildExtension函数主要对传入的Extension作了一些处理,如添加TORCH_EXTENSION_NAME的宏定义,生成ninja文件等,最后调用父类的build_extensions函数完成最后编译。

由于setuptools.command.build_ext和disutils.command.build_ext都是标准库,因此我一开始以为会有关于BuildExtension函数的详细文档。

结果搜了半天,网上都没有关于BuildExtension的任何介绍。

3. install和build_ext的关系

discuss.python.org/t/the-diffe…

blog.csdn.net/hxxjxw/arti…

pip install -e DIR will use PIP to install the package as editable, which will build any extension modules (setup.py build_ext), perform any other build requirements, then install the package symbolically (setup.py develop) including its dependencies

可见pip install -e DIR会调用 python setup.py build_ext(毕竟传给setup的extension就是通过build_ext来编译的),而pip install -e DIR又等价于python setup.py develop

image.png