AWSのGPUインスタンスでChainerMNを動かす環境構築

ChainerMNを試してみようと思い、AWS上に環境構築をしてみたので、その作業記録を残しておきます。

AWSのp2インスタンスはそれなりの値段がするので、環境構築は素早く終わらせたいですよね。

# 構成

- AWS p2.8xlarge
- Ubuntu Server 16.04 LTS (HVM), SSD Volume Type - ami-efd0428f
- CUDA 8.0
- cuDNN v5.1
- Python 3.5.2
- Chainer 1.24.0
- ChainerMN 1.0.0b1, (b2でも確認)

# 参考サイト

- [Ubuntu 16.04へのCUDAインストール方法](http://qiita.com/yukoba/items/3692f1cb677b2383c983)
- [Chainer 1.5のインストールがうまくいかない人への非公式なTips](http://qiita.com/unnonouno/items/c491b6df59352159cbf0)
- [Chainer Documents](http://docs.chainer.org/en/stable/)
- [ChainerMN Documents](https://chainermn.readthedocs.io/en/latest/)
- [NCCL](https://github.com/NVIDIA/nccl)

# 作業

## 前準備

```bash
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install linux-generic
$ sudo apt-get install build-essential
$ vi .bashrc # 以下の2行を追加
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
export CPATH="/usr/local/include"
```

## NVIDIA DriverとCUDAのインストール

[CUDA Toolkit Download](https://developer.nvidia.com/cuda-downloads) にアクセスし、Linux、x86_64、Ubuntu、16.04、deb [network]と選択し、ダウンロードリンクを拾ってきて、以下の作業をする。

```bash
$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
$ sudo apt-get update
$ sudo apt-get install cuda nvidia-367
$ sudo reboot
$ sudo apt-get autoremove
$ rm cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
$ vi .bashrc # 以下の4行を追加
export CUDA_HOME="/usr/local/cuda-8.0"
export PATH="$CUDA_HOME/bin:$PATH"
export LD_LIBRARY_PATH="$CUDA_HOME/lib64:$LD_LIBRARY_PATH"
export CPATH="$CUDA_HOME/include:$CPATH"
```
ログインし直す。

## cuDNN 5.1のインストール

[cuDNN Download](https://developer.nvidia.com/rdp/cudnn-download)でDownload cuDNN v5.1 (Jan 20, 2017), for CUDA 8.0、cuDNN v5.1 Library for LinuxをダウンロードしてAWS上に置いておく。

```bash
$ tar zxvf cudnn-8.0-linux-x64-v5.1.tgz
$ sudo cp -a cuda/lib64/* $CUDA_HOME/lib64/
$ sudo cp -a cuda/include/* $CUDA_HOME/include/
$ sudo ldconfig
$ rm -rf cuda cudnn-8.0-linux-x64-v5.1.tgz
```

## シンボリックリンクを貼り直す（追記 2017-06-08）

前項の作業において、

```bash
$ sudo ldconfig
```

をしたところ、

```bash
/sbin/ldconfig.real: /usr/lib/nvidia-375/libEGL.so.1 is not a symbolic link
/sbin/ldconfig.real: /usr/lib32/nvidia-375/libEGL.so.1 is not a symbolic link
```

と出るようになっていたので、下の作業でシンボリックリンクを貼り直しました。

```bash
$ sudo mv /usr/lib/nvidia-375/libEGL.so.1 /usr/lib/nvidia-375/libEGL.so.1.org
$ sudo mv /usr/lib32/nvidia-375/libEGL.so.1 /usr/lib32/nvidia-375/libEGL.so.1.org
$ sudo unlink /usr/lib/nvidia-375/libEGL.so
$ sudo ln -s /usr/lib/nvidia-375/libEGL.so.375.66 /usr/lib/nvidia-375/libEGL.so
$ sudo unlink /usr/lib32/nvidia-375/libEGL.so
$ sudo ln -s /usr/lib32/nvidia-375/libEGL.so.375.66 /usr/lib32/nvidia-375/libEGL.so
$ sudo ldconfig
```

この対処であっているのかわかりませんが、とりあえず使えています。

## LightDM を止める
```bash
$ sudo vi /etc/default/grub # 12行目を以下の用に編集
GRUB_CMDLINE_LINUX="systemd.unit=multi-user.target"
$ sudo update-grub
$ sudo reboot
```

## Open MPIのインストール

[Open MPI Open Source High Performance Computing](https://www.open-mpi.org)からOpen MPIのダウンロードリンクを拾ってきて、以下の作業をする。

```bash
$ wget https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.1.1.tar.bz2
$ tar jxvf openmpi-2.1.1.tar.bz2
$ cd openmpi-2.1.1
$ ./configure --with-cuda
$ make -j4
$ sudo make install
$ cd
$ rm -rf openmpi-2.1.1 openmpi-2.1.1.tar.bz2
```

## NVIDIA NCCLのインストール
```bash
$ git clone https://github.com/NVIDIA/nccl.git
$ cd nccl
$ make CUDA_HOME=/usr/local/cuda-8.0
$ sudo mkdir /usr/local/nccl
$ sudo make PREFIX=/usr/local/nccl install
$ cd
$ rm -rf nccl
$ vi .bashrc # 以下の4行を追加
export NCCL_ROOT="/usr/local/nccl"
export CPATH="$NCCL_ROOT/include:$CPATH"
export LD_LIBRARY_PATH="$NCCL_ROOT/lib/:$LD_LIBRARY_PATH"
export LIBRARY_PATH="$NCCL_ROOT/lib/:$LIBRARY_PATH"
```

ログインし直す。

## Chainer, ChainerMNなどのインストール

```bash
$ sudo apt-get install python3-pip
$ sudo pip3 install --upgrade pip
$ pip3 install --user pillow h5py chainer\==1.24.0
$ pip3 install --user cython
$ pip3 install --user chainermn
```

# 詰まったところ

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

* 上の手順でやれば間違いないはず

## ChainerMNのインストールがうまくいかない

- 原因：CythonがLD_LIBRARY_PATHとCPATHを正しく見ていなかった

参考の[Chainer 1.5のインストールがうまくいかない人への非公式なTips](http://qiita.com/unnonouno/items/c491b6df59352159cbf0)によると、Cythonインストール前にLD_LIBRARY_PATHとCPATHが設定されていないといけないらしい。
また、pipをsudoで行うと、環境変数がrootに引き継がれないので注意。--userでやろう。