1. 程式人生 > >REDHAT+GFLAGS+GLOG原始碼編譯CAFFE2指南

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 functionconst 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

編譯成功!開心一下吧