Windows編譯OpenBLAS


在嘗試用 LazyNet 時,由於原作者提供的OpenCV和OpenBLAS版本和我的環境不一樣,考慮自行配置依賴。

OpenCV源碼編譯的文章很多,這里主要說一下OpenBLAS的編譯。

cblas_sgemm crash

基於VS2017的MSVC編譯器,編譯安裝openblas develop分支最新版,發現 LazyNet 代碼有crash(access violation),而在Linux(ubuntu16.04,G++/Clang++-8)則運行正常。剝離出來的復現問題的最小化代碼見下方,解決辦法是用clang-cl(Windows下和MSVC兼容的clang編譯器)重新編譯OpenBLAS討論帖在此

#include <stdio.h>

extern "C" {
#include <cblas.h>
}

int main() {
	printf("OpenBLAS config info:\n%s\n", openblas_get_config());


#if 1 // will cause crash on VS2017 x64 with OpenBLAS latest
	const int M = 16;
	const int N = 676;
	const int K = 27;
#else // won't crash
	const int M = 4;
	const int N = 2;
	const int K = 3;
#endif

	const float alpha = 1.0f;
	const float beta = 0.f;

	int lda = K;
	int ldb = N;
	int ldc = N;

	float A[M*K];
	float B[K*N];
	float C[M*N];

	cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, A, lda, B,
		ldb, beta, C, ldc);

	return 0;
}

clang-cl編譯OpenBLAS步驟

盡管 OpenBLAS 官方 wiki 頁面 How to use OpenBLAS in Microsoft Visual Studio 已經貼出了具體步驟,不過一開始我並沒有去翻看此文檔,想當然的認為CMake + VS2017即可。實踐下來發現我並不需要fortran(用不到LAPACK),所用步驟如下:

1. 安裝依賴軟件

Visual Studio 2017

我沒有勾選里面的Clang。后續用conda裝。

CMake

我手動從官網下載的二進制包。conda安裝的cmake似乎不帶cmake-gui,查看CMakeCache的時候不方便。

Ninja

因為不用fortran(flang)編譯,因此不必更新為kitware-ninja,常規版本即可。

conda安裝的

我用的Miniconda,你用Anaconda也行,反正是用里面的conda作為包管理工具。注意conda並非只能安裝Python的包(甚至pip也能裝cmake,不過個人不喜歡這么做)。

首先配置conda源,在GitBash中編輯~/.condarc

channels:
  - conda-forge
  - defaults
show_channel_urls: true
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

其次執行如下命令:

conda update -n base conda
conda install -y clangdev perl

2. 編譯安裝

下載源碼

cd /d/dev
#git clone https://gitee.com/aczz/OpenBLAS
git clone https://gitee.com/xianyi/OpenBLAS
cd OpenBLAS
git checkout develop

寫構建腳本

mkdir build
vim build/clang-cl.bat

build/clang-cl.bat內容如下:

@echo off

set "LIB=%CONDA_INSTALL_LOCN%\Library\lib;%LIB%"
set "CPATH=%CONDA_INSTALL_LOCN%\Library\include;%CPATH%"
set BUILD_DIR="clang-cl"
if not exist %BUILD_DIR% mkdir %BUILD_DIR% 
cd %BUILD_DIR%
cmake ../.. -G "Ninja" -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER=clang-cl -DBUILD_WITHOUT_LAPACK=yes -DDYNAMIC_ARCH=ON -DCMAKE_BUILD_TYPE=Release
cd ..

執行構建和安裝

"c:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvars64.bat"
cd build
clang-cl.bat
cmake --build . --config Release
cmake --install . --prefix d:/lib/openblas/clang-cl/x64 -v

3. 使用OpenBLAS

這里主要說一下 CMake 里設置 OpenBLAS:實測可用的例子:

# OpenBLAS_DIR 指向包含OpenBLASConfig.cmake的目錄
set(OpenBLAS_DIR "D:/lib/openblas/clang-cl/x64/share/cmake/OpenBLAS")
find_package(OpenBLAS REQUIRED)

add_executable(lazynet
    ${lazynet_srcs}
    ${lazynet_incs}
)
target_include_directories(lazynet
    PUBLIC include
    ${OpenBLAS_INCLUDE_DIRS}
)
set(lazynet_dep_libs ${OpenCV_LIBS} ${OpenBLAS_LIBRARY})
if(UNIX)
    list(APPEND lazynet_dep_libs pthread)
endif()

注意點:

  1. 不要用OpenBLAS_LIBRARIES變量

打印出來它的值為空,而不是像OpenBLASConfig.cmake的注釋中寫的那樣,“和OpenBLAS_LIBRARIY相同”

  1. 不要信FindBLAS.cmake文件

盡管CMake(我用的3.17.1)安裝目錄下提供了FindBLAS.cmake文件,看似提供了各種BLAS的查找功能,但就OpenBLAS來說,在Windows下還不如手動設定;在Linux下僅對於apt安裝的openblas(版本通常很老)能找到庫文件,但並不提供頭文件查找目錄,需要自行設定:

    set(BLA_VENDOR "OpenBLAS")
    find_package(BLAS REQUIRED)
    set(OpenBLAS_INCLUDE_DIRS "/usr/include/openblas")
    set(OpenBLAS_LIBRARY ${BLAS_LIBRARIES})

而手動編譯的openblas則並不能被很優雅的找到。因而,請忽略FindBLAS.cmake這一文件。

  1. 自行編譯的openblas,在Linux下使用時,需要額外鏈接pthread庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM