AWS Amazon Linux 2 にCUDA 10環境を作る

# はじめに

AWS EC2 GPUインスタンスでCUDAを動かす記事を書こうとしたのですが、せっかくだからAmazon Linux 2にCUDA 10の環境を作ろう！と思ったのが完全に裏目に出てしまい環境構築がずいぶん長くなってしまったので記事を分けました。

# ゴール

* Amazon Linux 2上でCUDA 10が動く

# AWS GPUインスタンス

今回はP2インスタンスを使います。

# Amazon Linux 2とは

以下の特徴を持つAmazonが提供するLinux OSです。

* RedHat系
* 2023年6月30日まで長期サポートされる
* AWS の長期サポート(LTS)の対象である主要なパッケージのセットを提供する(systemd、GCC 7.3、Glibc 2.26、Binutils 2.29.1など)

# CUDAのインストール

### 必要モジュールの準備

まずはGCC。

```bash:gccのインストール
$ sudo yum install gcc gcc-c++
```

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

次にNVIDIAのドライバをインストールします。
P2インスタンスにはTesla K80を採用しているようなので、[こちら](https://www.nvidia.com/Download/index.aspx?lang=en-us)で最新ドライバのバージョンを確認します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/315364/29582a4a-cc1a-d000-2975-80bc3d0151da.png)

最新バージョンは `410.72`であることが分かったのでインストールします。
インストールには `kernel-devel`が必要なのでそれもついでにインストール。

```bash:NVIDIAドライバのインストール
$ sudo yum install kernel-devel
$ wget http://us.download.nvidia.com/tesla/410.72/NVIDIA-Linux-x86_64-410.72.run
$ sudo sh NVIDIA-Linux-x86_64-410.72.run
```

### CUDAのインストール

CUDAは[NVIDIAのサイト](https://developer.nvidia.com/cuda-downloads)からダウンロードします

```bash:CUDAのインストール
$ sudo rpm -i cuda-repo-rhel7-10.0.130-1.x86_64.rpm
$ sudo yum install cuda
```

さあCUDAのインストール完了！と思ったらインストール時にエラーが出ます。。

足りないモジュールがあるようなのでインストールすれば良いのですが、AmazonLinux2用のリポジトリ `amzn2-core`にモジュールがない！…のでEPELリポジトリを追加してそちらから取ってきます。

### EPELの追加と必要なモジュールのインストール

```bash:モジュールのインストールのためにepelリポジトリを追加
$ sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
```

```bash:CUDAに必要なモジュールのインストール
$ sudo yum install opencl-filesystem ocl-icd libva-vdpau-driver
```

### CUDAのインストール(2回目)

再度CUDAインストールチャレンジ！
しかしエラーが…

```bash:
Transaction check error:
  file /usr/lib64/libGLX.so.0 from install of nvidia-driver-libs-3:410.72-1.el7.x86_64 conflicts with file from package mesa-libGL-17.2.3-8.20171019.amzn2.0.4.x86_64
```

Amazon Linux 2で入っているlibGLXとコンフリクトを起こしている…

### 色々やったけどダメでした…

結局conflictsエラー解消しませんでした…
仕方がないのでローカルファイルでCUDA Toolkitをインストールします。

CUDAのインストーラは以下のタスクを順次やってくれるのですが、

1. NVIDIAドライバのインストール **← ここでエラー**
2. CUDA Toolkitのインストール
3. CUDA Samplesのインストール

今回エラーが出ているのはドライバのインストール部分のところです。
ドライバは手動でインストールが完了しているため、スキップしても大丈夫です。

### ローカルファイルでToolkitをインストール

```bash:CUDA&nbsp;Toolkitとsamplesのインストール
$ wget https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux
$ sudo sh cuda_10.0.130_410.48_linux --toolkit --silent
$ sudo sh cuda_10.0.130_410.48_linux --samples --silent
```

### サンプルの動作確認

CUDA Toolkitには各種サンプルが入っており、 `deviceQuery`というサンプルは動作確認でよく使われるため、こちらでCUDAの動作確認を行います。

```bash:サンプルの動作確認
$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery
$ sudo make
$ ./deviceQuery
./deviceQuery Starting...

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

Detected 1 CUDA Capable device(s)

Device 0: "Tesla K80"
  CUDA Driver Version / Runtime Version          10.0 / 10.0
  CUDA Capability Major/Minor version number:    3.7
  Total amount of global memory:                 11441 MBytes (11996954624 bytes)
  (13) Multiprocessors, (192) CUDA Cores/MP:     2496 CUDA Cores
  GPU Max Clock rate:                            824 MHz (0.82 GHz)
  Memory Clock rate:                             2505 Mhz
  Memory Bus Width:                              384-bit
  L2 Cache Size:                                 1572864 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
  Maximum Layered 1D Texture Size, (num) layers  1D=(16384), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(16384, 16384), 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:                     No
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Enabled
  Device supports Unified Addressing (UVA):      Yes
  Device supports Compute Preemption:            No
  Supports Cooperative Kernel Launch:            No
  Supports MultiDevice Co-op Kernel Launch:      No
  Device PCI Domain ID / Bus ID / location ID:   0 / 0 / 30
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

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

GPUのデバイス情報、CUDAの情報が色々と出力されますが、最後の `Result = PASS`が出ればOKです。

# まとめ

今回色々よくばったため色々苦労しました…
結局こういうことです。

* CUDAインストールがドライバのところで詰まってもスキップする術があります

# 参考URL
[Amazon Linux 2](https://aws.amazon.com/jp/amazon-linux-2/)
[Amazon Linux 2 に関するよくある質問](https://aws.amazon.com/jp/amazon-linux-2/faqs/)
[NVIDIA CUDA Installation Guide for Linux](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html)
[Linux インスタンスに NVIDIA ドライバをインストールする](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-nvidia-driver.html)