サブロウ丸

サブロウ丸

主にプログラミングと数学

クラスタコンピュータで MPI + Pythonを実行する

本稿ではクラスタコンピュータでMPIを用いてPythonを並列実行するまでの手順を紹介します。

1ノードでの実行の場合

クラスタと言いながらまずは1ノードでmpi + pythonを実行する場合です。

mpirun -np 4 python -c "import os; print(f'process = {os.getpid()}')"
process = 29593
process = 29594
process = 29596
process = 29595

もちろんスクリプトを実行する形式でも実行を行えます。

mpirun -np 4 python sample.py 

sample.py

import os
print(f'process = {os.getpid()}')

クラスタでの実行の場合

次のような準備を行う必要があります。

sshログインの整備

コマンドを実行するノードから、計算に使用するノード全てにパスワードなしでsshログインをできるようにします。 例えば方法としては下記。

  1. コマンドを実行するノードで公開鍵暗号の鍵を作成(ssh-keygen)
  2. 公開鍵(XXX.pub)を他のノードの.ssh/authorized_keysに記載
  3. .sshフォルダやauthorized_keysの権限を必要があれば変更(ls -laで確認)
    • .ssh: drwx------ (chmod 700 .ssh で変更)
    • .ssh/authorized_keys: -rw------- (chmod 600 authorized_keys で変更)

python環境の整備

全てのノードでpython環境を整える(pyenvなどを使用するとよい)。またその他必要なパッケージのinstallを行う。tmuxの下記ブログのスクリプトを使えば同時に複数のノードで同じコマンドを実行できて最高。

実行コマンド

実行も1ノードの場合と多少異なります。

  • mpirunはフルパスである必要がある(なぜかは分かりませんが)
  • pythonもフルパスで指定
  • フルパスは(which コマンド; e.g. which python)で確認できます
  • 下記に実行コマンド例を記載
    • /usr/local/openmpi/bin/mpirun -hostfile hostfile -np 4 /home/hogehoge/.pyenv/shims/python -c "from mpi4py import MPI; print(f'hello from rank {MPI.COMM_WORLD.Get_rank()} on {MPI.Get_processor_name()}')"

実行結果

hello from rank 0 on hogehoge1
hello from rank 1 on hogehoge2
hello from rank 3 on hogehoge3
hello from rank 2 on hogehoge4

実行のためにmpi4pyを使用しています。

おまけ

open-mpiのオプションについて

  • hostfile: ホスト名を指定するファイル
    • 要するに実行に用いる計算機情報を指定する
    • 用いるMPIによって記法が異なるのでそれぞれのマニュアルを見て作成する(openmpiならここに記載がある)
    • XX.XX.XXX.XXX(IP address) slots=1
      XX.XX.XXX.XXX slots=1
      XX.XX.XXX.XXX slots=1
      XX.XX.XXX.XXX slots=1
      
  • mca: Modular Component Architecture
    • 使い方は -mca パラメタ名 値
    • btl: Byte Transfer Layer、プロセス間におけるバイト列の送受信
      • selfは必ずつける必要があるみたい(openmpiのマニュアルにはFailure to specify the self BTL may result in Open MPI being unable to complete send-to-self scenarios (meaning that your program will run fine until a process tries to send to itself).とある)
    • btl_tcp_if_includeでは使用するethernetを指定
    • 参考( Open MPIのMCAフレームワーク一覧 · Keichi Takahashi)
  • display-map: 起動前に、各プロセスのマップされた場所を示すテーブルを表示
  • display-allocation: 検出されたリソース割り当てを表示

mpi4pyのインストールに失敗するとき

pip install mpi4pyでのエラー
      gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/home/tateiwa/.pyenv/versions/3.10.7_optcast/include -I/home/tateiwa/.pyenv/versions/3.10.7/include/python3.10 -c _configtest.c -o _configtest.o
      _configtest.c:2:10: fatal error: mpi.h: No such file or directory
          2 | #include <mpi.h>
            |          ^~~~~~~
      compilation terminated.
      failure.
      removing: _configtest.c _configtest.o
      error: Cannot compile MPI programs. Check your configuration!!!
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for mpi4py
Failed to build mpi4py
ERROR: Could not build wheels for mpi4py, which is required to install pyproject.toml-based projects

環境変数を次のように追加 (.bashrcに追記)でok

# openmpi
export PATH=${PATH}:/usr/local/openmpi/bin
export CPATH=/usr/local/openmpi/include
実行時に次のようなエラーが出る場合
--------------------------------------------------------------------------
WARNING: There is at least non-excluded one OpenFabrics device found,
but there are no active ports detected (or Open MPI was unable to use
them).  This is most certainly not what you wanted.  Check your
cables, subnet manager configuration, etc.  The openib BTL will be
ignored for this job.
--------------------------------------------------------------------------

mpirun(mpiexec)のオプションで-mca btl_tcp_if_include を指定してやる。具体的なend pointはifconfigで確認