CUDA及びnvidia-driverのインストール方法

# CUDA及びnvidia-driverのインストール方法

- **CUDA**(Compute Unified Device Architecture)とは、Nvidiaが開発しているGPUアクセラレーションアプリケーションを作成するための開発環境です。

- **nvidia-driver**はその名の通り、`GTX`や`RTX`シリーズを始めとするNvidia製のGPUを制御するためのドライバです。

これら２つの役割を簡単に説明すると、**nvidia-driver**がハードとOSの仲介役となり、その上で**CUDA**というツールキット(アプリケーション郡)が`python`などのプログラムにGPUリソースを提供します。

## インストール方法

昔は動作しているグラフィックドライバを停止したり、`dkms`等でカーネルを焼き直す等々の作業が必要でしたが、今日は`deb`ファイル一つで簡単にインストール可能です。

> `CUDA11.2`を`Ubuntu 16.04`にインストールする場合の手順を示します。

### 1. CUDA toolkit配布サイトより自分の環境を選択していき、`.deb`ファイルのダウンロードコマンドを確認する
まず、[CUDA Toolkit 11.2 Downloads](https://developer.nvidia.com/cuda-downloads)　にアクセスします。

- `Linux` -> `x86_64` -> `Ubuntu` -> `16.04` -> `deb(local)`の順に選択して行くと

`Download Installer for Linux Ubuntu 16.04 x86_64`

というコンテンツボックス内に`.deb`ファイルのダウンロード方法が表示されます。

![edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237739/373f68e2-cb87-c3a1-56c5-77f0d63c85e4.png)

### 2. `deb`ファイルを用いてCUDAのインストール

   実際に表示されたコマンドを以下に示しますが、あくまで一例なので必ず自分で操作した時のコンテンツボックスに表示されたコマンドを入力して下さい。

   ```bash:コンテンツボックスの中身
   #  リポジトリに優先度の登録
   wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-ubuntu1604.pin
   sudo mv cuda-ubuntu1604.pin /etc/apt/preferences.d/cuda-repository-pin-600
   
   # debファイルのダウンロード
   wget https://developer.download.nvidia.com/compute/cuda/11.2.0/local_installers/cuda-repo-ubuntu1604-11-2-local_11.2.0-460.27.04-1_amd64.deb

   # debファイルを用いてシステムにパッケージのインストール
   sudo dpkg -i cuda-repo-ubuntu1604-11-2-local_11.2.0-460.27.04-1_amd64.deb
   sudo apt-key add /var/cuda-repo-ubuntu1604-11-2-local/7fa2af80.pub
   
   # パッケージ一覧を更新
   sudo apt-get update
   ```

### 3. 自分の環境に合ったメタパッケージのインストール
　`dpkg -i`にてパッケージのインストールできましたが、まだシステムには反映されていません。最後に`sudo apt install`コマンドを用いてパッケージをシステムに適用させるのですが、ここで注意が必要です。コンテンツボックスでは`sudo apt install cuda`となっていますが、自分の用途に合わせて反映させるメタパッケージは変える必要があります。

　メタパッケージの一覧を公式サイト([3.10.3. Meta Packages](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#package-manager-metas))より抜粋、さらに和訳して以下に示します。
　
　主に指定するメタパッケージは以下の２つです。

- `cuda-11-2`
    - CUDA自体を新規でインストールする時。
- `cuda-toolkit-11-2`
    - 既に`nvidia-driver`がインストール済みの時
    - 既に他のCUDAが存在していて、別バージョンのCUDAをインストールしたい時。
        - 下手にドライバーを上書きすると、マシンが動作しなくなります。

ちなみに`CUDA10.1`の場合は`cuda-10-1`というメタパッケージ名になります。臨機応変に変換して下さい。

| Meta Package            | Purpose                                                      |
| ----------------------- | :----------------------------------------------------------- |
| cuda                    | すべてのCUDAツールキットとドライバーパッケージをインストールします。新しいcudaパッケージのリリース時に、自動で次のバージョンへのアップグレードを処理します。 |
| cuda-11-2               | すべてのCUDAツールキットとドライバーパッケージをインストールします。追加バージョンのCUDAがインストールされるまで、バージョン`11.2`のままで固定されます。 |
| cuda-toolkit-11-2       | CUDAアプリケーションの開発に必要なすべてのCUDAツールキットパッケージをインストールします。ドライバーは含まれていません。 |
| cuda-tools-11-2         | すべてのCUDAコマンドラインとビジュアルツールをインストールします。 |
| cuda-runtime-11-2       | CUDAアプリケーションの実行に必要なすべてのCUDAツールキットパッケージとドライバーパッケージをインストールします。 |
| cuda-compiler-11-2      | すべてのCUDAコンパイラパッケージをインストールします。       |
| cuda-libraries-11-2     | すべてのランタイムCUDAライブラリパッケージをインストールします。 |
| cuda-libraries-dev-11-2 | すべての開発CUDAライブラリパッケージをインストールします。   |
| cuda-drivers            | すべてのドライバーパッケージをインストールします。リリース時に、次のバージョンのドライバーパッケージへのアップグレードを処理します。 |


```bash
sudo apt install cuda-11-2
```
または、

```bash
sudo apt install cuda-toolkit-11-2
```
でCUDAパッケージをシステムに適用します。


## 複数のCUDAを管理したい。

**CUDA**と**nvidia-driver**には互換性があります。詳しく知りたい場合は下記の公式サイトを参照して下さい。

[Nvidia: Binary Compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility)

| **CUDA Toolkit**      | **Linux x86_64 Driver Version** |
| --------------------- | ------------------------------- |
| CUDA 11.1 (11.1.0)    | >= 450.80.02                    |
| CUDA 11.0 (11.0.3)    | >= 450.36.06                    |
| CUDA 10.2 (10.2.89)   | >= 440.33                       |
| CUDA 10.1 (10.1.105)  | >= 418.39                       |
| CUDA 10.0 (10.0.130)  | >= 410.48                       |
| CUDA 9.2 (9.2.88)     | >= 396.26                       |
| CUDA 9.1 (9.1.85)     | >= 390.46                       |
| CUDA 9.0 (9.0.76)     | >= 384.81                       |
| CUDA 8.0 (8.0.61 GA2) | >= 375.26                       |
| CUDA 8.0 (8.0.44)     | >= 367.48                       |
| CUDA 7.5 (7.5.16)     | >= 352.31                       |
| CUDA 7.0 (7.0.28)     | >= 346.46                       |

- `nvidia-driver==410.48`がインストールされている場合
  - `CUDA 10.0`, `9.2`, `9.1`...等がインストールできますが、`CUDA11.0`はインストールできません。事前に自分が今からインストールするCUDAとdriverの互換性があるかは確認して下さい。

ちなみに、これらのことを考えるのは以下のような状況にある時です。

- `nvidia-driver`のバージョンを変えられないor変えたく無い時
  - Google colabで作業している時
  - 既に環境構築済みのマシンに追加でCUDAをインストールする時

下手に`nvidia-driver`を操作すると環境を破壊してOSの再インストールをする羽目になります。面倒です。





## CUDAのインストール場所と切り替え方

CUDAの実態は`/usr/local`にあります。`/usr/local/cuda11-2`や`/usr/local/cuda10-2`です。しかし、python等のプログラムはそれらを直接参照しません。`cuda`という、シンボリックリンクを参照します。

```bash:Console
hoge@hoge:/usr/local$ ls -la
drwxr-xr-x 12 root root 4096 10月 15 10:10 .
drwxr-xr-x 13 root root 4096 10月 15 10:10 ..
～～～
lrwxrwxrwx  1 root root    9 10月 15 10:10 cuda -> cuda-11.2
drwxr-xr-x 16 root root 4096 12月 31 23:59 cuda-11-2
drwxr-xr-x 16 root root 4096 10月 15 10:10 cuda-10-2
～～～
```

上の状態では、`cuda`ディレクトリを参照することは`cuda-11-2`を参照するのと等価であることがわかります。もし`cuda10-2`に変更したい場合は`ln -nfs cuda-10-2 cuda`コマンドで`cuda`へのリンクを貼り直して下さい。こうすることで複数のバージョンのCUDAを管理運用することができます。





### cudnnのインストール場所

余談ですが、`cudnn`というライブラリは`/usr/include/cudnn.h`にあります。これらのバージョンを確認する場合、以下のように入力するとバージョンの確認ができます。

```bash
cat /usr/include/cudnn.h | grep CUDNN_MAJOR -A 2
```

cudnnはCUDAのバージョンに依存しています。なので、CUDAのバージョンを変えた場合、cudnnをアンインストールした後に適切なバージョンをインストールする必要があります。