Ever since I got my first macbook in 2011, macOS has always been my favorite OS for coding. However, since none of the current MacBook models come with a Nvidia graphics card, I have to use Ubuntu in my desktop PC to efficiently trian Tensorflow models. And it’s a hassle to switch between two OS’s from time to time.

So I looked for an eGPU solution for macOS. Installed my GTX 1080 Ti on my macOS and finally successfully compiled Tensorflow 1.8. Here is how I did it:

Acknowledgements

The following two articles helped me a lot:

  • https://segmentfault.com/a/1190000015807229 (Chinese)
  • https://gist.github.com/tothandras/a637ae10ae84585924e930cb254e0760

Most of the content of this post is referred from above articles. However, the TensorFlow source code patch doesn’t work anymore since one of the repos has been deleted on GitHub. You won’t be able to compile Tensorflow if you follow those steps exactly.

I have fixed the protobuf compilation issue, described here: github.com/tensorflow/tensorflow/issues/17067#issuecomment-420523109

Versions

Installing the correct versions of all drivers is crucial in this tutorial. The versions we will be using are:

  • Tensorflow 1.8
  • macOS High Sierra 10.13.6
  • NVIDIA Web Driver: 387.10.10.15.15.108
  • CUDA 9.2
  • cuDNN v7.2.1
  • Xcode 8.2.1
  • bazel 0.14.0
  • Python 3.6

Install Dependencies

Xcode 8.2.1

Download and install Xcode 8.2.1 at https://developer.apple.com/download/more/

You probably already have Xcode 9 installed. You can put Xcode 8.2.1 into a subfolder at /Applications/Xcode 8.2.1/Xcode.app, so that you can keep both version, then switch the tool chain to 8.2.1:

sudo xcode-select -s /Applications/Xcode\ 8.2.1/Xcode.app

Confirm your clang version:

$ clang -v
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode 8.2.1/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Python 3.6.5

brew install python3 will install the latest Python 3.7. So make sure you follow these commands to install Python 3.6.5:

$ brew unlink python
$ brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/f2a764ef944b1080be64bd88dca9a1d80130c558/Formula/python.rb
$ pip3 install --upgrade pip setuptools wheel

CUDA

  1. Nvidia GeForce driver release 387.10.10.15.15.108 at: https://images.nvidia.com/mac/pkg/387/WebDriver-387.10.10.15.15.108.pkg
  2. CUDA driver at https://www.nvidia.com/object/mac-driver-archive.html. For me, I used release 396.148
  3. CUDA Toolkit 9.2 at https://developer.nvidia.com/cuda-toolkit

Use the following command to verify the installtion:

$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Tue_Jun_12_23:08:12_CDT_2018
Cuda compilation tools, release 9.2, V9.2.148

cuDNN

NVIDIA cuDNN is a GPU-accelerated library of primitives for deep neural networks.

Download cuDNN here: https://developer.nvidia.com/rdp/cudnn-download. You need to sign up for a Nvidia developer account to download it.

Extra the files into /usr/local/cuda/:

$ tar -xzvf cudnn-9.2-osx-x64-v7.2.1.38.tgz
$ sudo cp cuda/include/cudnn.h /usr/local/cuda/include
$ sudo cp cuda/lib/libcudnn* /usr/local/cuda/lib
$ sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib/libcudnn*

CUDA-Z

Install CUDA-Z by brew:

$ brew cask install cuda-z

Bazel

Make sure you installed Bazel 0.14.0:

$ curl -O https://github.com/bazelbuild/bazel/releases/download/0.14.0/bazel-0.14.0-installer-darwin-x86_64.sh
$ chmod +x bazel-0.14.0-installer-darwin-x86_64.sh
$ ./bazel-0.14.0-installer-darwin-x86_64.sh
$ bazel version
Build label: 0.14.0

Compile TensorFlow

Clone the TensorFlow source code:

$ git clone https://github.com/tensorflow/tensorflow -b r1.8

Modify the source code so that we can compile it on MacOS:

$ git clone https://github.com/tensorflow/tensorflow -b r1.8
$ cd tensorflow
$ curl -O https://raw.githubusercontent.com/dinever/tensorflow-macos-gpu/master/patch/tensorflow-macos-gpu-r1.8.patch
$ git apply tensorflow-macos-gpu-r1.8.patch
$ curl -o third_party/nccl/nccl.h https://raw.githubusercontent.com/SixQuant/tensorflow-macos-gpu/master/patch/nccl.h

Make sure you are using Python 3.6.5:

$ python3 --version
Python 3.6.5

Run the configure script:

$ ./configure
Please specify the location of python. [Default is /usr/local/opt/python@2/bin/python2.7]: /usr/local/bin/python3

Found possible Python library paths:
  /usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Please input the desired Python library path to use.  Default is [/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages]

Do you wish to build TensorFlow with Google Cloud Platform support? [Y/n]: n
No Google Cloud Platform support will be enabled for TensorFlow.

Do you wish to build TensorFlow with Hadoop File System support? [Y/n]: n
No Hadoop File System support will be enabled for TensorFlow.

Do you wish to build TensorFlow with Amazon S3 File System support? [Y/n]: n
No Amazon S3 File System support will be enabled for TensorFlow.

Do you wish to build TensorFlow with Apache Kafka Platform support? [Y/n]: n
No Apache Kafka Platform support will be enabled for TensorFlow.

Do you wish to build TensorFlow with XLA JIT support? [y/N]: n
No XLA JIT support will be enabled for TensorFlow.

Do you wish to build TensorFlow with GDR support? [y/N]: n
No GDR support will be enabled for TensorFlow.

Do you wish to build TensorFlow with VERBS support? [y/N]: n
No VERBS support will be enabled for TensorFlow.

Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: n
No OpenCL SYCL support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]: y
CUDA support will be enabled for TensorFlow.

Please specify the CUDA SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 9.0]: 9.2

Please specify the location where CUDA 9.1 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:

Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: 7.2

Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:

Please specify a list of comma-separated Cuda compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size. [Default is: 3.5,5.2]6.1

Do you want to use clang as CUDA compiler? [y/N]:n
nvcc will be used as CUDA compiler.

Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:

Do you wish to build TensorFlow with MPI support? [y/N]:
No MPI support will be enabled for TensorFlow.

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:

Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]:
Not configuring the WORKSPACE for Android builds.

Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See tools/bazel.rc for more details.
	--config=mkl         	# Build with MKL support.
	--config=monolithic  	# Config for mostly static monolithic build.
Configuration finished

Start the compilation:

$ bazel clean --expunge
$ bazel build --config=opt --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0" --action_env PATH --action_env DYLD_LIBRARY_PATH //tensorflow/tools/pip_package:build_pip_package

Installation

$ gcc -march=native -c -fPIC tensorflow/contrib/nccl/kernels/nccl_ops.cc -o _nccl_ops.o
$ gcc _nccl_ops.o -shared -o _nccl_ops.so
$ mv _nccl_ops.so bazel-out/darwin-py3-opt/bin/tensorflow/contrib/nccl/python/ops
$ rm _nccl_ops.o

Build PIP Package:

$ bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/Downloads/

Clean up:

$ bazel clean --expunge

Install the package using pip:

$ pip3 uninstall tensorflow
$ pip3 install ~/Downloads/tensorflow-1.8.0-cp36-cp36m-macosx_10_13_x86_64.whl

It’s done! Now you can verify if GPU works with TensorFlow by the following Python script:

#!/usr/bin/env python

import tensorflow as tf

config = tf.ConfigProto()
config.log_device_placement = True

# Creates a graph.
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
with tf.Session(config=config) as sess:
    # Runs the op.
    print(sess.run(c))