Skip to content

Instantly share code, notes, and snippets.

@protrolium
Forked from kylemcdonald/build-caffe.md
Last active August 23, 2017 00:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save protrolium/0d0b42774473ef6305c0 to your computer and use it in GitHub Desktop.
Save protrolium/0d0b42774473ef6305c0 to your computer and use it in GitHub Desktop.
How to build Caffe for OS X.

Theory of Building Caffe on OS X

(with addendums, tangents, and other follies)

Introduction

I have followed Kyle McDonald's Theory of Building Caffe after what could be described as some careless brew updates and obliviousness to the conflicts between various versions of OS X, CUDA, CUDA drivers, CuDNN, and Caffe itself. I am replicating Kyle's steps here and adding a few more which were unique to my case and may not necessarily work for everyone. The goal is to run python -c "import caffe" without crashing.

Official Caffe OS X Installation Guide

http://caffe.berkeleyvision.org/install_osx.html


Prerequisites:

  • OS X 10.9+ (in this case OS X Yosemite 10.10.5)
  • Xcode is installed. Run xcode-select --install to verify that the command line tools are installed.
  • Homebrew is installed

Dependencies

The first dependency is downloading and installing CUDA and CuDNN. In my case I had already installed CUDA 7.0 some months ago, but then decided to try the latest version for my current system: CUDA 7.5.20 for Mac OSX 10.10 x86_64. This ended up causing some headaches and incompatibility with Caffe down the road. I decided to start fresh with CUDA 7.0 and removed all versions installed on my machine.

Removing CUDA:

/System/Library/Extensions/CUDA.kext
/Library/Frameworks/CUDA.framework
/Library/LaunchAgents/com.nvidia.CUDASoftwareUpdate.plist
/Library/PreferencePanes/CUDA/Preferences.prefPane
/System/Library/StartupItems/CUDA/

If you installed the tookits and samples, delete the following also:

/Developer/NVIDIA/CUDA-x.x
/usr/local/cuda

CUDA installs itself in /Developer/NVIDIA/ and symlinks to /usr/local/cuda/. I reinstalled CUDA 7.0 compatible with OS X 10.10.5. Afterwards, I downloaded cuDNN v3 (September 8, 2015), for CUDA 7.0 and later from NVIDIA and moved the folder cuda it unzips as into /Developer/NVIDIA/ renaming it to CuDNN-v3. Usually this would be placed somewhere else, like /usr/local/cudnn but I decided to do something similar to the CUDA installer.

Next, we will install Python with homebrew: brew install python. Caffe recommends using Anaconda, but as far as I can tell it only helps by bundling a few modules (numpy, scipy, sklearn) that we can just as easily install with pip at the end.

When homebrew asks you to run pip install --upgrade pip setuptools only run pip install --upgrade pip. Otherwise you will have conflicts between a Python 2 and Python 3 installation.

Then we run the following as stated in the document, which will download and install a bunch of prerequisites for Caffe. The installation instructions assume you have numpy and protobuf installed. If not, first run:

$ brew install numpy protobuf

Then continue with the recommended steps:

$ brew install -vd snappy leveldb gflags glog szip lmdb
$ brew tap homebrew/science
$ brew install hdf5 opencv

boost and boost-python need to be installed from source. However version 1.58 is incompatible. To fix this we will modify the Homebrew formulas. Run brew edit boost, replace the contents with this formula and brew edit boost-python and use this formula. When you are done with this tutorial, replace the formula files with their original formulas by opening /usr/local/Library/Formula/ and running git checkout -- ..

For now, continue as recommended:

$ brew install --build-from-source --with-python -vd protobuf
$ brew install --build-from-source -vd boost boost-python

Sanity Checks

At this point we need to make sure that two things are the case:

  1. All shared libraries that reference a C++ standard library are using libc++ and not libstdc++
  2. boost-python is linked against the Homebrew-installed Python, not the system python (because we will also link Caffe against Homebrew's Python, and because pip is using Homebrew's Python).

We can check this with otool -L:

$ brew info boost
...
$ otool -L /usr/local/Cellar/boost/1.57.0/lib/libboost_system.dylib # this is one of the libs that caffe links against
...
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
...
$ brew info boost-python
...
$ otool -L /usr/local/Cellar/boost-python/1.57.0/lib/libboost_python.dylib
...
/usr/local/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.0)
...

It looks like Boost is the right version (1.57.0) and it's linking against the right libraries. If it's not, you will get Sigabrt and other strange errors from Python later when you try to import caffe.

If we were running an older versions of OS X, it would use libstdc++ by default for compiling Caffe, which means all the Homebrew formulas would have to be modified to match. Since we're using a newer version we don't have to do this.

Compiling Caffe

Next, we adjust the Makefile.config:

  1. Uncomment USE_CUDNN := 1 because we want to use it.
  2. Edit the PYTHON_INCLUDE. The example values use the system path for Python. We modify them to use the Homebrew path: PYTHON_INCLUDE := /usr/local/lib/python2.7/site-packages/numpy/core/include/ /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/include/python2.7.
  3. For the same reason as the previous step, edit PYTHON_LIB: PYTHON_LIB := /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/
  4. Uncomment WITH_PYTHON_LAYER := 1.
  5. Change the INCLUDE_DIRS to add CuDNN: INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /Developer/NVIDIA/CuDNN-v3/include
  6. Change the LIBRARY_DIRS to add CuDNN: LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /Developer/NVIDIA/CuDNN-v3/lib. It's very important that $(PYTHON_LIB) comes first here, otherwise make will try to use the system python that it finds in /usr/lib.
  7. Do not change BLAS := atlas. By default this will cause Caffe to link with Accelerate, which is a fast BLAS implementation provided by Apple with OS X.

Run make all from the main Caffe directory. If you have a quad-core processor or better you can type make all -j4 to speed up compilation a bit. Here are some errors you might run into with make:

  • If it complains about a specific library, you could have missed one of the prerequisites. Check with brew info x, where x is the name of the library it's complaining about, that it's correctly installed.

  • If it complains that something is not found for architecture x86_64, this is libstc++ vs libc++ mistmatch and you'll need to double-check all the prerequisites installed by Homebrew that they don't say libstdc++ in the otool -L output.

  • If it complains about pyconfig.h, make sure you are passing the right Python path to PYTHON_INCLUDE. For example, open /usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/include/python2.7 to see that pyconfig.h is in there. If not, you need to install Python with brew, or the path is different for your installation (e.g., a different version number like 2.7.10).

  • If it complains about nvcc fatal : The version ('7xxxx') of the host compiler ('Apple clang') is not supported you may need to install a compatilble version of XCode (in addition to the Command Line Tools, which may already be installed). The problem seems to be that the latest version of Apple's clang compiler is unsupported by CUDA. Even for CUDA 7.5, the latest supported version of XCode is XCode 6.2.

    • Download XCode 6.2
    • Install XCode into the Applications, "Keep both" if a newer version already exists on disk.
    • open XCode and check under Preferences > Locations that XCode 6.2 is selected under Command Line Tools.
  • If it complains about:

ImportError: dlopen(/Users/[username]/caffe/python/caffe/_caffe.so, 2): Library not loaded: @rpath/libcudnn.7.0.dylib
  Referenced from: /Users/[username]/caffe/python/caffe/_caffe.so
  Reason: image not found

… make sure that the libraries are symlinked in /usr/local/cuda/lib It was not enough to have libcudnn.7.0.dylib living inside /Developer/NVIDIA/CuDNN-v3/lib/ even with the export DYLD_LIBRARY_PATH='/Developer/NVIDIA/CuDNN-v3/lib':$DYLD_LIBRARY_PATH declared in my ~/.bashrc. To do this I had to create two new symbolic links:

$ sudo ln -s /Developer/NVIDIA/CuDNN-v3/lib/libcudnn.7.0.dylib /usr/local/cuda/lib
$ sudo ln -s /Developer/NVIDIA/CuDNN-v3/lib/libcudnn_static.a /usr/local/cuda/lib

(You can run checks with make clean and then make && make test && make runtest from your caffe directory).
Once make all finishes, run make pycaffe.

Next, make sure some system variables are configured correctly for Python. Open your ~/.bash_profile or equivalent in a text editor (e.g. in my case, subl ~/.bashrc). Now to add environment variables:

export DYLD_LIBRARY_PATH='/Developer/NVIDIA/CuDNN-v3/lib':$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH='/usr/local/cuda/lib/':$DYLD_LIBRARY_PATH
export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/cuda/lib:/Developer/NVIDIA/CuDNN-v3/lib:/Developer/NVIDIA/CUDA-7.0/lib:/usr/local/lib:/usr/lib:/usr/local/Cellar/:$DYLD_FALLBACK_LIBRARY_PATH
export PYTHONPATH=~/Documents/caffe/python:$PYTHONPATH

The first two tell Python where to load the dylibs for CUDA and CuDNN from. The third line tells Python where to load pycaffe from. Customize the PYTHONPATH line so it matches where you have caffe installed.

Now, if we try to test with python -c "import caffe" we will get an error No module named skimage.io. So we run pip install scikit-image. If we test again, No module named scipy so we pip install scipy. Testing again:

$ python
>>> import caffe
>>> 

WILDCARD

If it complains about caffe Fatal Python error: PyThreadState_Get: no current thread you need to reinstall boost-python:

brew uninstall boost-python
brew install --build-from-source --fresh -vd boost-python

Finally, testing one more time:

$ python
>>> import caffe
>>> 

Success _______ !

iPYTHON WILDCARD

When running ipython notebook it complains about ImportError: IPython.html requires pyzmq >= 13
In order to resolve this use pip to uninstall and re-install ipython

$ pip uninstall ipython
$ pip install "ipython[all]"

The issue is that notebooks have their own set of dependencies, which aren't installed with pip install ipython. However, having installed ipython, pip doesn't see the need to add anything if you then try the [all] form.

For some shells (e.g. zsh) it's necessary to escape or quote the square brackets (pip install ipython[all] would also work).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment