EC2にもGPUが搭載されているインスタンスがあるけど、科学技術計算用途に使えるのか試してみました。
結論から書くと、Marketplaceに用意されているNVIDIAのAMIは古くてなんとなく嫌なので、全部セットアップしてサンプル流してって軽く考えていたら大変だった。。。
結果的にはGPU1ノードで単精度1TFLOPSは出せたのでなかなか良いのではないのでしょうか?
まずEC2に用意されているGPUインスタンスは2種類しかありません。今回はg2.2xlargeを利用します。
Marketplaceからお手軽に試したい人は以下のリンクからどうぞ。
https://aws.amazon.com/marketplace/search/results/?page=1&searchTerms=GPU
いい感じのAMIが無い
美しいCUDA環境を作りたいが為にCentOS6.5を使いたいわけですが、先月まではあったはずのHVMインスタンスが無くなくなっている上に、「普通のCentOSから自分でHVM作るのはしんどいからやめた方がいいですよ」という神の声もあったので、やむを得ず公式のRHEL6.5 HVMを選択します。必ずHVMを選択してください。でないとGPUが使えません。
TokyoリージョンではGPUインスタンスが使えないので、N. Virginiaリージョンで立てます。
ハマったポイント
なんだか分からないけどこのAMIはrootのボリュームが拡張できないので、とりあえず100GBのEBSをアタッチしました(20GBもあれば十分)。でないと、CUDAインストールで空き容量が足りません的なメッセージと共に悲しみにふけることになります。これは後からでも追加可能。
SSHでログインしてセットアップ開始
起動後はとりあえずおまじないを少々
[ec2-user@~]$ sudo su - [root@~]$ yum groupinstall "Development Tools" [root@~]$ yum update
ちなみに以下コマンドでGPUが本当にあるのか確認できます。
[root@~]$ lspci | grep -i nVidia 00:03.0 VGA compatible controller: NVIDIA Corporation GK104GL [GRID K520] (rev a10)
rpmforgeのリポジトリを追加する
[root@~]$ yum install http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
ドライバがインストールできるようにgrubを編集
OSが始めから持っているドライバでGPUが動作している状態なので、OS起動時にNVIDIAドライバを使わないようにgrubを編集します。
カーネルの起動オプションに rdblacklist=nouveau を追加して再起動するだけ
[root@~]$ vim /etc/grub.conf
kernel /boot/ほにゃららの行の最後に追加すればよいです。保存したら必ずrebootしましょう。
最新のNVIDIAドライバをインストールする
NVIDIAのWebからドライバをダウンロードしますが、方法は何でも良いです。今回はwgetで落としました。落としたら権限を与えて実行します。
[root@~]$ wget http://jp.download.nvidia.com/XFree86/Linux-x86_64/331.49/NVIDIA-Linux-x86_64-331.49.run [root@~]$ chmod +x NVIDIA-Linux-x86_64-331.49.run [root@~]$ ./NVIDIA-Linux-x86_64-331.49.run
規約読んでねページはxキー連打でスイスイ進みます。ドライバインストール時にいろいろ聞かれますが、基本的にはデフォルトインストールで良いです。途中で32bitOpenGLあれこれ入れますか?と聞かれますが、習慣でインストールしました。
CUDAのインストール先EBSを用意する
rootボリュームはパンパンになる上にインストールは失敗するし、拡張にチャレンジするものの何故かうまくいかず挫折したので、別にEBSを用意しておいてそこにCUDAをインストールします。
EBSアタッチの詳細は検索すると沢山でてくるのでそれらを参考してほしいですが、ポイントはマウントポイントのパスを以下のようにしましょう。SELinuxも無効にします。
/usr/local/cuda-5.5
[root@~]$ fdisk /dev/xvdb [root@~]$ mkfs.ext4 /dev/xvdb1 [root@~]$ mkdir /usr/local/cuda-5.5 [root@~]$ mount /dev/xvdb1 /usr/local/cuda-5.5 [root@~]$ df -h [root@~]$ umount /usr/local/cuda-5.5/ [root@~]$ blkid /dev/xvdb1 [root@~]$ vim /etc/fstab [root@~]$ mount -av -t ext4 [root@~]$ getenforce [root@~]$ vim /etc/selinux/config [root@~]$ setenforce 0 [root@~]$ mount -av -t ext4
CUDA5.5をRPMインストール
最近はRPMで配布されていてなんだか便利
[root@~]$ yum install http://developer.download.nvidia.com/compute/cuda/repos/rhel6/x86_64/cuda-repo-rhel6-5.5-0.x86_64.rpm [root@~]$ yum clean expire-cache [root@~]$ yum install cuda
パスを通す
CUDAのユーティリティなどなどが使えるようにパスを通します。方法は何でも良い
[root@~]$ cd [root@~]$ vim .bashrc export PATH=/usr/local/cuda-5.5/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-5.5/lib64:/lib:$LD_LIBRARY_PATH :wq
試しにGPUの状態を見てみる
[root@~]$ nvidia-smi -l Fri Mar 7 18:47:22 2014 +------------------------------------------------------+ | NVIDIA-SMI 5.319.37 Driver Version: 319.37 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GRID K520 Off | 0000:00:03.0 Off | N/A | | N/A 45C P8 17W / 125W | 9MB / 4095MB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Compute processes: GPU Memory | | GPU PID Process name Usage | |=============================================================================| | No running compute processes found | +-----------------------------------------------------------------------------+
サンプルプログラムでベンチマークを取る
今回は、粒子法シミュレーション記述言語による多体問題を投げます、というと聞こえはそれっぽいですが、要するにnBodyをコンパイルして実行します。
[root@~]$ cd /usr/local/cuda-5.5/samples/5_Simulations/nbody/ [root@~]$ make /usr/local/cuda-5.5/bin/nvcc -ccbin g++ -I../../common/inc -m64 -gencode arch=compute_10,code=sm_10 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=\"sm_35,compute_35\" -o nbody.o -c nbody.cpp /usr/local/cuda-5.5/bin/nvcc -ccbin g++ -I../../common/inc -m64 -gencode arch=compute_10,code=sm_10 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=\"sm_35,compute_35\" -o bodysystemcuda.o -c bodysystemcuda.cu ptxas /tmp/tmpxft_00000e5b_00000000-14_bodysystemcuda.compute_10.ptx, line 2565; warning : Double is not supported. Demoting to float /usr/local/cuda-5.5/bin/nvcc -ccbin g++ -I../../common/inc -m64 -gencode arch=compute_10,code=sm_10 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=\"sm_35,compute_35\" -o render_particles.o -c render_particles.cpp /usr/local/cuda-5.5/bin/nvcc -ccbin g++ -m64 -o nbody nbody.o bodysystemcuda.o render_particles.o -L../../common/lib/linux/x86_64 -lGL -lGLU -lX11 -lXi -lXmu -lglut -lGLEW -lcufft mkdir -p ../../bin/x86_64/linux/release cp nbody ../../bin/x86_64/linux/release
出来ました。指示通り実行ファイルのある場所に移動します
[root@~]$ cd ../../bin/x86_64/linux/release/
nbodyにbenchmarkオプションと問題数を渡せば実行できますが、今回は連続して問題を投げたときFLOPSの値が安定しているかも含めて見たかったので、簡単なシェルスクリプトを書いて実行し、その裏でnvidia-smi -lも見つつGPUの頑張り具合を観察してみます
nbody.shとして以下のようにしました
#!/bin/bash NDEV=`nvidia-smi -q | grep -c "Product Name"` sleep 3 mkdir -p log echo "nbody start" while : do ./nbody -benchmark -numbodies=${NDEV}00000 -numdevices=${NDEV} >> log/nbody.log done
[root@~]$ sh nbody.sh
もう1つ端末を開いて、状況を見てみます
[root@~]$ nvidia-smi -l +-----------------------------------------------------------------------------+ | Compute processes: GPU Memory | | GPU PID Process name Usage | |=============================================================================| | No running compute processes found | +-----------------------------------------------------------------------------+ Fri Mar 7 19:04:49 2014 +------------------------------------------------------+ | NVIDIA-SMI 5.319.37 Driver Version: 319.37 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GRID K520 Off | 0000:00:03.0 Off | N/A | | N/A 67C P0 102W / 125W | 65MB / 4095MB | 99% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Compute processes: GPU Memory | | GPU PID Process name Usage | |=============================================================================| | 0 3892 ./nbody 54MB | +-----------------------------------------------------------------------------+
GPU温度も上がり、タスクが投げられ、消費電力も上がってるのが分かります。
計算結果はlogに出力されているので確認してみます。
[root@~]$ cat log/nbody.log number of CUDA devices = 1 > Windowed mode > Simulation data stored in video memory > Single precision floating point simulation > 1 Devices used for simulation GPU Device 0: "GRID K520" with compute capability 3.0 > Compute 3.0 CUDA device: [GRID K520] number of bodies = 100000 100000 bodies, total time for 10 iterations: 1963.470 ms = 50.930 billion interactions per second = 1018.605 single-precision GFLOP/s at 20 flops per interaction
単精度ですが1TFLOPS程度は安定して出ていることが分かりました 。
今回はEC2の初期設定(時刻設定など)を省いて、とりあえずGPUを使ってみようと言うことと、綺麗なOSかつ最新のドライバで計算させたいということをやってみました。並列計算も試せてないし、まだまだ美しいHPC-AMIを作るという意味では詰められる余地が大いにありました。
元記事は、こちら