MacでGPU(cuda)が使えるtensorflowをビルドする

2019/01/10追記
MojaveからNVIDIA eGPUがサポートされなくなりました。サポートされる気配もありません。CUDAは使えなくなりました。おとなしくUbuntuを使いましょう。
→ https://qiita.com/74th/items/1ead4955b69d91023305


方法は以下に最もまとまって書かれている。https://gist.github.com/smitshilu/53cf9ff0fd6cdb64cca69a7e2827ed0f


tensorflow-gpuパッケージを使うこともできるが、tensorflowのバージョンが少し古い（今のバージョンはMacOSでのGPUはサポートされていない）のと、自分の環境のCUDAのバージョンで動作するとは限らないため、自前でビルドする必要がある。

なお、私のビルドしたものは下記においています。もし、環境が一致すれば使えると思います。

https://j74th.com/tensorflow/

* 1.8.0追記 :v1.8.0の場合は、ncclをMacOS用にビルドして、このパッチでいけました。
  * nccl: https://github.com/74th/nccl 
  * patch: https://gist.github.com/74th/31eacbbac6351649caa417b19231f09e 
* 1.7.0追記 :v1.7.0の場合はこのパッチでいけました https://gist.github.com/74th/e06c5f243f83728cbf189d3b1e813e9c

この記事は以下のバージョンをターゲットとする。

* tensorflow v1.5.0
* OSX: 10.13.3(High Sierra)
* XCode: 8.2
* CUDA Driver: 9.1(387.128)
* cuDNN: 7
* GPU Driver Version: 387.10.10.10.25.156
* OpenMP (LLVM v5.0.0)
* Python: 3.6.4
* Bazel: 0.9

eGPUを使う場合、GPUドライバをインストールするには、以下の手順を行う。

* SIPを解除する。(CMD+RでMacを立ち上げ、Terminalから`csrutil disable`を入力する)
* https://github.com/vulgo/webdriver.sh のWebインストーラを利用する。
* 詳しくは→ https://egpu.io/forums/mac-setup/wip-nvidia-egpu-support-for-high-sierra/

CUDA Driver及びCUDA Toolkit、CUDA sampleをインストールする。

ダウンロード: http://www.nvidia.co.jp/object/mac-driver-archive-jp.html

この時、GPUドライバのバージョンとCUDAのバージョンが一致している必要があり、どのCUDAのバージョンとGPUドライバが一致しているか不明なため、とりあえずどちらも最新化して検証した。

正しくCUDAが動作するかどうか試すには、CUDA sampleから以下を実行すると良い。

```
cd /Developer/NVIDIA/CUDA-9.1/samples/1_Utilities/deviceQuery
sudo make
./deviceQuery
```

cuDNNは以下からダウンロードして、`/usr/local/cuda`に展開する。

ダウンロード: https://developer.nvidia.com/cudnn

現状のXcode8.3以降のclangがCUDAに対応していないため、XCode8.2をインストールする必要がある。

ダウンロード: https://developer.apple.com/download/more/

/Applications/Xcode8.2.appとかとして置いて、`sudo xcode-select -s /Applications/Xcode8.2.app`とすると、利用するXCodeを切り替えることができる。

bazelは最新版0.10.0が動作しない（どうも、0.1と勘違いされるっぽい）ため、bazel 0.9.0をインストールする。

ダウンロード: https://github.com/bazelbuild/bazel/releases/tag/0.9.0

OpenMPのライブラリが必要になる。

ダウンロード OpenMP Source code : http://releases.llvm.org/download.html

```sh
xz -dc openmp-5.0.0.src.tar.xz | tar xfv -
cd openmp-5.0.0.src.tar.xz
mkdir build
cd build
cmake ..
make install
```

tensorflowソースコードをcloneする。

```
git clone https://github.com/tensorflow/tensorflow.git -b v1.5.0
```

以下の3つのソースコードの、`__align(sizeof(T))__`の文字列を削除する。

* tensorflow/core/kernels/depthwise_conv_op_gpu.cu.cc
* tensorflow/core/kernels/split_lib_gpu.cu.cc
* tensorflow/core/kernels/concat_lib_gpu_impl.cu.cc

`./configure`で、以下の通り設定をする。

Cuda compute capabilitiesの値のみ、https://developer.nvidia.com/cuda-gpus を見て、自分のGPUに合わせて、設定する。（GTX10X0は6.1、GTX9X0は5.2）

```
$./configure
You have bazel 0.9.0-homebrew installed.
Please specify the location of python. [Default is /Users/nnyn/.pyenv/versions/3.6.4-cuda/bin/python]:


Found possible Python library paths:
  /Users/nnyn/.pyenv/versions/3.6.4-cuda/lib/python3.6/site-packages
Please input the desired Python library path to use.  Default is [/Users/nnyn/.pyenv/versions/3.6.4-cuda/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 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.1


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


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]:
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]: 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]:


Add "--config=mkl" to your bazel command to build with MKL support.
Please note that MKL on MacOS or windows is still not supported.
If you would like to use a local MKL instead of downloading, please set the environment variable "TF_MKL_ROOT" every time before build.

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

Configuration finished
```

ビルドする。

```sh
export CUDA_HOME=/usr/local/cuda
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:/usr/local/cuda/extras/CUPTI/lib 
export LD_LIBRARY_PATH=$DYLD_LIBRARY_PATH
export PATH=$DYLD_LIBRARY_PATH:$PATH
bazel build --config=cuda --config=opt --action_env PATH --action_env LD_LIBRARY_PATH --action_env DYLD_LIBRARY_PATH //tensorflow/tools/pip_package:build_pip_package
```

ビルド後、インストールする。

```
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
sudo pip install /tmp/tensorflow_pkg/tensorflow-1.5.0-cp36-cp36m-macosx_10_7_x86_64.whl
```