Ubuntu 10.10 64bitでCUDA4.0とPyCUDAをセットアップする方法

###必要なもの
・Ubuntu 10.10 64bit
・うまくいかなくても泣かない心と根性
・美女に惚れたダサ男のように、CUDAに拒絶されても拒絶されてもついていく精神



###参考サイト
・half an EGG:[Ubuntu][CUDA]Ubuntu及びCUDAの開発環境の構築メモ
・irieめも:Ubuntu 10.10にCUDAをインストールした時のメモ
PyCUDA@tiker.net



###CUDAのインストール
CUDAの環境構築自体は割りとみんなうまくいくと思うけど、一応メモメモ

1.NVIDIAの最新グラッフィックドライバのインストール

sudo su
add-apt-repository ppa:ubuntu-x-swat/x-updates
apt-get update
apt-get install nvidia-current nvidia-current-modaliases nvidia-settings
でOK、再起動後に
sudo nvidia-xconfig
を実行して、ログアウト→ログイン

2.CUDAのインストールに必要な環境のインストール
sudo apt-get install g++ freeglut3-dev libxi-dev libxmu-dev
sudo apt-get install openmpi-bin openmpi-dev
でOK

3.CUDA関連ツールのダウンロード(取得時点のバージョンは4.0.17)http://developer.nvidia.com/cuda-toolkit-40
から
cudatoolkit_4.0.17_linux_64_ubuntu10.10.run
cudatools_4.0.17_linux_64.run
gpucomputingsdk_4.0.17_linux.run
visualprofiler_4.0.51_linux_64_sles11.0.tar.gz
をダウンロードしよう
とりあえずここでは
~/CUDA
フォルダにこれらのファイルを入れるものと仮定
visualprofilerのパッチファイルに関しては今回は触れないけど、コレに関してはおそらくこのドキュメントあたりを参考にすればいけるはず

4.CUDA関連ツールのインストール
4.1.CUDAツールのインストール

chmod a+x cudatoolkit_4.0.17_linux_64_ubuntu10.10.run
sudo ./cudatoolkit_4.0.17_linux_64_ubuntu10.10.run
でインストール完了。
インストール場所を聞かれるけど、基本的にはエンターキーを押すだけでOK。

#設定ファイルなどその1
/etc/ld.so.conf.d/cuda.conf

/usr/local/cuda/lib64
/usr/local/cuda/lib
を書き加えて
sudo ldconfig

その2
/etc/profile.d/cuda.sh

export PATH="/usr/local/cuda/bin:$PATH"
export LIBRARY_PATH="/usr/lib/nvidia-current"
を書き加えてログオフ→ログイン
(たぶん大丈夫だと思うけど、僕はzshを使ってるので、.zshrcに同様の内容を追加)

4.1.SDKのインストール
chmod a+x ./gpucomputingsdk_4.0.17_linux.run
./gpucomputingsdk_4.0.17_linux.run
でOK。
サンプルファイルを
cd ~/NVIDIA_GPU_Computing_SDK/C
make
でコンパイル。
cd ~/NVIDIA_GPU_Computing_SDK/C/bin/linux/release
./oceanFFT
で青い波みたいのが表示されたらとりあえず成功。

5.64bit環境向け
cd ~/NVIDIA_GPU_Computing_SDK/C/lib
for i in `ls *_x86_64.a`; do ln -sv $i ${i%_x86_64.a}.a; done



###PyCUDAのインストールこれが曲者。CUDAのインストールには成功したが、PyCUDAのインストールには何度も挫折。
最終的にどこいじったかわからなくなって再インストールを何度も繰り返したりした。

1.gcc周りの設定PyCUDAにはgcc-4.3が必要なため、updata-alternativesで変更する。
デフォルトではすっからかんの状態のためgccのインストールと設定を行う。ついでにgcc-4.5も入れてしまおう。
sudo apt-get install gcc-4.3 g++-4.3 gcc-4.5 g++-4.5
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.5 45 --slave /usr/bin/g++ g++ /usr/bin/g++-4.5 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.5
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 44 --slave /usr/bin/g++ g++ /usr/bin/g++-4.4 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.4
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 43 --slave /usr/bin/g++ g++ /usr/bin/g++-4.3 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.3
の後に
sudo update-alternatives --config gcc
でgcc-4.3の番号を選択

2.PyCUDAのセットアップに必要なものをインストール(Boostの他にnumpyも必要なので入れておこう)
sudo apt-get install build-essential python-dev python-numpy python-setuptools libboost-python-dev libboost-thread-dev

3.PyCUDAのダウンロード
sudo apt-get install git
git clone http://git.tiker.net/trees/pycuda.git
でOK

4.PyCUDAのインストール
cd pycuda
./configure.py --cuda-root=/usr/local/cuda --cudadrv-lib-dir=/usr/lib --boost-inc-dir=/usr/include --boost-lib-dir=/usr/lib --boost-python-libname=boost_python-mt-py26make -j 4
これで問題なくmakeが通れば問題なし。

さて、ここからが一番のはまりどころで、
sudo python setup.py install
とやってもnvccが見つからないYO!と言われて弾き返される。

でもecho $CUDA_ROOTってやるときちんとPATHは通ってるし…ってことで四方八方色々調べてみると、sudoだからCUDA_ROOTのパスを~/root以下に書かなきゃダメだYOってことに気づいて…

sudo su
cd ~
でrootのホームに移動して
vi .zshrc
あたりで
export PATH=/usr/local/cuda:/usr/local/cuda/bin:$PATH
export CUDA_ROOT=/usr/local/cuda:/usr/local/cuda/bin:$CUDA_ROOT
export LIBRARY_PATH=/usr/lib/nvidia-current:$LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/lib:$LD_LIBRARY_PATH
を記載した後に、
exit
cd ~/CUDA
sudo python setup.py install
でOK



これでCUDA及びPyCUDAのインストールは完了
みなさんもハッピーGPGPUライフをお過ごしください

RでdoMCを使ったお手軽並列計算

前書き
奥様1「ちょっと奥さん!最近のCPUってマルチコアになってて何でも並列計算とかできるらしいわよ?」
奥様2「え…でも並列計算の計算環境作成ってすごく面倒くさいんでしょう?」
マーク・パンサー「なんで?面倒くさくないよ?」
奥様2「え…でも大して速くならないんでしょ?」
マーク・パンサー「違うよ,全然違うよ」

ということでRでの並列計算のお話です.
以前にも
LAM/MPIのインストール for MacOSX
とかいう記事を書きましたが,正直このアプローチは面倒くさすぎるというか設定した私ももう一度やれと言われたら多分無理.
基本的に以前の記事はネットワーク経由での並列計算でしたが,今回はマシン単体での並列計算のお話.
つまり「近頃の若いマシンはマルチコアとかいう大層なものを積んでるんだから,精一杯こき使ってやろうぜい」というお話です.





なんで並列計算やる必要あるの?
さて,まずRでの並列計算についてですが,まずRの欠点として…
・基本的にオンメモリでデータを保持
・マルチCPU環境でも基本的に1コアで計算
・デフォルトで大規模データの処理が苦手(デフォルトでは2^31-1個までしか保持てきない)
など割と言い始めたらキリがないですが,今日のお話は2番目の「マルチCPU環境でも基本的に1コアで計算」です.
Rは基本的に1コアで計算してしまうので,並列計算をしてあげないと計算資源の無駄なわけです.



並列計算のパッケージっていろいろあるけど,どのパッケージを使えばいいの?
さて,Rで並列計算するには,まずどのパッケージを使えばいいの?という話が挙がります.
ちょっと調べただけでもdoNWS・doSNOW・doSMP・doMC・rMPIなど結構出てきます.
この中で最適なパッケージはどれかというと…ココの記事いわく…
http://www.revolutionanalytics.com/subscriptions/docs/RevolutionREnterprise4.0/parRman.pdfの22ページより…

The doNWS and doSNOW packages are parallel backends for clusters of workstations; they can be used on a single multi-core or multi-processor computer, but they are not optimized for such use.
The doSMP and doMC packages are parallel backends for foreach that are intended for parallel processing on a single computer with multiple cores or processors. The doSMP package is available on all platforms, while doMC, which depends on the multicore packages, is currently available only on Mac and Linux systems.
なので
doNWS・doSNOW: マルチコアシステムには最適化されていない
doSMP・doMC: マルチコアシステムに最適化されている
→というわけで、一台のマシンで使う場合はdoSMP・doMCが最適

さて,ここからは個人的な経験談なのですが,Mac版doSMPは経験上どうもうまく動かない傾向にあるので、並列計算を行うにあたってはdoMCを使うのが無難かなぁと思います.
(追記:今さら気づきましたがdoMCはLinuxかMac版しか無い模様.Windowsユーザの方はdoSMPを使うしかないようです…といってもコードの書き方は殆ど変わらなかったはず.)




doMCをインストールしよう
doMCのインストールは簡単.
セオリー通り
install.packages("doMC")
とやるだけです.依存パッケージも同時にインストールしてくれます.



doMCを使ってみよう
まずは参考までにサンプルコードを貼っておきます.とっても簡単です.
何のことはない,N個の正規乱数を発生させて,その和を取るということを1000回くりかえした計算時間を返すという単純なものです.
#計算コア数ベクトル生成(コア数: 1,2,4,6,8)
n_core <- c(1,seq(2,8,by=2))
#正規乱数発生数を設定
N <- 10^6
#計算時間の結果を突っ込む空マトリックスの作成
result.mat <- matrix(0,length(n_core),3)
for(i in 1:length(n_core)){
    registerDoMC(n_core[i])
    result <- system.time(foreach(i = 1:1000,.combine = "cbind") %dopar% {
        sum(rnorm(N))
    })
    core.d <- c(n_core[i],result[3])
    names(core.d) <- c("Cores","ProcTime")
    print(core.d)
    result.mat[i,] <- as.numeric(result)[1:3]
}
return(result.mat)
と言った感じです.ね?簡単でしょ?
普段のコードと違うところと言ったら
registerDoMC(n_core[i])

foreach(i = 1:1000,.combine = "cbind") %dopar% {hogehoge}
の所ぐらいです.

さて,それぞれの関数の意味ですが…
registerDoMC(hoge)
で使用するコア数の設定をすることができます,
例えばCore2DuoだったらregisterDoMC(2),Corei7だったら…これはCPUによって違いますね.
次に
result <- foreach(i = 1:1000,.combine = "cbind") %dopar% {hogehoge}
に並列計算の処理を書きます.
基本的にhogehogeの部分に書く処理内容はfor文と同じですが,結果がresultに保存されるので,その点だけは注意です.
つまり
result <- c()
foreach(i = 1:1000,.combine = "cbind") %dopar% {
    result[i] <- mean(rnorm(10000))
    }
とか書いてもダメで,
result <- foreach(i = 1:1000,.combine = "cbind") %dopar% {
    mean(rnorm(10000))
    }
と書いてくださいといいうことです.
返り値はいろいろな形が設定できます.詳しくはヘルプを見てね!って感じですが,cbindにしておけばベクトルで返してくれますし,デフォルトだとそれぞれの計算結果をリストで返してくれたはずです.
注意する点はこれぐらいでしょうか.
これでとっても簡単に計算ができます.




実際どれぐらい早くなるの?
ここまでの記事は正直ほかのサイトさんでも書かれてるので大して新しい情報は無いのですが,実際の効果についてはあまり触れられていないので,記入しておこうかなと思います.
以前機会があって結構大規模なマシンに触れる機会があったので,試しにテストして見ました.

・テスト内容
100,000個の標準正規乱数を1,000回発生させて,それぞれの和をとる計算にかかる時間を計測

・マシン
R for Linux 64bit (Ubuntu Linux 11.04)
CPU: Xeon 2.8GHz *2 (24 core)
RAM: 48GB



R for Mac OS X 64bit (Mac OS X 10.7.1)
CPU: Core i7 2.3GHz *1 (8 core)
RAM: 8GB
の2台で計測

結果
赤線がXeonのマシン,青線がCore i7のマシンになっています.
計算時間については1コア時の計算時間を1として正規化しています.
計算の内容にも依るのかなと思いますが,どちらも実コア数近辺までは計算速度が早くなっている気がします.
それ以降では計算効率がガクッと落ちてしまっています.
registerDoMC関数で指定するコア数は,実コア数までにしておくのが妥当かもしれません.

以上,これでみなさんもハッピー並列計算ライフをお楽しみください.