REDHAT+GFLAGS+GLOG原始碼編譯CAFFE2指南
REDHAT+GFLAGS+GLOG原始碼編譯CAFFE2指南
為什麼要從原始碼編譯?
caffe2出來有一段時間了,但是原始碼編譯的教程少的令人髮指,因為伺服器沒有相關環境,同時劃重點,伺服器不聯網,所有的庫都要自己下載上傳編譯。所以需要從頭到尾自己編譯caffe2。
編譯前的準備
確認你已經安裝或者下載好了這些類庫(有一些不是一定要的,可以根據自己的選擇自由決定)
- [x] cuda
- [x] glog
- [x] gloo
- [x] glflags
- [x] mpi
- [x] leveldb
- [x] lmdb
- [x] opencv
- [x] intel-compiler
安裝好的務必記住其各個庫的根目錄位置,apt安裝最為簡便,因為伺服器沒有相關庫,所以要自己原始碼編譯這些開源的庫才能使用。編譯方式很簡單,configure結束後make,make install即可。
編譯CAFFE2
在CAFFE2根目錄執行以下指令:
makedir build && cd build
cmake ..
/*
在下面的介面更改prefix-install路徑,因為不是管理員許可權,只能安裝到本地路徑
*/
ccmake ..
如果以上類庫安裝無誤,同時提示你沒有任何問題,那麼恭喜你有很大可能安裝成功。有問題的話之後再細說。
執行make install
,無錯誤的話整個過程就解說,但是,如果這麼簡單就沒有這個blog了,哈哈哈哈
CAFFE2安裝智障的地方就是其神奇一般的cmake指令碼,以至於你都不知道如何去適配你自己原始碼編譯各種庫檔案(也許我太菜了2333)。
1. 首先來看CAFFE2編譯過程中的第一段錯誤
-- Caffe2: Cannot find glog automatically. Using legacy find.
-- Could NOT find glog (missing: GLOG_LIBRARY)
CMake Warning at cmake/public/glog.cmake:66 (message):
Caffe2: glog cannot be found. Depending on whether you are building Caffe2
or a Caffe2 dependent library, the next warning / error will give you more
info.
Call Stack (most recent call first):
cmake/Dependencies.cmake:134 (include)
CMakeLists.txt:182 (include)
這段錯誤的意思是找不到glog庫,可是我已經原始碼編譯安裝好glog庫了,設定好了環境變數為什麼依然看不到這個類庫。第一步肯定是百度(google不好用啊= =),於是找到了大神的blogcaffe:cmake編譯指定glog,gflag路徑,雖然是caffe的,但是也可以一探究竟為啥會出問題:
當使用cmake編譯caffe的情況下,在 cmake生成Makefile時會自動找到系統安裝的glog,gflag,但是如是我們自己編譯了一個glog,gflag,並沒有安裝在(/usr)系統目錄下,而是放在使用者目錄(/home)下,要想使用這個glog,gflag版本,不做處理cmake是找不到的。
caffe2的cmake不太一樣,所以要這樣子新增
#在 $caffe2_source_root/cmake/public/glog.cmake中做如下修改
include(FindPackageHandleStandardArgs)
set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
if(NOT WIN32)
#新增函式
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR}
NO_DEFAULT_PATH)
#新增結束
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR})
endif()
#新增函式
find_library(GLOG_LIBRARY glog
PATHS ${GLOG_ROOT_DIR}
PATH_SUFFIXES lib lib64
NO_DEFAULT_PATH)
#新增結束
find_library(GLOG_LIBRARY glog
PATHS ${GLOG_ROOT_DIR}
PATH_SUFFIXES lib lib64)
執行指令
/*glog_root指向你glog類庫的根目錄*/
cmake .. -DGLOG_ROOT_DIR=$glog_root
重新檢視cmake輸出可以看到cmake找到了你自定義的glog類庫了。
但是!但是!機智的CAFFE2怎麼可能這麼快讓你通關了,這只是考驗的開始,於是遇到了下一個問題:
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘void caffe2::SetUsageMessage(const string&)’:
/caffe2source/pytorch/caffe2/core/flags.cc:17:3: error: ‘gflags’ has not been declared
gflags::SetUsageMessage(str);
^
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘const char* caffe2::UsageMessage()’:
/caffe2source/pytorch/caffe2/core/flags.cc:21:10: error: ‘gflags’ has not been declared
return gflags::ProgramUsage();
^
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘bool caffe2::ParseCaffeCommandLineFlags(int*, char***)’:
/caffe2source/pytorch/caffe2/core/flags.cc:26:10: error: ‘gflags’ has not been declared
return gflags::ParseCommandLineFlags(pargc, pargv, true);
^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-invalid-partial-specialization" [enabled by default]
make[2]: *** [caffe2/CMakeFiles/caffe2.dir/core/flags.cc.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [caffe2/CMakeFiles/caffe2.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Compiling src/broadcast.cu > /caffe2source/pytorch/third_party/nccl/build/obj/broadcast.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Compiling src/reduce.cu > /caffe2source/pytorch/third_party/nccl/build/obj/reduce.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Compiling src/reduce_scatter.cu > /caffe2source/pytorch/third_party/nccl/build/obj/reduce_scatter.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Linking libnccl.so.1.3.5 > /caffe2source/pytorch/third_party/nccl/build/lib/libnccl.so.1.3.5
Archiving libnccl_static.a > /caffe2source/pytorch/third_party/nccl/build/lib/libnccl_static.a
[ 37%] No install step for 'nccl_external'
[ 37%] Completed 'nccl_external'
[ 37%] Built target nccl_external
make: *** [all] Error 2
但是之前cmak的提示是
Caffe2: Found gflags with new-style gflags target.
這就很尷尬了,這是咋回事,這裡的問題原因經過我的搜尋在官方github的issue找到了,簡單點來說就是官方在最新3.0版本的gflags將名稱空間從google改為了gflags,伺服器上仍舊為2.2.1的老舊版本,最新的caffe2用的是新版gflags,所以不相容,解決方法也很簡單,下載最新的gflags吧。但是!同樣的資料夾下的cmake怎麼格式不一樣啊,我編譯出來的gflags資料夾下有lib,include,bin
三個資料夾,你這個find_library
,find_path
也太敷衍了吧好歹glog
還像回事,你這個只搜尋GFLAGS_ROOT_DIR好像不行啊(cmake是不是還會遞迴搜尋,反正這裡沒有搜尋到),於是手動滑稽一下吧。
#原始的gflags.cmake
include(FindPackageHandleStandardArgs)
set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
# We are testing only a couple of files in the include directories
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR})
endif()
if(WIN32)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
find_library(GFLAGS_LIBRARY gflags)
endif()
#修改後的gflags.cmake
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
# find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
# PATHS ${GFLAGS_ROOT_DIR})
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/include
NO_DEFAULT_PATH)
#find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
# PATHS ${GFLAGS_ROOT_DIR}/include)
endif()
if(WIN32)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
# find_library(GFLAGS_LIBRARY gflags)
find_library(GFLAGS_LIBRARY gflags
PATH ${GFLAGS_ROOT_DIR}/lib
NO_DEFAULT_PATH)
endif()
最後cmake執行的指令是(cudnn_root也是原始碼編譯的,其它類庫是自帶的)
cmake $caffe_root -G "Unix Makefiles" \
-DGLOG_ROOT_DIR=$glog_root \
-DCUDNN_ROOT_DIR=$cudnn_root \
-DGFLAGS_ROOT_DIR=$gflags_root
make install
編譯成功!開心一下吧