Haskell のGPU演算環境をセットアップする
概要
以下の書籍を購入ました。途中でaccelerate-cudaのインストールを求められたのですが、これは現在accelerate-llvm-ptxに置き換わっています。
このセットアップ方法が少々面倒だったので書き残しておきます。
※英語版ですが以下で上記テキストの内容が公開されています。
ソフト環境
名前 | バージョン |
---|---|
OS | Ubuntu 20.04 |
docker | 24.0.2, build cb74dfc |
docker compose | v2.18.1 |
cuda | 11.6 |
nvidia-docker | 2.13.0 |
そんなことしなくても、、、
この記事書いた1年後に気づいたのですが、cudaを10.2に戻して以下コマンドを実行すればdocker無しで使えるようになりました。なのでcudaバージョン戻せる方は戻したほうが快適です。もちろんllvmとかはインストールする必要があります。後々別の記事を書きますか、、、なお私が持っているGPUはRTX3080であり、CUDAは11.2以降を必要としますのでコンパイルに成功しても実行時にエラーとなります。
cabal install accelerate-llvm-ptx
cabal install --lib accelerate-llvm-ptx
cuda 10.2に戻す方法は以下に書きました。
RTX3080でCUDA11.8の場合は以下で出来ました。ghc:v8.6.5
cabal v2-install accelerate-llvm-ptx -f -nvvm
cabal v2-install accelerate-llvm-ptx -f -nvvm --lib
ハード環境
名前 | バージョン |
---|---|
CPU | AMD Ryzen 9 3900XT 12-Core |
GPU | RTX3080 |
RAM | 76GB |
手順
以下をgit clone
します
cloneしたフォルダ内で以下を実行します。
sudo docker compose build
sudo docker compose up -d
これにより出来たコンテナに以下でアクセスします。
sudo docker exec -it haskell_gpu-haskell-cuda-1 bash
以降はコンテナ内での操作です。
以下を実行します。
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda-11.6/nvvm/lib64"
以下を/app/mnt
にgit clone
します。
上記の/app/mnt/accelerate-llvm
フォルダ内で以下を実行してください。
ln -s stack-9.0.yaml stack.yaml
stack setup
stack install
これによりGPUが使用可能となります。
確認
/app/mnt/accelerate-llvmでstack ghci
を実行し、以下がエラーなくimportできると思います。
import Data.Array.Accelerate.LLVM.PTX
本当はコンテナのどこでもimportできるようにしたいですがやり方を見いだせていません、、、
以下の本のサンプルを実行してみます。
サンプルは以下にあります。
上記のサンプル内のGPUを使った最短経路問題を解くコードであるfwaccel-gpu.hsとAccelerateCompat.hsを/app/mnt/accelerate-llvm
に移動し、fwaccel-gpu.hsを以下を参考に編集してください。
# diff fwaccel-gpu_org.hs fwaccel-gpu.hs
9c9,10
< import Data.Array.Accelerate.CUDA
---
> -- import Data.Array.Accelerate.CUDA
> import Data.Array.Accelerate.LLVM.PTX
77c78
< test = toList (shortestPaths testGraph) == toList expectedResult
---
> test = toList (shortestPaths testGraph) Prelude.== toList expectedResult
81c82
< where k = length xs
---
> where k = Prelude.length xs
86c87
< (n:_) <- fmap (fmap read) getArgs
---
> (n:_) <- Prelude.fmap (Prelude.fmap read) getArgs
コンパイル、実行してみます。
stack exec -- ghc -O2 fwaccel-gpu.hs -threaded
./fwaccel-gpu 2000 +RTS -s
以下の様に出力されました。
root@a0dff553f17f:/app/mnt/accelerate-llvm# ./fwaccel-gpu 2000 +RTS -s
Scalar Z [-1526072448]
1,700,044,264 bytes allocated in the heap
1,084,219,424 bytes copied during GC
211,265,000 bytes maximum residency (11 sample(s))
1,227,288 bytes maximum slop
439 MiB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 1673 colls, 0 par 0.722s 0.724s 0.0004s 0.0012s
Gen 1 11 colls, 0 par 0.591s 0.592s 0.0538s 0.2041s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.001s ( 0.001s elapsed)
MUT time 0.659s ( 0.672s elapsed)
GC time 1.314s ( 1.316s elapsed)
EXIT time 0.001s ( 0.001s elapsed)
Total time 1.974s ( 1.990s elapsed)
Alloc rate 2,580,233,428 bytes per MUT second
Productivity 33.4% of total user, 33.8% of total elapsed
並行でホストマシンにてnvidia-smi
を実行してみて使用率からGPU演算がなされていることが確認できました。
Discussion