macにeGPUを繋いでTensorflow(GPU版)を動かす

macにNVIDIA製GPUをeGPUとして繋いでTensorflowを動かすことができました．
研究室でmacを買い替えたのでPython環境構築からまとめておきます．

#環境
- iMac 2017(macOS Sierra 10.12.6)
- SONNET eGFX Breakaway Box
- NVIDIA GeForce GTX 1080 Ti (STRIX-GTX1080TI-O11G)

NVIDIA製のGPUであれば基本的に動くはずです．
またmacOS High SierraではGeForceのドライバが入らず**動作しません**でした(2017.12.9 現在)．


#今回やること

- Python環境構築
- GeForceドライバのインストール(GPUそのものを動かすために必要)
- CUDA, cuDNNのインストール(GPUをグラフィック用途以外で使う(=GPGPU)ために必要)
- Tensorflow-GPUのインストール

#Pythonの環境構築
Python3.6.xを使いたいのでpyenvを使ってインストールします．
インストールしたバージョンは現時点で最新の**Python 3.6.3**です．
こちらの記事を一通りやれば大丈夫でした．
[MacOSとHomebrewとpyenvで快適python環境を。](https://qiita.com/crankcube@github/items/15f06b32ec56736fc43a)


#GeForceドライバのインストール

##macOSのSIPを無効にする
1. **リカバリーモード**(電源オフの状態からCommand+Rを押したまま電源ボタンを押す)でmacを起動する．私の場合HighSierraからダウングレードしたためかOption+Command+Rでした．
2. メニューバーのユーティリティ→**ターミナル**を起動する．
3. `csrutil disable`と入力する．
4. シャットダウンする．

##automate-eGPUを使ったドライバのインストール
macとeGPUを接続してからmacを通常起動します．
起動したらターミナルを起動して以下のコマンドを実行します．

    curl -o automate-eGPU.sh https://raw.githubusercontent.com/goalque/automate-eGPU/master/automate-eGPU.sh
    chmod +x automate-eGPU.sh
    sudo ./automate-eGPU.sh
質問内容はすべて`y`で大丈夫でした．最後の行を実行すると以下のようになるはずです．

    ***      automate-eGPU.sh v1.0.1      ***
    * (c) 2016, 2017 by Goalque & FricoRico *
    *****************************************
    Detected eGPU
     GP102 [GeForce GTX 1080 Ti]
    Current OS X
     10.12.6 16G29
    Previous OS X
     [not found]
    Latest installed Nvidia web driver
     [not found]
    No Nvidia web driver detected.
    Checking IOPCITunnelCompatible keys...
    
    Searching for matching driver...
    
    Driver [378.05.05.25f01] found from:
    https://images.nvidia.com/mac/pkg/378/WebDriver-378.05.05.25f01.pkg
    Do you want to download this driver (y/n)?
    y
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 62.1M  100 62.1M    0     0  2238k      0  0:00:28  0:00:28 --:--:-- 5218k
    Driver downloaded.
    Removing validation checks...
    Modified package ready. Do you want to install (y/n)?
    y
    installer: Package name is NVIDIA Web Driver 378.05.05.25f01
    installer: Installing at base path /
    installer: The install was successful.
    installer: The install requires restarting now.
    Checking IOPCITunnelCompatible keys...
    
    IOPCITunnelCompatible mods done.
    Add: ":IOKitPersonalities:AppleGraphicsDevicePolicy:ConfigMap:Mac-77F17D7DA9285301" Entry Already Exists
    Board-id added.
    Rebuilding caches...
    All ready. Please restart the Mac.
**再起動**するとmacにGPUが認識されます（リンゴマーク→このMacについて→システムレポートから確認できます）．
※ちなみにRadeon Pro 560は環境構築中のmacに標準搭載のGPUです．
<img width="863" alt="スクリーンショット 2017-12-08 23.07.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/222278/9bb76c18-d60b-65ad-517e-02b27e10dbc4.png">

#CUDA, cuDNNのインストール
##CUDA Toolkit
NVIDIAの[本家サイト](https://developer.nvidia.com/cuda-toolkit-archive)から**CUDA Toolkit 8.0 GA2**をダウンロード&インストールします．
<img width="482" alt="スクリーンショット 2017-12-08 23.17.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/222278/626d8407-8875-ab17-58cd-005dff54a435.png">
インストーラが起動したらNextを押していけば大丈夫です．

##CUDAアップデート
上記のCUDA Toolkitに含まれるCUDAはv8.0.61のようですが，このバージョンではTensorflowがGPUを認識しませんでした．
またToolkitでCUDAをアップデートすると，v9.x系になってしまいTensorflowがエラーメッセージを吐きます．
そこで手動でv8.x系の最新版にしました．

[こちら](http://www.nvidia.co.jp/object/mac-driver-archive-jp.html)からCUDA v8.x系の最新版をダウンロード&インストールします．
現時点での最新版は**CUDA 8.0.90 driver for MAC**です．
インストールが終わったらターミナルを起動して以下のコマンドを実行します．

    echo 'export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib"' >> ~/.bash_profile
    echo 'export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/cuda/lib"' >> ~/.bash_profile
    echo 'export PATH="$PATH:/usr/local/cuda/bin"' >> ~/.bash_profile

##cuDNNのインストール
再びNVIDIAの[本家サイト](https://developer.nvidia.com/rdp/cudnn-download)から
**cuDNN v5.1 (Jan 20, 2017), for CUDA 8.0**をダウンロード&インストールします．
ここのリンクでは無料登録しないとダウンロードできません．
※v5.1でないとTensorflow-GPUがうまく動きません．

ターミナルを起動して次のコマンドを実行します．

    cd ~/Downloads 　#　ダウンロードしたディレクトリ
    tar xvfz cudnn-8.0-osx-x64-v5.1.tgz
    sudo mv cuda/include/* /usr/local/cuda/include/
    sudo mv cuda/lib/* /usr/local/cuda/lib/
#Tensorflowのインストール
次のコマンドを実行するだけです．

    pip install tensorflow-gpu

以上でmac上でTensorflow-GPUを動かすことができるようになりました．

    import tensorflow as tf
    sess = tf.Session()

こちら↑の2行をPython上で実行するとGeforce GTX 1080 Tiが認識されていることが確認↓できます．

    Python 3.6.3 (default, Dec  8 2017, 21:44:22) 
    [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import tensorflow as tf
    >>> sess = tf.Session()
    ...(中略)...
    name: GeForce GTX 1080 Ti
    major: 6 minor: 1 memoryClockRate (GHz) 1.683
    pciBusID 0000:86:00.0
    Total memory: 11.00GiB
    Free memory: 10.81GiB
    2017-12-09 01:25:05.202056: I tensorflow/core/common_runtime/gpu/gpu_device.cc:908] DMA: 0 
    2017-12-09 01:25:05.202059: I tensorflow/core/common_runtime/gpu/gpu_device.cc:918] 0:   Y 
    2017-12-09 01:25:05.202066: I tensorflow/core/common_runtime/gpu/gpu_device.cc:977] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:86:00.0)

お疲れさまでした