Installing Numpy and OpenBLAS

Numpy is a great software package for doing numeric computations in Python. If set up right (i.e. using OpenBLAS), I’ve found it can be even faster than MATLAB’s highly optimized ATLAS backend. Unfortunately, if installed naïvely using pip, it can be very slow. Even installing it using sudo apt-get install python-numpy (on Ubuntu) is not as good as the following setup in my experience.

Here I will tell you how to set up Numpy and OpenBLAS on an Ubuntu machine from source (though I think they should be pretty transferable to any flavour of Linux). These instructions are based on the very useful blog post that can be found on odsf’s blog.

Before we begin

First, make sure you have these tools installed

sudo apt-get install git python-dev gfortran

Also, it might make things easier to make sure that the other Fortran compiler, g77, is not installed (though if you prefer to keep it around, you just have to take an extra step in the Numpy install).

OpenBLAS

The first step is to install OpenBLAS. This can be done via apt-get, but installing from source has the advantages that OpenBLAS will be fully optimized to your machine, and you can put it somewhere other than /usr/lib (which should hopefully allow Octave to be installed simultaneously, though I haven’t tried this yet).

To install OpenBLAS, do the following commands

  cd ~/src
  git clone https://github.com/xianyi/OpenBLAS
  cd OpenBLAS
  make FC=gfortran
  sudo make PREFIX=/opt/openblas install

As you can see, I prefer to put my OpenBLAS install in /opt, so it’s out of the way of things I install with apt-get.

Finally, you have to let your system know about these new libraries. Add a file to /etc/ld.so.conf.d/ called openblas.conf, containing the path to your new libraries (/opt/openblas/lib). Then run sudo ldconfig.

Numpy

Building Numpy requires Cython, so make sure it is installed (pip install cython, with sudo or --user as necessary depending on where you want to install it).

Next, we install Numpy

  cd ~/src
  git clone https://github.com/numpy/numpy
  cd ~/numpy

By default, the repository will be on the current development (master) branch. I prefer to use the latest stable branch. To find this, type git checkout v and press Tab. This should show you all the possible branches. Find the newest branch (largest version number) with no letters after it (indicating a full release). Right now it’s v1.10.4:

  git checkout v1.10.4

Add a file called site.cfg, with the following lines

  [default]
  include_dirs = /opt/openblas/include
  library_dirs = /opt/openblas/lib

  [openblas]
  openblas_libs = openblas
  library_dirs = /opt/openblas/lib

  [lapack]
  lapack_libs = openblas
  library_dirs = /opt/openblas/lib

This file lets Numpy know where your OpenBLAS libraries are. Run python setup.py config to make sure everything is set up correctly. You should see no mention of ATLAS. (TODO: I should try this with ATLAS installed, to see if Numpy ignores it or tries to use it.) If everything looks good, go ahead and call python setup.py build. If you have both Fortran compilers installed, call:

  python setup.py build --fcompiler=gnu95

to specify gfortran as the compiler (see Numpy install notes).

One of the benefits of using OpenBLAS is that it can make Numpy’s dot function for matrix-matrix multiplies really fast. For this to work, Numpy needs the file core/_dotblas.so to exist. In your Numpy source directory (where you should still be if you’re following along), look under build/lib.linux-x86_64-2.7/numpy/core, and make sure _dotblas.so is there. You can also run ldd on it, to make sure that it’s finding your OpenBLAS library all right. (Update: new versions of Numpy no longer create _dotblas.so, see below.)

If everything seems good, call python setup.py install. Installing to a virtual environment is best. Otherwise, use the --user flag to install to your home directory, or put the sudo command on front to install to the /usr directory.

To make sure everything is working right, I run the following script

import numpy as np
import numpy.random as npr
import time

# --- Test 1
N = 1
n = 1000

A = npr.randn(n,n)
B = npr.randn(n,n)

t = time.time()
for i in range(N):
    C = np.dot(A, B)
td = time.time() - t
print("dotted two (%d,%d) matrices in %0.1f ms" % (n, n, 1e3*td/N))

# --- Test 2
N = 100
n = 4000

A = npr.randn(n)
B = npr.randn(n)

t = time.time()
for i in range(N):
    C = np.dot(A, B)
td = time.time() - t
print("dotted two (%d) vectors in %0.2f us" % (n, 1e6*td/N))

# --- Test 3
m,n = (2000,1000)

A = npr.randn(m,n)

t = time.time()
[U,s,V] = np.linalg.svd(A, full_matrices=False)
td = time.time() - t
print("SVD of (%d,%d) matrix in %0.3f s" % (m, n, td))

# --- Test 4
n = 1500
A = npr.randn(n,n)

t = time.time()
w, v = np.linalg.eig(A)
td = time.time() - t
print("Eigendecomp of (%d,%d) matrix in %0.3f s" % (n, n, td))

And on my machine, I get these results

  multiplied two (1000,1000) matrices in 49.8 ms
  dotted two (4000) vectors in 6.87 us
  SVD of (2000,1000) matrix in 1.192 s
  Eigendecomp of (1500,1500) matrix in 7.805 s

If just the matrix-matrix multiply is slow, it’s likely because core/_dotblas.so didn’t get created, or can’t find your OpenBLAS library (see above). If the SVD and Eigendecomposition are slow, it’s likely that you have a problem with the LAPACK linking (this only happened when I tried to use the OpenBLAS installation from apt-get).

Update: no _dotblas.so in new Numpy

New versions of Numpy no longer create _dotblas.so, so don’t worry if you don’t see it. If Numpy is finding your OpenBLAS install when you do python setup.py config, you’re probably good.

Scipy

Scipy is easy to install, because it will make use of Numpy’s OpenBLAS bindings. Just run pip install scipy and you should be good to go, or install normally from source to get the lastest development version.