はじめに
OpenBLASのビルド方法いろいろです。リビジョンは 78702753f を使用しています。
make時に利用できるオプションは Makefile.rule に記載されています。
Linuxでビルド
単にOpenBLASをLinux環境でビルドするだけなら簡単です。Debian 10だと以下のようになります。
$ git clone https://github.com/xianyi/OpenBLAS.git
$ cd OpenBLAS
$ make -j2
<中略>
OpenBLAS build complete. (BLAS CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_haswellp-r0.3.13.dev.a (Multi-threading; Max num-threads is 8)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
-j2で2並列ビルドにしています。gfortranがインストールされていない環境なのでLAPACK関連はビルドされていません。
ビルドしたライブラリを呼び出せるか確認するため、インストールします。
$ make PREFIX=$(pwd)/build install
https://github.com/xianyi/OpenBLAS/wiki/User-Manual#call-cblas-interface
に記載されている例をビルドして実行してみます。例に記載されてるコードをコピーしたファイルが
a.cです。
$ LD_LIBRARY_PATH=../build/lib gcc -I ../build/include -lopenblas a.c
$ LD_LIBRARY_PATH=../build/lib ldd a.out
linux-vdso.so.1 (0x00007ffd9019f000)
libopenblas.so.0 => ../build/lib/libopenblas.so.0 (0x00007f17e22f7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f17e2110000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f17e1f8d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f17e1f6c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f17e26aa000)
$ LD_LIBRARY_PATH=../build/lib ./a.out
11.000000 -9.000000 5.000000 -9.000000 21.000000 -1.000000 5.000000 -1.000000 3.000000
計算結果が出力されていることを確認できました。
VirtualBox内のLinuxでビルド
CPUの自動判定ができない環境では、動かしたいCPUの系統をTARGETで指定する必要があります。
少なくともVirtualBox内では自動判定できませんでした。
TARGETの一覧はTargetList.txt に記載されています。
ここでは、VirtualBox内のDebian 10でNEHALEMを指定してみます。CPUは2個です。gfortranはインストール済みの環境です。
$ make TARGET=NEHALEM -j2
<中略>
OpenBLAS build complete. (BLAS CBLAS LAPACK LAPACKE)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Fortran compiler ... GFORTRAN (cmd & version : GNU Fortran (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_nehalemp-r0.3.13.dev.a (Multi-threading; Max num-threads is 2)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
依存しているライブラリは以下のようになります。
$ ldd libopenblas_nehalemp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007f5cdda3e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5cdcba7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5cdcb86000)
libgfortran.so.5 => /lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f5cdc918000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5cdc757000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5cdda40000)
libquadmath.so.0 => /lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f5cdc715000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5cdc4f7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5cdc4db000)
CBLASのみビルド
FortranインターフェイスもLAPACKも不要であれば、
$ make TARGET=NEHALEM ONLY_CBLAS=1 -j2
<中略>
OpenBLAS build complete. (CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_nehalemp-r0.3.13.dev.a (Multi-threading; Max num-threads is 2)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblas_nehalemp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007fff91ebd000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff87e467000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff87e446000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff87e285000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff87e992000)
のようにすることで依存するライブラリの数を減らせます。なお、異なるオプションでmakeを実行済みの場合は、最初にmake cleanを実行しておく必要があります。
BLASとCBLASのみビルド
gfortranがインストールされている環境であれば、NO_LAPACK=1を指定することでBLASとCBLASのみをビルドできます。
$ make TARGET=NEHALEM NO_LAPACK=1 -j2
<中略>
OpenBLAS build complete. (BLAS CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Fortran compiler ... GFORTRAN (cmd & version : GNU Fortran (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_nehalemp-r0.3.13.dev.a (Multi-threading; Max num-threads is 2)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblas_nehalemp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007fff1b6ed000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8826dc6000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8826da5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8826be4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8827317000)
マルチスレッドなしでビルド
LAPACKが不要かつマルチスレッドも不要であれば
$ make TARGET=NEHALEM ONLY_CBLAS=1 USE_THREAD=0 -j2
<中略>
OpenBLAS build complete. (CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_nehalem-r0.3.13.dev.a (Single-threading)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblas_nehalem-r0.3.13.dev.so
linux-vdso.so.1 (0x00007ffcdf5d1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb537e1d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb537c5c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb538218000)
のようにすることで、依存するライブラリの数をさらに減らせます。
マルチCPU対応でビルド
Linux環境でマルチCPU対応のビルドしてみます。
$ make DYNAMIC_ARCH=1 -j2
<中略>
OpenBLAS build complete. (BLAS CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblasp-r0.3.13.dev.a (Multi-threading; Max num-threads is 8)
Supporting multiple x86_64 cpu models with minimum requirement for the common code being HASWELL
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblasp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007ffec9b63000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6da587d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6da585c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6da569b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6da6d60000)
$ du -b libopenblasp-r0.3.13.dev.so
20676824 libopenblasp-r0.3.13.dev.so
makeのログを見る限り、
PRESCOTT
CORE2
NEHALEM
SANDYBRIDGE
HASWELL
SKYLAKEX
COOPERLAKE
BARCELONA
BULLDOZER
PILEDRIVER
STEAMROLLER
EXCAVATOR
ZEN
がビルドされてるようです。
比較のため、haswellの場合のサイズもみてみます。
$ ldd libopenblas_haswellp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007ffd066e2000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f37a4b71000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f37a4b50000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f37a498f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f37a50dc000)
$ du -b libopenblas_haswellp-r0.3.13.dev.so
4077872 libopenblas_haswellp-r0.3.13.dev.so
複数のCPUに対応したことで .so のサイズが増えていることが分かります。
続いて、VirtualBox内のLinux環境でマルチCPU対応のビルドしてみます。
$ make TARGET=NEHALEM DYNAMIC_ARCH=1 NO_LAPACK=1 -j2
<中略>
OpenBLAS build complete. (BLAS CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Fortran compiler ... GFORTRAN (cmd & version : GNU Fortran (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblasp-r0.3.13.dev.a (Multi-threading; Max num-threads is 2)
Supporting multiple x86_64 cpu models with minimum requirement for the common code being NEHALEM
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblasp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007ffdc5bfd000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa9101af000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa91018e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa90ffcd000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa91168c000)
$ du -b libopenblasp-r0.3.13.dev.so
20676824 libopenblasp-r0.3.13.dev.so
同じようにビルドされました。
Windows10 WSL1
Windows10のWSL1環境でビルドしてみます。gfortranがインストールされている環境です。こちらもDebian 10です。
この環境でもCPU自動検出は動作しないのでTARGETを指定する必要があります。
$ make TARGET=NEHALEM ONLY_CBLAS=1 -j2
<中略>
OpenBLAS build complete. (CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... GCC (cmd & version : cc (Debian 8.3.0-6) 8.3.0)
Library Name ... libopenblas_nehalemp-r0.3.13.dev.a (Multi-threading; Max num-threads is 8)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblas_nehalemp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007ffff07e4000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f74fdea0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f74fde7f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f74fdcb0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f74fe3ba000)
$ du -b libopenblas_nehalemp-r0.3.13.dev.so
3817776 libopenblas_nehalemp-r0.3.13.dev.so
Windows10 WSL1 + clang
WSL1環境でgccではなくclangでビルドしてみます。
$ make TARGET=NEHALEM ONLY_CBLAS=1 CC=clang -j2
<中略>
OpenBLAS build complete. (CBLAS)
OS ... Linux
Architecture ... x86_64
BINARY ... 64bit
C compiler ... CLANG (cmd & version : clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final))
Library Name ... libopenblas_nehalemp-r0.3.13.dev.a (Multi-threading; Max num-threads is 8)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
$ ldd libopenblas_nehalemp-r0.3.13.dev.so
linux-vdso.so.1 (0x00007fffd93c6000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc764ab0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc764a8f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc7648c0000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc764fb5000)
$ du -b libopenblas_nehalemp-r0.3.13.dev.so
3692824 libopenblas_nehalemp-r0.3.13.dev.so
gccでビルドした場合に比べて、若干ですが .so のサイズが小さくなっています。
Windows10 WSL1 + Android NDK
Android NDKをWSL1に準備して、Android用にクロスコンパイルしてみます。
ここで利用するAndroid NDKのバージョンはr21d (21.3.6528147)です。
リリースノートによると、
- platforms
- sources/cxx-stl
- sysroot
- toolchains(toolchains/llvm を除く)
がNDKのパスから削除されるとのことですので、
toolchains/llvmのみを用いてOpenBLASをビルドしてみます。
x86 32-bit
x86の32-bit向けのビルドするためのシェルスクリプトの例は以下のとおりです。
#!/bin/bash
API_VERSION=24
NDK=/path/to/ndk/android-ndk-r21d-linux-x86_64/android-ndk-r21d
NDK_BINPATH=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
NDK_SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
NDK_LIBPATH=$NDK_SYSROOT/usr/lib/i686-linux-android/$API_VERSION
NDK_CC="i686-linux-android$API_VERSION-clang --sysroot $NDK_SYSROOT -B$NDK_LIBPATH"
PATH=$NDK_BINPATH:$PATH make TARGET=NEHALEM ONLY_CBLAS=1 AR=ar CC="$NDK_CC" LDFLAGS="-L$NDK_LIBPATH" HOSTCC=gcc USE_THREAD=0 -j2
これを実行してビルドが成功すると、
OpenBLAS build complete. (CBLAS)
OS ... Android
Architecture ... x86
BINARY ... 32bit
C compiler ... CLANG (cmd & version : Android (6454773 based on r365631c2) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project
98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn))
Library Name ... libopenblas_nehalem-r0.3.13.dev.a (Single-threading)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
が表示されます。なお、AR=ar を AR=i686-linux-android-ar としてもビルドできます。
x86 64-bit
x86の64-bit向けのビルドするためのシェルスクリプトの例は以下のとおりです。
#!/bin/bash
API_VERSION=24
NDK=/path/to/ndk/android-ndk-r21d-linux-x86_64/android-ndk-r21d
NDK_BINPATH=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
NDK_SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
NDK_LIBPATH=$NDK_SYSROOT/usr/lib/x86_64-linux-android/$API_VERSION
NDK_CC="x86_64-linux-android$API_VERSION-clang --sysroot $NDK_SYSROOT -B$NDK_LIBPATH"
PATH=$NDK_BINPATH:$PATH make TARGET=NEHALEM ONLY_CBLAS=1 AR=ar CC="$NDK_CC" LDFLAGS="-L$NDK_LIBPATH" HOSTCC=gcc USE_THREAD=0 -j2
これを実行してビルドが成功すると、
OpenBLAS build complete. (CBLAS)
OS ... Android
Architecture ... x86_64
BINARY ... 64bit
C compiler ... CLANG (cmd & version : Android (6454773 based on r365631c2) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project
98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn))
Library Name ... libopenblas_nehalem-r0.3.13.dev.a (Single-threading)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
が表示されます。なお、AR=ar を AR=x86_64-linux-android-ar としてもビルドできます。
arm 32-bit
armの32-bit向けのビルドするためのシェルスクリプトの例は以下のとおりです。
#!/bin/bash
API_VERSION=24
NDK=/path/to/ndk/android-ndk-r21d-linux-x86_64/android-ndk-r21d
NDK_BINPATH=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
NDK_SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
NDK_LIBPATH=$NDK_SYSROOT/usr/lib/arm-linux-androideabi/$API_VERSION
NDK_CC="armv7a-linux-androideabi24-clang --sysroot $NDK_SYSROOT -B$NDK_LIBPATH"
PATH=$NDK_BINPATH:$PATH make TARGET=ARMV7 ONLY_CBLAS=1 ARM_SOFTFP_ABI=1 AR=ar CC="$NDK_CC" LDFLAGS="-L$NDK_LIBPATH" HOSTCC=gcc USE_THREAD=0 -j2
これを実行してビルドが成功すると、
OpenBLAS build complete. (CBLAS)
OS ... Android
Architecture ... arm
BINARY ... 32bit
C compiler ... CLANG (cmd & version : Android (6454773 based on r365631c2) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project
98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn))
Library Name ... libopenblas_armv7-r0.3.13.dev.a (Single-threading)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
が表示されます。なお、AR=ar を AR=arm-linux-androideabi-ar としてもビルドできます。
arm 64-bit
armの64-bit向けのビルドするためのシェルスクリプトの例は以下のとおりです。
#!/bin/bash
API_VERSION=24
NDK=/path/to/ndk/android-ndk-r21d-linux-x86_64/android-ndk-r21d
NDK_BINPATH=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
NDK_SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
NDK_LIBPATH=$NDK_SYSROOT/usr/lib/aarch64-linux-android/$API_VERSION
NDK_CC="aarch64-linux-android24-clang --sysroot $NDK_SYSROOT -B$NDK_LIBPATH"
PATH=$NDK_BINPATH:$PATH make TARGET=ARMV8 ONLY_CBLAS=1 AR=ar CC="$NDK_CC" LDFLAGS="-L$NDK_LIBPATH" HOSTCC=gcc USE_THREAD=0 -j4
mkdir -p build-aarch64
INSTALL_DIR=$(readlink -f build-aarch64)
PATH=$NDK_BINPATH:$PATH make TARGET=ARMV8 ONLY_CBLAS=1 PREFIX=$INSTALL_DIR install
これを実行してビルドが成功すると、
OpenBLAS build complete. (CBLAS)
OS ... Android
Architecture ... arm64
BINARY ... 64bit
C compiler ... CLANG (cmd & version : Android (6454773 based on r365631c2) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project
98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn))
Library Name ... libopenblas_armv8-r0.3.13.dev.a (Single-threading)
To install the library, you can run "make PREFIX=/path/to/your/installation install".
が表示されます。なお、AR=ar を AR=aarch64-linux-android-ar としてもビルドできます。