前に書いた記事 で,python・numpy・scipyをrootを取らずにソースからインストールする方法について述べた.
しかし,上記の方法は以下の問題点がある.
- 遅い.
- すごく遅い.
- とてつもなく遅い.
BLASやLAPACKがマルチスレッド対応になっていないのがその原因.Intel MKLを買うほどお金もないので,OpenBLASを使うことにする.
参考記事は以下の2つ.
- Building Numpy and Scipy with OpenBLAS2 (日本語) https://lucidfrontier45.wordpress.com/2012/02/26/building-numpy-and-scipy-with-gotoblas2/
- Numpy/Scipy with OpenBLAS for Ubuntu 12.04 (英語) http://osdf.github.io/blog/numpyscipy-with-openblas-for-ubuntu-1204.html
OpenBLAS
SurviveGotoBLASを使う.まずはスタティックライブラリのビルド.
# wget http://prs.ism.ac.jp/~nakama/SurviveGotoBLAS2/SurviveGotoBLAS2_3.14.tar.gz
# tar xzf SurviveGotoBLAS2_3.14.tar.gz
# cd survivegotoblas2_3.14
# vim Makefile.rule
TARGET=X86_64
BINARY=64
USE_THREAD=1
USE_OPENMP=1
NUM_THREADS=12 # CPUの数に応じて調節する
NO_CBLAS=1 # CBLASはあとでビルドする
NO_LAPACK=1 # LAPACKもあとでビルドする
# make all -j 4
# cp libgoto2.a ~/lib # 永続的に残す場所(ここでは~/lib)へコピー
Theanoのようにダイナミックリンクライブラリを要求するパッケージもあるので,.soも作る.
# mkdir tmp
# cd tmp
# cp ../libgoto2.a .
# ar -x libgoto2.a # .aを.oに分解
# gfortran -shared -lpthread -lgomp -o libgoto2.so *.o
# cp libgoto2.so ~/lib # 永続的に残す場所へコピー
# export BLAS=~/lib/libgoto2.so # なくても良いかも
CBLAS
SurviveGotoBLASに入っているものを使っても良いが,ここでは自分でビルドする.先ほどビルドしたBLASを忘れずにCBLASビルド時に指定..soを作るところ(下から2行目)で忘れがちになるので,要注意.
# wget http://www.netlib.org/blas/blast-forum/cblas.tgz
# tar xzf cblas.tgz
# cd CBLAS
# cp Makefile.LINUX Makefile.in
# vim Makefile.in
BLLIB = ~/lib/libgoto2.a # ここでBLASを参照
CBLIB = ../lib/libcblas.a # CBLASの出力先
LOADER = $(FC) -lpthread
CFLAGS = -O3 -m64 -fPIC -DADD_
FFLAGS = -O3 -m64 -fPIC
# make all -j 4
# cp lib/libcblas.a ~/lib # 永続的に残す場所へコピー
# gfortran -L${HOME}/lib -lgoto2 -shared -o libcblas.so *.o
# cp libcblas.so ~/lib # 永続的に残す場所へコピー
LAPACK
これも自分でビルドする.これまでに作ったライブラリをLAPACKビルド時に指定.
# wget http://www.netlib.org/lapack/lapack.tgz
# tar xzf lapack.tgz
# cd lapack
# cp INSTALL/make.inc.gfortran make.inc
# vi make.inc
OPTS = -O3 -m64 -fPIC
NOOPT = -O0 -m64 -fPIC
LOADOPTS = -L${HOME}/lib -lgoto2 -lcblas
# make lapacklib -j 4
# cp liblapack.a ~/lib # 永続的に残す場所へコピー
# mkdir tmp
# cd tmp
# cp ../liblapack.a .
# ar -x liblapack.a # .aを.oに分解
# gfortran -L${HOME}/lib -lgoto2 -lcblas -shared -o liblapack.so *.o
# cp liblapack.so ~/lib
# export LAPACK=~/lib/liblapack.so # なくても良いかも
Numpy
ビルド前にsite.cfgを編集して,そこでBLAS,LAPACKを参照させることがポイント.
# wget http://sourceforge.net/projects/numpy/files/NumPy/1.9.0/numpy-1.9.0.tar.gz/download --no-check-certificate
# tar xzf numpy-1.9.0.tar.gz
# cd numpy-1.9.0
# cp site.cfg.example site.cfg
# vim site.cfg
[DEFAULT]
library_dirs = ${HOME}/lib
[atlas]
atlas_libs = goto2,cblas
# python setup.py build
# python setup.py install
ちゃんと動いているかどうか,念のためテスト.たぶんここではエラーは出ないはず.
# python -c "import numpy; numpy.test(verbose=2)"
ここにあるテストスクリプトを走らせて,速度を確認してみると良いかもしれない.
# python test_numpy.py
Scipy
# wget http://sourceforge.net/projects/scipy/files/scipy/0.14.0/scipy-0.14.0.tar.gz/download
# tar xzvf scipy-0.14.0.tar.gz
# cd scipy-0.14.0
# vim site.cfg
[DEFAULT]
library_dirs = ${HOME}/lib
[atlas]
atlas_libs = lapack,goto2,cblas
ここで,scipy/lib/lapack/__init__.pyを以下のように書き換える.
(旧)
from scipy.linalg import flapack
from scipy.linalg import clapack
_use_force_clapack = 1
if hasattr(clapack,'empty_module'):
clapack = flapack
_use_force_clapack = 0
elif hasattr(flapack,'empty_module'):
flapack = clapack''
(新)
from scipy.linalg import flapack
clapack = flapack
_use_force_clapack = 0
最後にビルドインストールして終わり.
# python setup.py build
# python setup.py install
こちらもテストをしてみる.たまに失敗するかもしれないけれども,
# python -c "import numpy; numpy.test(verbose=2)"