読者です 読者をやめる 読者になる 読者になる

HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

MPIライブラリ毎のプロセスマッピング指定方法

さっき、ひさびさにIntelMPIを使ってて、プロセスマッピングの指定ってどうやるんだっけと小一時間悩んでしまったので、自分用メモとして残しときます。

IntelMPIの場合、プロセスマッピングを指定するには以下の環境変数を使います。

  • I_MPI_PIN
  • I_MPI_PIN_MODE
  • I_MPI_PIN_RESPECT_CPUSET
  • I_MPI_PIN_RESPECT_HCA
  • I_MPI_PIN_CELL
  • I_MPI_PIN_DOMAIN
  • I_MPI_PIN_ORDER
  • I_MPI_PIN_PROCESSOR_LIST

といってもI_MPI_PINからI_MPI_PIN_RESPECT_HCAまでは通常はデフォルト値のままで良いので、指定するのは後半の4つのみです。

I_MPI_PIN_CELLに指定可能な値は"unit"か"core"のどちらかで、前者は論理コア後者は物理コア単位での割り当てを行うことを指定します。
HyperThreadingが有効な時に、なるべく1rankが使うコアを狭めたいけど同じ物理コアで2rank動かれるのは困る、なんて時にはcoreを指定すれば良さそうです。*1


I_MPI_PIN_DOMAINは1rankが使うコア数を指定するものです。
1ノード16コアの環境で、ノードあたり8プロセス実行とかだったら16/8で2と指定すれば良いのですが、autoに指定しておくとこれと同様な計算を自動的にやってくれます。また、OMP_NUM_THREADSの値と合わせるompというキーワードも使えます。
他にもsocket/core/nodeといった指定もできますし(それぞれ1ソケット/1コア/1ノードあたり1rankを割り当てる)cacheという値を指定すれば、cacheを共有している範囲をdomainとしてその範囲内には1プロセスしか割り当てません。
ただし -n オプションで指定されたプロセス数が、使うノードの範囲内に納まらなかった場合は1domain内に複数のrankが割り当てられることもあります。(その場合はrank0から順に各domainに1rankづつ割り当てて、余ったらまたdomain0から順に割り当ててといった感じになるはず)
それから、auto/ompもしくは明示的なdomainのサイズを指定した場合は続けて :layout という形でdomainのレイアウト方法を指定できます。
これは、compact/scatter/platformの3つの値が指定できて、compactだと同一domainがなるべく近いコアに、scatterだとなるべく遠いコアに割り当てられます。platformにすると単純にBIOSレベルでのcore id順(たぶん/proc/cpuinfoで見える順番)で割り当てられます。

まぁ、色々書いたけど ハイブリッドプログラムなら omp:compactでflat MPIのプログラムなら core にしておけばたいてい大丈夫でしょう。
ハイブリッドプログラムで非privateな領域にやたらとアクセスしてスラッシングが酷いとかなら、omp:scatterも有効かもしれませんが、そもそもそんなプログラムは書き換えるべk


I_MPI_PIN_ORDERはI_MPI_PIN_DOMAINで指定した各ドメインを実際に割り当てる時の順番を指定します。
指定できる値は、compact/scatter/spread/bunchの4つです。
reference manualに非常に分かりやすい解説があったので、詳細は省きますが、たぶんcompactしか使わない。


I_MPI_PIN_PROCESSOR_LISTは、DomainとOrderの組み合わせでは指定できないような面倒なパターンを指定する時に使えます。
例えばrank0から3は同一ソケット上の連続した3つの物理コアを使ってrank4は同じノードの別ソケットを使うとか。
これで細かく指定するのは、コアを余らせて実行するような時なので、普段はあんあり出番は無いです。(ベンチマークとる時はそこそこ使う)

最後に、この辺のプロセスマッピングの状況を出力させるには

export I_MPI_DEBUG=4

を指定しておけばOKです。(正確に4じゃなくても4以上の値ならOK)

*1:でも、そもそもHPC用途だと大抵HT切ってるから使ったこと無いw