CUDA 10.2 Install 備忘録

#概要
DarknetでCUDAとcuDNNを使用するため、これらをインストールする手順の備忘録
鶏脳なので…
本PCでは、ここの作業以前に何らのNVIDIAソフトはインストールしていない。
まぁDarknetの[サイト](https://pjreddie.com/darknet/install/)にも書いてあるけど ("I won't go into CUDA installation in detail because it is terrifying.")、うまくいかないことが多くってNVIDIAにはもっと洗練されたインストレーションを提供していただきたい。

- 実施時期: 2019年12月
- OS: Ubuntu18.04LTS
- GPU: GeForce GTX 1070

##前準備
CUDA対応NVIDIAボードが刺さっていることを確認する。

```Terminal
$ lspci | grep -i nvidia
01:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GP104 High Definition Audio Controller (rev a1)
```

##CUDAのインストール
インストーラはwgetでダウンロードするコマンドだけのインストールする手順
下記は[オフィシャル](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation)を参照した。


```Terminal
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo apt-key add /var/cuda-repo-10-2-local-10.2.89-440.33.01/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda
reboot
```

もしこれで失敗したらCUDA10.1だけど[ココ](https://infinite8institute.com/cuda-install)を試してみよう、10.2に読み替えて。

インストーラ(deb[local])をNVIDIAのサイトからダウンロードしてインストールする[手順](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation)がNVIDIAの推奨なのかも。

この後インストールするDarknet用にパス2行を忘れずにbashrcに追加しておく。

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

##cuDNNのインストール
v10.2のインストーラを[オフィシャルサイト](https://developer.nvidia.com/rdp/cudnn-download)から/Downloadsにダウンロードする。
辿っていくと３種類のインストーラがあるところに行き着く。

- cuDNN Library for Linux
- cuDNN Runtime Library for Ubuntu18.04 (Deb)
- cuDNN Developer Library for Ubuntu18.04 (Deb)

ここでは一番目のLibrary "cudnn-10.2-linux-x64-v7.6.5.32.tgz"ファイルをダウンロードする。手順は下記の通り[オフィシャル](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#installlinux-tar)に従う。

```Terminal
cd /Downloads
tar -xzvf cudnn-10.2-linux-x64-v7.6.5.32.tgz
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*
```

ちなみに２番目のRuntimeがほとんどのユーザが使用するライブラリなのでこれを入れてもよいのかも。
入れ方は[ココ](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#installlinux-deb)を参照。インストーラの"sudo dpkg -i libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb"をダウンロードし、dpkgを実行するだけなんだとさ…

```Terminal
cd /Downloads
sudo dpkg -i libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb
```

でもdpkgでインストール中、symbolic linkエラーが発生し先に進めない。対策は後述する。


３番目のDeveloperはCUDAの関数を使ってコーディングするヘビーユーザ用ライブラリなので、コーディングする必要がなければDeveloperはインストールしない。


##確認1
インストールできたか簡単に確認する。
ただし、この２つのコマンドだけで正しくインストールできたか判断してよいのかはわからない。

```Terminal
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Wed_Oct_23_19:24:38_PDT_2019
Cuda compilation tools, release 10.2, V10.2.89


$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 1070    On   | 00000000:01:00.0  On |                  N/A |
| 27%   22C    P8     7W / 151W |    167MiB /  8117MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1152      G   /usr/lib/xorg/Xorg                            93MiB |
|    0      1332      G   /usr/bin/gnome-shell                          71MiB |
+-----------------------------------------------------------------------------+
```

Driver Version: 440.33.01と表示されているが、明示的にGPUのドライバはインストールしていないので、CUDAをインストールするとドライバもインストールされる様子。
当たり前のように聞こえるが、CUDAで苦労した人はわかると思うが、ネットで調べると所かしこにnvidia-driver-***インストール方法が書かれていて、個別にインストールする必要があるの？と思ってしまう、が、必要ない、と思われる。

##確認2
個人的にはコンパイルして確認できなければ気持ちが悪い。
cuDNNのRuntime Libraryを入れると、下記のパスにサンプルコードが入る。

/usr/local/cuda-10.2/samples

サンプルを下記の通り[手順](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#compiling-examples)に従いmakeする。

```Terminal
cd /usr/local/cuda-10.2/samples
sudo make -k
```
オプションなしのmakeだと途中エラーが発生し先に進めないので、-kオプションをつけるようにオフィシャルに書かれていた。
ここで作成された実行ファイルでインストール状態を確認する。

このsamplesフォルダのbin/x86_64/linux/releaseフォルダに実行ファイルが作成されるので、この中のdeviceQueryとbandwidthTestを実行しResult = PASSとなることを確認する。
まず、deviceQueryを実行して確認。

```Terminal
$ cd bin/x86_64/linux/release
$ sudo ./deviceQuery
./deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "GeForce GTX 1070"
  CUDA Driver Version / Runtime Version          10.2 / 10.2
  CUDA Capability Major/Minor version number:    6.1
  Total amount of global memory:                 8117 MBytes (8511488000 bytes)
  (15) Multiprocessors, (128) CUDA Cores/MP:     1920 CUDA Cores
  GPU Max Clock rate:                            1683 MHz (1.68 GHz)
  Memory Clock rate:                             4004 Mhz
  Memory Bus Width:                              256-bit
  L2 Cache Size:                                 2097152 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
  Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  2048
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and kernel execution:          Yes with 2 copy engine(s)
  Run time limit on kernels:                     Yes
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Disabled
  Device supports Unified Addressing (UVA):      Yes
  Device supports Compute Preemption:            Yes
  Supports Cooperative Kernel Launch:            Yes
  Supports MultiDevice Co-op Kernel Launch:      Yes
  Device PCI Domain ID / Bus ID / location ID:   0 / 1 / 0
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 10.2, CUDA Runtime Version = 10.2, NumDevs = 1
Result = PASS
```

PASSしているので、bandwidthTestも実行

```Terminal
$ sudo ./bandwidthTest
[CUDA Bandwidth Test] - Starting...
Running on...

 Device 0: GeForce GTX 1070
 Quick Mode

 Host to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes)        Bandwidth(GB/s)
   32000000                     12.8

 Device to Host Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes)        Bandwidth(GB/s)
   32000000                     13.1

 Device to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes)        Bandwidth(GB/s)
   32000000                     195.0

Result = PASS

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
```
PASSしている。

##cuDNNインストール中のエラー
インストール中、"libcudnn.so.7 is not a symbolic link"のエラーではまったお話
症状は下記

```Terminal
$ sudo dpkg -i libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb
Selecting previously unselected package libcudnn7.
(Reading database ... 202410 files and directories currently installed.)
Preparing to unpack libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb ...
Unpacking libcudnn7 (7.6.5.32-1+cuda10.2) ...
Setting up libcudnn7 (7.6.5.32-1+cuda10.2) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
/sbin/ldconfig.real: /usr/local/cuda-10.2/targets/x86_64-linux/lib/libcudnn.so.7 is not a symbolic link
```

sudo ldconfigを試したが、同じ"libcudnn.so.7 is not a symbolic link"で終わってしまう。
そこで下記URLを参照した。

https://askubuntu.com/questions/1025928/why-do-i-get-sbin-ldconfig-real-usr-local-cuda-lib64-libcudnn-so-7-is-not-a
http://queirozf.com/entries/installing-cuda-tk-and-tensorflow-on-a-clean-ubuntu-16-04-install#-sbin-ldconfig-real-usr-local-cuda-lib64-libcudnn-so-5-is-not-a-symbolic-link

解決前のibcudnn関連共有ライブラリをチェックした。

```Terminal
$ cd /usr/local/cuda/lib64
$ ls -lha libcudnn*
-rwxr-xr-x 1 root root 439M  1月  7 22:08 libcudnn.so
-rwxr-xr-x 1 root root 439M  1月  7 22:08 libcudnn.so.7
-rwxr-xr-x 1 root root 439M  1月  7 22:08 libcudnn.so.7.6.5
-rw-r--r-- 1 root root 413M  1月  7 22:08 libcudnn_static.a
```
上記URLを参考にライブラリのリンクを張りなおした。

```Terminal
sudo rm libcudnn.so
sudo rm libcudnn.so.7
sudo ln libcudnn.so.7.6.5 libcudnn.so.7
sudo ln libcudnn.so.7 libcudnn.so
sudo ldconfig
```

再度dpkg を実行し、cuDNNのインストールは正常に完了。
一筋縄ではいかない。

以上