pytorch下的lib库 源码阅读笔记(1)
置顶:将pytorch clone到本地,查看initial commit,已经是麻雀虽小五脏俱全了,非常适合作为学习模板。
2017年12月7日01:24:15
2017-10-25 17:51
参考了知乎问题 如何有效地阅读PyTorch的源代码? 相关回答
按照构建顺序来阅读代码是很聪明的方法。
1,TH中最核心的是THStorage、THTensor,
THStorage实现了底层数据(其实就是一个数组),
THTensor实现了对底层数据的查看。
2,TH: 核心就THStorage与THTensor,辅助有 THGeneral、THHalf、THAllocator、THSize
2017-11-14 02:56
看了这么久,终于知道TH的头在哪里了。该有的预备知识也差不多都具备了,接下来准备一边继续深入
研究TH,一边记笔记。TH看懂了,THNN也是差不多立马能读懂的,再加上一个ATen或类似的东西,就可以
在C/C++层面构建神经网络了。
2017年11月15日01:35:54
pytorch的主要维护者之一的 Adam Paszke 有一篇 A quick tour of Torch internals 的文章。里头大概讲了下
TH的结构。TH用 C 模拟了泛型编程。今天抽丝剥茧,写了一个只包含2个文件的极度简单的演示程序:
main.cpp
#include <iostream> #define CONCAT_2_EXPAND(x,y) x ## y #define show_(name) CONCAT_2_EXPAND(show_, name) // 上面两句合并成一句: #define show_(name) show_##name 都会出错! #include "generic.h" //real = int 类型, int 先用 real 来代表自己 #define real int #line 1 GENERIC_FILE #include GENERIC_FILE #undef real // int 用完 real 后必须 undef 掉 real,因为 double 还要用 real //real = double 类型 #define real double #line 1 GENERIC_FILE #include GENERIC_FILE int main(){ show_int(6); show_double(3.14); system("pause"); return 0; }
generic.h
#ifndef GENERIC_FILE #define GENERIC_FILE "generic.h" #else #include <iostream> using namespace std; void show_(real)(real number){ cout << "real = " << number << endl; } #endif
注释:
#line number "string"
它通知预处理器从下一行的行号被重新设定为 number 所代表的数字。如果给出了可选部分"string",预处理器就把它作为当前文件的名字。这条指令将修改__LINE__符号的值,如果加上可选部分,还将修改__FILE__符号的值。
两个文件的功能是显示 int 和 double 两种不同类型的数。已经实现了泛型编程。
#define、#undef、#line 1 GENERIC_FILE 三者的组合运用真是绝妙的用法。
预编译完后代码膨胀成包含 show_int() 和 show_double() 两个函数的文件了。其实在 C和指针 这本书的 17.5.4节也提到过用C模拟泛型编程的一些技巧。可以参看。用C实现泛型,使用者需要遵循一定的命名规则。
2017年11月18日20:09:10
将函数的泛型实现从 generic.h 中分离到单独的 generic.c 文件中去了,代码在这:generic_in_c
文件结构及编译过程比较巧妙。
TH在make过程中可以看到如下信息:
Scanning dependencies of target TH [ 5%] Building C object CMakeFiles/TH.dir/THGeneral.c.o [ 10%] Building C object CMakeFiles/TH.dir/THHalf.c.o [ 15%] Building C object CMakeFiles/TH.dir/THAllocator.c.o [ 20%] Building C object CMakeFiles/TH.dir/THSize.c.o [ 25%] Building C object CMakeFiles/TH.dir/THStorage.c.o [ 30%] Building C object CMakeFiles/TH.dir/THTensor.c.o [ 35%] Building C object CMakeFiles/TH.dir/THBlas.c.o [ 40%] Building C object CMakeFiles/TH.dir/THLapack.c.o [ 45%] Building C object CMakeFiles/TH.dir/THLogAdd.c.o [ 50%] Building C object CMakeFiles/TH.dir/THRandom.c.o [ 55%] Building C object CMakeFiles/TH.dir/THFile.c.o [ 60%] Building C object CMakeFiles/TH.dir/THDiskFile.c.o [ 65%] Building C object CMakeFiles/TH.dir/THMemoryFile.c.o [ 70%] Building C object CMakeFiles/TH.dir/THAtomic.c.o [ 75%] Building C object CMakeFiles/TH.dir/THVector.c.o [ 80%] Building C object CMakeFiles/TH.dir/generic/simd/convolve.c.o [ 85%] Building C object CMakeFiles/TH.dir/generic/simd/convolve5x5_sse.c.o [ 90%] Building C object CMakeFiles/TH.dir/vector/AVX.c.o [ 95%] Building C object CMakeFiles/TH.dir/generic/simd/convolve5x5_avx.c.o [100%] Linking C shared library libTH.so [100%] Built target TH
逆着这个顺序来,一边删除功能一边编译可以了解TH的结构。
THStorage应该是TH最基本的功能了。是先实现storage,再实现tensor及相关功能,再实现file功能。
lapack、blas、simd等从cmakelists来看都是可选的。
storage和allocator紧密关联。THGeneral.c中大部分是实现内存管理的东西。
查看预编译后的代码可以看到总共有8种类型的storage: inttypes 5种 + floattypes 2种 + half类型
预编译展开 TH.h 可以看到所有的函数声明。