Windows编译OpenBLAS

Deadly 提交于 2020-05-04 09:39:42

在尝试用 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库
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!