nvidia cudaセットアップ

Ubuntu 20.04LTSに、`NVIDIAドライバ(version 450)`、CUDA11対応の`CUDA Toolkit`と`cuDNN SDK 8.0.4`をインストールする方法をメモしておきます。TensorFlowを動かすのが目的です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/86ea1b9f-2dfe-f403-516c-5c58e8a7b690.png)
https://www.tensorflow.org/install/gpu

## `nouveau`をblacklistする
インストール直後はOSSの`nouveau`ドライバがロードされています。

```
$ lsmod | grep nouveau
nouveau              1949696  1
mxm_wmi                16384  1 nouveau
video                  49152  1 nouveau
ttm                   106496  2 drm_vram_helper,nouveau
drm_kms_helper        184320  4 ast,nouveau
i2c_algo_bit           16384  2 ast,nouveau
drm                   491520  8 drm_kms_helper,drm_vram_helper,ast,ttm,nouveau
wmi                    32768  2 mxm_wmi,nouveau
```

`CUDA`を使えるようにするにはNVIDIAのドライバが必要なので、`nouveau`を`blacklist`に記載し、initramfsからも抜いてNVIDIAのドライバが使えるようにします。再起動後に`nouveau`がロードされていないのを確認します。

```
$ sudo echo "blacklist nouveau" >> /etc/modprobe.d/blacklist-nouveau.conf
$ sudo echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf
$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-5.8.0-36-generic
$ sudo reboot
$ lsmod | grep nouveau
$ 
```

## インストールするドライバのバージョンを確認する
次にubuntuで配布しているドライバのバージョンを確認します。

```
$ ubuntu-drivers devices
== /sys/devices/pci0000:5d/0000:5d:00.0/0000:5e:00.0 ==
modalias : pci:v000010DEd00001DB4sv000010DEsd00001214bc03sc02i00
vendor   : NVIDIA Corporation
model    : GV100GL [Tesla V100 PCIe 16GB]
driver   : nvidia-driver-450 - distro non-free
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-460 - distro non-free recommended
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-440-server - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin
$
$
$ sudo apt info nvidia-driver-450 | grep -i version

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Version: 450.102.04-0ubuntu0.20.04.1
$
$
$ sudo apt info nvidia-driver-450-server | grep -i version

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Version: 450.80.02-0ubuntu0.20.04.3
$
```
NVIDIAのウェブサイトを確認すると450.80.02を配布しているので、このバージョンをインストールできる`nvidia-driver-450-server`をインストールすることにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/248a6fe9-72d4-7519-cc5b-24a0ce42527b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/aaff94d6-def0-0f87-1bab-ea9132ac6cb8.png)

## ドライバのインストールと起動確認
ドライバをインストールして、リブート後に`nvidia-smi`でドライバの起動確認します。

```
$ sudo apt install nvidia-driver-450-server
$ sudo reboot
$ 
$ lsmod | grep nvidia
nvidia_uvm           1003520  0
nvidia_drm             49152  0
nvidia_modeset       1183744  1 nvidia_drm
nvidia              19718144  2 nvidia_uvm,nvidia_modeset
drm_kms_helper        217088  5 drm_vram_helper,ast,nvidia_drm
drm                   552960  7 drm_kms_helper,drm_vram_helper,ast,drm_ttm_helper,nvidia_drm,ttm
$ 
$ nvidia-smi 
Fri Jan  8 16:11:05 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.80.02    Driver Version: 450.80.02    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla V100-PCIE...  Off  | 00000000:5E:00.0 Off |                    0 |
| N/A   33C    P0    37W / 250W |      0MiB / 16160MiB |      4%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
$
```

## `CUDA Toolkit`のインストール
次に`CUDA Toolkit`をインストールするのですが、Ubuntuではまだ11.0を配布していません。

```
$ sudo apt info nvidia-cuda-toolkit | grep -i version

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Version: 10.1.243-3
$ 
```

NVIDIAのウェブサイトに行き、Ubuntu 20.04を選ぶと表示されるインストール手順を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/05550c15-b349-2b52-96a7-2d4146a59292.png)

インストールのコマンドは`cuda-11-0`のようにバージョンを指定する必要があります。これなしで実行したらcudaの11.2がインストールされてしまいました。

```
$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
$ sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
$ sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
$ sudo apt-get update
$ sudo apt-get install cuda-11-0
$ sudo reboot
```

リブート後、`CUDA Toolkit`がちゃんとインストールできているか`nvcc -V`コマンドで確認します。入っていないと言われるのですが、パスが通っていないようなので通します。

```
$ nvcc -V

Command 'nvcc' not found, but can be installed with:

sudo apt install nvidia-cuda-toolkit

$ /usr/local/cuda/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0
$
$ echo "export PATH="/usr/local/cuda/bin:$PATH" >> /etc/bash.bashrc
```

## `cuDNN`のインストール
`cuDNN SDK 8.0.4`をNVIDIAのウェブサイトからダウンロードします。ダウンロードにはNVIDIAデベロッパーアカウント（無料登録）が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696922/edfd2c53-d764-42ea-b4c5-ba8456c95b92.png)

Ubuntu 20.04用のダウンロードがないのでcuDNN Library for Linux(x86_64)をダウンロードします。解凍してみるとフォルダ2個にヘッダーファイルやライブラリが入っているものの、コピー先の指示がありません。txtファイルはライセンス契約書です。。。

```
$ ls
include  lib64  NVIDIA_SLA_cuDNN_Support.txt
$
$ ls include/
cudnn_adv_infer.h  cudnn_cnn_infer.h  cudnn_ops_infer.h
cudnn_adv_train.h  cudnn_cnn_train.h  cudnn_ops_train.h
cudnn_backend.h    cudnn.h            cudnn_version.h
$
$ ls lib64/
libcudnn_adv_infer.so        libcudnn_cnn_train.so.8.0.4
libcudnn_adv_infer.so.8      libcudnn_ops_infer.so
libcudnn_adv_infer.so.8.0.4  libcudnn_ops_infer.so.8
libcudnn_adv_train.so        libcudnn_ops_infer.so.8.0.4
libcudnn_adv_train.so.8      libcudnn_ops_train.so
libcudnn_adv_train.so.8.0.4  libcudnn_ops_train.so.8
libcudnn_cnn_infer.so        libcudnn_ops_train.so.8.0.4
libcudnn_cnn_infer.so.8      libcudnn.so
libcudnn_cnn_infer.so.8.0.4  libcudnn.so.8
libcudnn_cnn_train.so        libcudnn.so.8.0.4
libcudnn_cnn_train.so.8      libcudnn_static.a
$
```


ググったら[公式ドキュメント](https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#install-linux)がすぐに見つかり、コピー先の指定とファイル権限の変更の指示がありました。パスも通しておきます。

```
$ sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
$ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64

$ sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
$ echo 'export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"' >> /etc/bash.bashrc
$ echo 'export LD_LIBRARY_PATH="/usr/lib/cuda/include:$LD_LIBRARY_PATH"' >> /etc/bash.bashrc
```
インストールがちゃんとできたかの確認には`mnistCUDNN`をコンパイルするらしい。必要なファイルは`cuDNN Code Samples and User Guide ~`にあるらしいので、Ubuntu18.04用の`deb`ファイルをダウンロードしてきて解凍します。

```
$ mkdir libcudnn8-samples
$ dpkg-deb -x libcudnn8-samples_8.0.4.30-1+cuda11.0_amd64.deb libcudnn8-samples
$
$ cd libcudnn8-samples/usr/src/cudnn_samples_v8/mnistCUDNN
$ make clean && make
$ ./mnistCUDNN
mnistCUDNN 
Executing: mnistCUDNN
cudnnGetVersion() : 8004 , CUDNN_VERSION from cudnn.h : 8004 (8.0.4)
Host compiler version : GCC 9.3.0

There are 1 CUDA capable devices on your machine :
device 0 : sms 80  Capabilities 7.0, SmClock 1380.0 Mhz, MemSize (Mb) 16160, MemClock 877.0 Mhz, Ecc=1, boardGroupID=0
Using device 0
...
...
0.0000012 0.0000006 

Result of classification: 1 3 5

Test passed!
$
```

無事コンパイルに成功しました。これでCUDAの設定は完了です。