はじめに
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 installhttps://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.somakeのログを見る限り、
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.sogccでビルドした場合に比べて、若干ですが .so のサイズが小さくなっています。
Windows10 WSL1 + Android NDK
Android NDKをWSL1に準備して、Android用にクロスコンパイルしてみます。 ここで利用するAndroid NDKのバージョンはr21d (21.3.6528147)です。 リリースノートによると、
- platforms
- sources/cxx-stl
- sysroot
- toolchains(toolchains/llvm を除く)
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 としてもビルドできます。