CentOS 7.3 に CUDA 8.0 （＆NVIDIA P100） をインストールする

[NVIDIA CUDA Installation Guide for Linux](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#axzz4VX488ASJ) と [CUDA Quick Start Guide]
(http://developer.download.nvidia.com/compute/cuda/8.0/secure/prod/docs/sidebar/CUDA_Quick_Start_Guide.pdf?autho=1484207780_f81f3dd051421deec828aea6c34a908a&file=CUDA_Quick_Start_Guide.pdf) を参考に CUDA8.0 を CentOS7.3 へインストールした際のメモです。

# CUDA の概要

CUDA は NVIDIA 社の開発した並列処理のプログラミングモデル。NVIDIA 社の GPU と同時に使う。CUDA をインストールすると C 等のプログラミング言語に拡張がされ、並列処理が簡単・高速に実現できる。

CUDA を使うには以下が必要：

* CUDA に対応した GPU（今回は P100 を使用）
* NVIDIA CUDA toolkit （今回は CUDA 8.0.44 を使用。NVIDIAドライバも同時にインストールされる）
* OS(今回は CentOS 7.3を使用）

# CUDA インストール事前準備

## GPU の確認
CUDA 対応 GPU が正しく設置されていることを確認する。

確認方法は以下：

```
$ lspci | grep -i nvidia
0c:00.0 3D controller: NVIDIA Corporation GP100GL (rev a1)
84:00.0 3D controller: NVIDIA Corporation GP100GL (rev a1)
```

※トラブルが発生した場合は、以下でエラーメッセージが出ていないかを確認するのも有効

```
$ dmesg | grep NVRM
```

例えば以下のようなエラーが出たりする（以下はサーバファームウェアが対応していなかった場合の例）：

```
[ 1490.618920] NVRM: This PCI I/O region assigned to your NVIDIA device is invalid:
NVRM: BAR1 is 0M @ 0x0 (PCI:0000:0c:00.0)
[ 1490.618926] NVRM: The system BIOS may have misconfigured your GPU.
[ 1490.618962] NVRM: This PCI I/O region assigned to your NVIDIA device is invalid:
NVRM: BAR1 is 0M @ 0x0 (PCI:0000:84:00.0)
```


## Linux バージョンの確認

CUDA8.0 は CentOS 6.x, 7.x に対応。今回は 7.3.1611 を使用。確認方法は以下：

```
$ uname -m && cat /etc/*release
x86_64
CentOS Linux release 7.3.1611 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.3.1611 (Core)
CentOS Linux release 7.3.1611 (Core)
```

## gcc バージョンの確認

CUDA8.0 は gcc 4.8.2 が必要。今回は 4.8.5 を使用。確認方法は以下：

```
$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

## カーネルバージョンの確認

CUDA8.0 は Kernel 3.10 が必要。今回は 3.10.0-514.el7 を使用。確認方法は以下：

```
$ uname -r
3.10.0-514.el7.x86_64
```

## kernel headers と development packages の確認

CUDA ドライバインストールにはカーネルと同じバージョンの kernel headers と development packages が必要。今回は 3.10.0-514.el7 がインストールされていなければならない。確認方法は以下：

```
$ yum list installed | grep kernel
abrt-addon-kerneloops.x86_64          2.1.11-45.el7.centos             @anaconda
kernel.x86_64                         3.10.0-514.el7                   @anaconda
kernel-devel.x86_64                   3.10.0-514.el7                   @anaconda
kernel-headers.x86_64                 3.10.0-514.el7                   @anaconda
kernel-tools.x86_64                   3.10.0-514.el7                   @anaconda
kernel-tools-libs.x86_64              3.10.0-514.el7                   @anaconda
```

インストールされていない場合は以下でインストールする：

```
$ sudo yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r)
```

## CUDA Toolkit (Runfile) のダウンロード

ファイルは https://developer.nvidia.com/cuda-downloads からダウンロードする。今回は Runfile をダウンロードする。バージョンは 8.0.44：

```
$ wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run
```

※ 過去に CUDA をインストールした場合は[こちら](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#handle-uninstallation)の手順に従ってアンインストールする必要あり

# CUDA のインストール（Runfile を使用）

Runfile によりインストールされるものは以下の通り：

* NVIDIA Driver
* CUDA Toolkit
* CUDA Sample

##  Nouveau ドライバをオフにする

Nouveau ドライバ有無の確認には以下のコマンドを使用。何かが表示された場合にはオフにする必要がある：

```
$ lsmod | grep nouveau
```

オフにするには /etc/modprobe.d/blacklist-nouveau.conf を以下の内容で作成し、

```
$ sudo vi /etc/modprobe.d/blacklist-nouveau.conf

---
blacklist nouveau
options nouveau modeset=0
```

カーネル initramfs を以下のコマンドを使って再生成する：

```
$ sudo dracut --force
```

## デバイスファイルの確認

デバイスファイル /dev/nvidia* が存在し、アクセス権 0666 （rw-rw-rw-）であることを確認する。このファイルは CUDA ドライバーが NVIDIA ドライバーカーネルと情報をやり取りするのに必要。NVIDIA ドライバーを使うアプリが存在するとこのファイルは自動生成されるとのこと。ファイルが無い場合には以下のスクリプトを使って生成する。

```
#!/bin/bash

/sbin/modprobe nvidia

if [ "$?" -eq 0 ]; then
  # Count the number of NVIDIA controllers found.
  NVDEVS=`lspci | grep -i NVIDIA`
  N3D=`echo "$NVDEVS" | grep "3D controller" | wc -l`
  NVGA=`echo "$NVDEVS" | grep "VGA compatible controller" | wc -l`

  N=`expr $N3D + $NVGA - 1`
  for i in `seq 0 $N`; do
    mknod -m 666 /dev/nvidia$i c 195 $i
  done

  mknod -m 666 /dev/nvidiactl c 195 255

else
  exit 1
fi

/sbin/modprobe nvidia-uvm

if [ "$?" -eq 0 ]; then
  # Find out the major device number used by the nvidia-uvm driver
  D=`grep nvidia-uvm /proc/devices | awk '{print $1}'`

  mknod -m 666 /dev/nvidia-uvm c $D 0
else
  exit 1
fi
```

## CUDA インストールの実行

Runfile を実行する：

```
$ sudo sh cuda_8.0.44_linux-run --silent
```

## PATH の追加

PATH と LD_LIBRARY_PATH に以下を追加する(64bitの場合)：

```
$ export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
$ export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64\
                         ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
```