置頂:將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 可以看到所有的函數聲明。
