Juliaの並列周りは色々あってよくわからない。Juliaには普通にMPI通信をするMPIバインドもあるのだけどこれは別物。MPIを使ってaddProcs
の際の起動を行うだけか。
通信モード
3つの通信モードがある。
- マスタプロセスはMPIの外で動作する。ワーカプロセスのみMPIで実行。ワーカプロセス、マスタプロセスはTCP/IPで通信。つまりMPIの通信機構は使わない。
- マスタを含めてすべてのプロセスがMPI内で動作。TCP/IPで通信
- マスタを含めてすべてのプロセスがMPI内で動作。TCP/IPではなく、MPIを通信機構として使う。
スパコン系は、MPIでしか高速な通信ができないものもあるので、3が興味深い。
モード1
モード1とモード 2,3では書き方がかなり違う。モード1の場合はわりに普通のクラスタマネージャと同様の書き方。ごく普通にJuliaを起動し、そこでMPIClusterManager
をつかってワーカを起動する。SSHの代わりにMPIでプロセスをまとめて起動しているだけに見える。
using MPIClusterManagers, Distributed
manager = MPIManager(np=4)
addprocs(manager)
こうするとworkerが4つできてくるので、あとは普通に使える。
モード2/3
こちらは、MPI.jlの場合と同様にmpirun
を用いて複数のJuliaプロセスを同時に起動する形。プログラムの書き方も随分違う。MPIを起動しておいてから、ClusterManagerのイベントループを実行すると、rank0だけが帰ってきて、他のプロセスがワーカとして見えるようになる。
モード2と3はイベントループを起動する際のオプションで切り替える。
using MPIClusterManagers, Distributed
import MPI
MPI.Init()
rank = MPI.Comm_rank(MPI.COMM_WORLD)
size = MPI.Comm_size(MPI.COMM_WORLD)
manager = MPIClusterManagers.start_main_loop(TCP_TRANSPORT_ALL)
# manager = MPIClusterManagers.start_main_loop(MPI_TRANSPORT_ALL)
....
MPIClusterManagers.stop_main_loop(manager)
最後にイベントループを停止する必要がある。
分散コードとしては普通のDistributedと同様に書ける。例えば、上の・・・・
のところに、下のように書く。
@everywhere import Distributed
println("rank=$rank, size=$size, workers=", workers())
@everywhere function host_and_id()
strip(read(`hostname`, String)) * " : " * string(Distributed.myid())
end
futures =
[ @spawnat i host_and_id() for i in workers() ]
for f in futures
println(fetch(f))
end
で
mpirun -np 3 julia mode2test.jl
のようにして3プロセスで実行すると、
rank=0, size=3, workers=[2, 3]
host1 : 2
host2 : 3
のような出力が得られる。Juliaは1オリジンでプロセス番号も1からはじまるので、プロセス1がランク0に相当する。地味にうざい。残りのランク1,2がそれぞれプロセス2,3としてワーカになっている事がわかる。
設定の注意点
最初うまく動かなかった
手元のmacOS 上の1.4.2 ではモード2,3の動作がおかしい。どうもMPIとしてでなく全く独立のプロセスとして起動されてしまっているようだ。MPIがちゃんと動いて無いのかな? MPI.jl の設定がちゃんとできていなかった。下のようにしてビルドし直したらどうやら動いた。まだちょっと挙動がおかしいが。
import Pkg
Pkg.add("MPI")
ENV["JULIA_MPI_BINARY"]="system"
Pkg.build("MPI")
エラー
手元の環境では終了時にエラーが出る。手元の環境の問題か、バグか。
PMIX ERROR: ERROR in file gds_ds12_lock_pthread.c at line 206
所感
実装しようと思っていた機能がすでにあって、嬉しいやら悲しいやら。
とりあえず、スパコンでちゃんと性能がでるのか測ってみよう。