Numpy/Scipy with OpenBLAS for Ubuntu 12.04

Attention conservation notice: Superseded by an improved text.

ATLAS was my linear algebra backend on Linux machines for years. Installing it usually took a complete day and always failed at the first attempt. Probably because my notes were not as tidy as these.

OpenBLAS is supposed to be much faster than ATLAS and much easier to setup with numpy/scipy, too. At least that's what you can read around the web. Trying both methods didn't work for me though. Luckily enough, Google does Japanese and with some tiny adaptation this works. I'll describe the complete procedure for Ubuntu 12.04.

apt-get and other preparations for 12.04

sudo apt-get install git python-dev gfortran swig
sudo apt-get install rcconf dialog

The first line is clear, you probably have these installed anyway. I use rcconf to disable CPU frequency scaling (search for ONDEMAND on the linked site). 12.04 uses a new linker with some known issues. Therefore

export LIBRARY_PATH=/usr/local/lib

Note that adapting LD_LIBRARY_PATH or updating something in /etc/ld.so.conf.d (even done in the correct way) does not help.

OpenBLAS

git clone git://github.com/xianyi/OpenBLAS
wget http://www.netlib.org/blas/blast-forum/cblas.tgz

Also wget the latest LAPACK from http://www.netlib.org/lapack/. Untar both tgzs into their appropriately named directories.

Change into the cloned OpenBLAS directory and make two tiny modifications to Makefile.rule: Uncomment the lines NO_CBLAS = 1 and NO_LAPACK = 1. Then

make FC=gfortran
sudo make PREFIX=/usr/local/ install

For building CBLAS, change into the extracted directory. In Makefile.in do

BLLIB = /usr/local/lib/libopenblas.a 
CBLIB = ../lib/libcblas.a
...
LOADER = $(FC) -lpthread
...
CFLAGS = -O3 -march=native -m64 -fomit-frame-pointer -fPIC -DADD_
FFLAGS = -O3 -march=native -m64 -fomit-frame-pointer -fPIC

Adapt the last two lines to your needs, -fPIC is the important piece. Then

make
cd lib
ar -x libcblas.a
gfortran -lopenblas -shared -o libcblas.so *.o
sudo cp libcblas.* /usr/local/lib/

If you get an error about a missing library openblas with the gfortran command then you should first check if your LIBRARY_PATH is set correctly (i.e. pointing to the place where you installed OpenBLAS).

Continuing with LAPACK, change the file make.inc (copied from make.inc.example) in the extracted directory as follows:

OPTS     = -O3 -march=native -m64 -fomit-frame-pointer -fPIC
...
NOOPT    = -O0 -fPIC
...
LOADOPTS = -lopenblas -lcblas
...
LAPACKLIB = liblapack.3.?.?.a # `?` depends on your version!

Again, -fPIC is the important piece. Then (subsitute the correct version for 3.?.?)

make lapacklib
mkdir tmp
cd tmp
cp ../liblapack.3.?.?.a .
ar -x liblapack.3.?.?.a
gfortran -lopenblas -lcblas -shared -o liblapack.3.?.?.so *.o
sudo cp liblapack.3.?.?.* /usr/local/lib

Finally, add the following symbolic links in /usr/local/lib:

cd /usr/local/lib
sudo ln -sn liblapack.3.?.?.a liblapack.a
sudo ln -sn liblapack.3.?.?.so liblapack.so

Ready for the python part!

Numpy

git clone https://github.com/numpy/numpy

In the numpy folder, create a site.cfg with the following two sections:

[default]
library_dirs = /usr/local/lib
include_dirs = /usr/local/include

[atlas]
atlas_libs = openblas,cblas

Check the detected configuration with python setup.py config. You should see several ATLAS_INFO paired with None. If there is something like 3.8.2 instead of None then you have an ATLAS install somewhere on your system and numpy won't use OpenBLAS. Get rid of this install (e.g. via apt-get purge) and rerun the config command. If ATLAS_INFO is completely missing then numpy couldn't find your libopenblas* libraries — you need to check all previous steps again. Now:

python setup.py build
sudo python setup.py install

Test your installation with this (Before doing a system-wide installation I prefer to do a local installation via python setup.py install --prefix=~/local/to/me. In this case you need to adopt PYTHONPATH accordingly). On the following computer

cat /proc/cpuinfo
...
model name     : Intel(R) Core(TM) i7 CPU 870  @ 2.93GHz
...

I get

FAST BLAS
version: 1.8.0.dev-3f10c36
maxint: 9223372036854775807

dot: 0.162246799469

For reference, an ATLAS-based numpy installation (via apt-get) takes about 0.26 sec, numpy without any optimized BLAS takes about 0.98 sec (on the mentioned computer). You can change the number of cores OpenBLAS utilizes via OPENBLAS_NUM_THREADS, e.g. export OPENBLAS_NUM_THREADS=2 results in

 :::bash
FAST BLAS
version: 1.8.0.dev-3f10c36
maxint: 9223372036854775807

dot: 0.0949754238129 sec

Scipy

git clone https://github.com/scipy/scipy

I mentioned conspicuously often some ATLAS installation on your system, but why have one anyway, this is about OpenBLAS, after all?! The funny (or rather not so) fact is that for scipy the following is necessary:

sudo apt-get install libatlas-base-dev
cd /usr/local/lib
sudo ln -sn /usr/lib/atlas-base/liblapack_atlas.a liblapack_atlas.a
sudo ln -sn /usr/lib/atlas-base/liblapack_atlas.so liblapack_atlas.so

But only after you have a working numpy installation! Otherwise it interferes with OpenBLAS. This is a work around for a problem that I don't quite understand and that seems to bother only some people, well, and me. (To the reader: If you know of a solution, please tell me). Your site.cfg looks like that:

[default]
library_dirs = /usr/local/lib
include_dirs = /usr/local/include

[atlas]
atlas_libs = lapack_atlas,openblas,cblas

(There are no sections for umfpack. Adapt accordingly to your needs). Now

python setup.py build
sudo python setup.py install

results in a working scipy installation (i.e. python -c "import scipy.linalg" works without any segfaults.). Timings for the scipy installation can be done via this script (it has some room for improvement, though ...). My machine produces

cholesky: 0.080588388443 sec
svd: 1.13443040848 sec

Finally, if you feel good enough (and do a pip install nose), you can run nose tests via

python -c "import numpy; numpy.test(verbose=2)"
python -c "import scipy; scipy.test(verbose=2)"

(Note: I didn't!). Comments, corrections, pointers, etc. are more than welcome.