目录
引子
17年6月开始由于在我们的问题求解过程中需要使用到复数,而唯一支持复数的框架tensorflow也并不是所有的操作都支持,此外对于复数这个部分优化的有限,所以着手开始尝试修改几个流行的框架。我分别在MXNet的后端mshadow,PyTorch的仓库下提了issue试图询问开发者是否有相关计划,不过遗憾的是好像由于目前复数在实际工作中的应用并不是很多,复数支持并非是优先级较高的特性。
首先感谢一下这期间中国科学技术大学韩永健老师,中科院物理所王磊老师,复旦大学李晓鹏老师组的支持(没阻止我不务正业,但是没轮子用很难受啊,捂脸)。
虽然从底层代码的角度来看,个人更加喜欢MXNet的C++代码,和PyTorch的几个C语言库。读过一些很有收获。但是只有PyTorch的开发者鸟我了,所以就开始改底层有些不太好改的PyTorch(相比MXNet而言)。相比之下当时还在v0.1版本的PyTorch底层就混乱了许多,这也导致从底层支持复数并不是那么容易。第一个完成复数支持的仓库是在Github:PhillippPelz修改的版本之上做的,但是他的做法似乎PyTorch的团队并不是很喜欢,他直接修改了几个后端的C/CUDA C库,并且导致一些命名上的混乱。后来我在之前的基础上将复数单独拿出来,交了第一个PR,大约9k行的C,用以提供一个支持复数的CPU后端,但是也许是因为太多了,没人review也没人merge。期间有人联系过我向我要源码,相关指导等等,可见复数并非我一个人所需。如果不尽早merge,由于PyTorch的更新速度比较快(三个月一个release)我一个人很难跟上它的进度,因为整体工程量不小,等我修改完又需要费很大力气去跟进其它新特性。所以更希望是先能merge CPU然后再支持GPU。(GPU上用float2来模拟复数的时候map/reduce之类的地方一些原来能用trick变得很不好写)跨过几个版本可能就又需要很多修改。所以后来我就放弃独立支持复数的计划了,改去使用Julia,并且在Julia上搭建自己所需。但是在修改PyTorch期间,为了方便我记录了一些笔记来阐述源码的构成和作用,以及我猜测的作者的设计思路,现在慢慢整理分享出来以飨读者。
整体结构
目前我本地版本是commit d0cabbd
PyTorch是一个以Python为前端的框架,在借助Python这个动态语言本身的特性基础上使用动态图来定义模型,可以说PyTorch很好地借助了Python编译器的一些特性(例如垃圾回收,语言本身的动态性等),这使得用户在使用时会觉得好像比tensorflow这样使用静态图的框架容易。
结构上大约有两部分,一部分是Python,另外一部分是C/C++写的后端。Python的部分比较容易读,如果后面有时间再介绍。C/C++后端的多维数组库在v0.4开始用aten(a tensor library)库作为上层封装再通过torch/csrc 中的部分胶水代码接入Python(但慢慢在改为pybind11)。自动微分使用C++完成,后端采用的是一个类似于录像带的机制来记录相关操作。新加入的jit部分还有详细读,不介绍。用`tree`看一下大约是这样的。后端核心代码主要在 lib 里。
├── autograd
├── backends
├── contrib
...
├── csrc
│ ├── allocators.cpp
│ ├── allocators.h
│ ├── assertions.cpp
│ ├── assertions.h
│ ├── autograd
│ ├── byte_order.cpp
│ ├── byte_order.h
│ ├── copy_utils.h
│ ├── cuda
│ ├── DataLoader.cpp
│ ├── distributed
│ ├── dl.c
│ ├── DynamicTypes.cpp
│ ├── DynamicTypes.h
│ ├── Exceptions.cpp
│ ├── Exceptions.h
│ ├── expand_utils.cpp
│ ├── expand_utils.h
│ ├── Generator.cpp
│ ├── Generator.h
│ ├── generic
│ ├── jit
│ ├── Module.cpp
│ ├── Module.h
│ ├── ModuleSparse.cpp
│ ├── nn
│ ├── nnpack
│ ├── nvrtc.cpp
│ ├── onnx
│ ├── PtrWrapper.cpp
│ ├── PtrWrapper.h
│ ├── PythonTypes.h
│ ├── README.md
│ ├── serialization.cpp
│ ├── serialization.h
│ ├── Size.cpp
│ ├── Size.h
│ ├── Storage.cpp
│ ├── Storage.h
│ ├── Tensor.cpp
│ ├── Tensor.h
│ ├── THP_API.h
│ ├── THP_export.h
│ ├── THP.h
│ ├── Types.h
│ ├── utils
│ ├── utils.cpp
│ └── utils.h
├── cuda
...
├── distributed
...
├── distributions.py
├── for_onnx
...
├── jit
├── legacy
├── lib
│ ├── ATen
│ ├── build
│ ├── build_libs.bat
│ ├── build_libs.sh
│ ├── gloo
│ ├── include
│ ├── libshm
│ ├── libshm_windows
│ ├── libTH.so.1
│ ├── nanopb
│ ├── nccl
│ ├── pybind11
│ ├── README.md
│ ├── TH
│ ├── THC
│ ├── THCUNN.h
│ ├── THD
│ ├── THNN.h
│ └── tmp_install
├── multiprocessing
├── nn
├── onnx
├── optim
├── random.py
├── serialization.py
...
├── _thnn
├── _torch_docs.py
├── utils
└── _utils.py
53 directories, 110 files