概要
- 非構造MPI並列セル中心有限体積法コード用のメモです。
- MPIなどで空間を並列処理する際の分割をMETISで半自動化します。
- METISのコマンドを手動実行します。実行環境に縛られにくい利点があります。
- Ubuntuで動かしていますがgpmetisコマンドが使えれば何でも良いです。
準備
- METISのコマンドが使えるようにインストールします。
- sudo apt update
- sudo apt install metis -y
- 端末で"gpmetis"を実行してコマンドが認識されている事を確認します
-
手元でハンドリング出来る格子データ
-
オレオレフォーマットで可
-
gpmetisに渡すcellの接続情報を用意する
ここで作成したいのは以下のようなデータです。
graph.dat
24 38 ←総node数、総edge数
7 2 ←node 1 が接続しているnode番号。2つ隣接している
8 3 1 ←node 2 が接続しているnode番号。3つ隣接している...
node番号は1から数えます。
このdatファイルは以下のような格子に対応します。
graph.datに記述されているようにnode1は2、7と隣接しています。同様にnode2は1、3、8に隣接しています。
ここで、グラフ理論で言うところのnode/edgeと、有限体積法(FVM)で言うところのnode/edgeは意味が異なる点に注意します。ここではnode/edgeはグラフ理論における用語を指すことにします。例えばFVMでnodeと言えば通常は節点のことですが、ここでのnodeはCell-centered FVMにおけるcellに相当します。
それぞれ以下のように対応します。
-
グラフ:node = Cell-centered FVM:cell
-
グラフ:edge = Cell-centered FVM:隣接するcellを結んで出来る線、cell間の面
したがってgraph.datの「総node数」で指定するべき値はCell-centered FVMの「総cell数」であり、「総edge数」は「隣接するcellを結んで出来る線の総数」もしくは「境界を除くcell間の面の総数」となります。
もし使用している格子データに「総edge数」が含まれていない場合は別途数え上げる必要があります。
gpmetisで任意の領域数に分割する
「準備」で用意していたgpmetisコマンドを使って分割します。5つの領域に分割したい場合は端末で以下のように実行します。
gpmetis graph.dat 5
以下のようなファイルが生成されるはずです。
graph.dat.part.5
1 ← cell 1は領域1
1 ← cell 2は領域1
3 ← cell 3は領域3
...
ここで領域は0から数えます。
仮に並列化手法がMPIであれば各「領域」が「ランク」ということになります。
gpmetisの出力を使って元の格子を分割する
graph.datの出力を使って元の格子データを分割します。例として4分割したgraph.dat.part.4を読み込んで初めの格子に領域(ランク)を割り振り、色分けして出力してみます。
綺麗に4等分してくれました。
もう少し複雑な例として非構造格子に適用してみます。こちらの記事で作成したものです。
ここでは5分割してみます。
どの程度均等に分割されたか確認してみます。
rank0 | rank1 | rank2 | rank3 | rank4 | |
Cell [%] | 19.52 | 20.39 | 20.07 | 19.74 | 20.29 |
面数 [%] | 19.85 | 20.77 | 20.43 | 20.09 | 20.68 |
節点数 [%] | 21.80 | 23.00 | 22.60 | 22.20 | 23.00 |
追加のオプションは指定していませんが十分な分割性能です。
※面と節点はrank境界で共有されている都合上、全rankの和は100%にはならないので大体です。
補足
大抵の場合、MPIでの並列計算に使用するためには各rank間で通信した情報を格納する余分なcellを各ランクで確保する必要があります。