2024年7月8日月曜日

CentOS9にOpenMPI(Python: mpi4py) + OpenMP(C言語: gcc)を動かす

 CentOS9上にOpenMPI(Python: mpi4py) + OpenMP(C言語: gcc)を動かしていきます。MPIでプロセスを生成して、その各プロセスでMP(C言語)を呼び出し、その中でスレッドを動かします。

1. 必要なモジュールのインストール(root権限で実施)

CentOS9にはPythonはインストール済み -> Python 3.9.19

    (1) pipをインストール

$ sudo yum install python3-pip 

    (2) Python開発モジュールをインストール(これがないとmpi4pyがうまくインストールできなかった)

$ sudo yum install python3-devel 

    (3) gccをインストール

$ sudo yum install gcc

    (4)OpenMPIをインストール+パスの追加

$ sudo yum install openmpi

$ echo 'export PATH=/usr/lib64/openmpi/bin:$PATH' >> ~/.bashrc

$ echo 'export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH' >> ~/.bashrc

$ source ~/.bashrc

2. MPのテスト(ユーザ権限で実施)
OpenMPのテストをします。「omp_program.c」を作成します。
#include <stdio.h>
#include <omp.h>
void openmp_function() {
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
int num_threads = omp_get_num_threads();
printf("Hello from thread %d out of %d threads\n", thread_id, num_threads);
}
}
int main() {
openmp_function();
return 0;
}
view raw gistfile1.txt hosted with ❤ by GitHub
    (1) コンパイル
$ gcc -fopenmp -o omp_program omp_program.c
    (2) 実行
$ ./omp_program
3. mpi4pyをインストール(ユーザ権限で実施)
    (1) mpi4pyをインストール
$ pip3 install mpi4py
    (2) 「run_mpi.py」を作成
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
print(f"Hello from rank {rank}")
view raw gistfile1.txt hosted with ❤ by GitHub
    (3) インターフェースの設定
さくらサーバの場合警告が出たので、以下を設定してから実行
export PSM3_ALLOW_LOC_ALIASES=1
export PSM3_ENABLE_SYMMAP=0
export PSM3_NIC=ens3
export OMPI_MCA_mtl_ofi_provider_exclude="psm3"
    (4) MPIの実行
mpirun -np 4 python3 run_mpi.py
4. MPをmpi4pyから呼び出して、プロセス2、スレッド4で動かす
MPIプログラム(Python)からrankを引数として、MP(C言語)を呼び出し、プロセス数2、スレッド数4、計 2 * 4 = 8並列で動かします。
    (1) [omp_program_with_rank.c]の作成
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
void openmp_function(int rank) {
#pragma omp parallel
{
int thread_id = omp_get_thread_num();
int num_threads = omp_get_num_threads();
printf("Rank %d, Hello from thread %d out of %d threads\n", rank, thread_id, num_threads);
}
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <rank>\n", argv[0]);
return 1;
}
int rank = atoi(argv[1]);
openmp_function(rank);
return 0;
}
view raw gistfile1.txt hosted with ❤ by GitHub
MPの動作確認

gcc -fopenmp -o omp_program_with_rank omp_program_with_rank.c

./omp_program_with_rank 0

Rank 0, Hello from thread 0 out of 6 threads

Rank 0, Hello from thread 3 out of 6 threads

Rank 0, Hello from thread 1 out of 6 threads

Rank 0, Hello from thread 4 out of 6 threads

Rank 0, Hello from thread 2 out of 6 threads

Rank 0, Hello from thread 5 out of 6 threads

    (2) [run_mpi_with_rank.py]の作成

from mpi4py import MPI
import subprocess
def run_c_program(rank):
# 環境変数を設定してスレッド数を指定
env = {"OMP_NUM_THREADS": "4"}
command = ["./omp_program_with_rank", str(rank)]
result = subprocess.run(command, env=env)
return result.returncode
if __name__ == "__main__":
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
if rank < 2: # 2プロセスのみ実行
print(f"Running on rank {rank} out of {size} processors")
run_c_program(rank)
view raw gistfile1.txt hosted with ❤ by GitHub
実行
mpirun -np 2 python3 run_mpi_with_rank.py   
Running on rank 0 out of 2 processors
Running on rank 1 out of 2 processors
Rank 0, Hello from thread 0 out of 4 threads
Rank 0, Hello from thread 3 out of 4 threads
Rank 0, Hello from thread 2 out of 4 threads
Rank 0, Hello from thread 1 out of 4 threads
Rank 1, Hello from thread 0 out of 4 threads
Rank 1, Hello from thread 3 out of 4 threads
Rank 1, Hello from thread 2 out of 4 threads
Rank 1, Hello from thread 1 out of 4 threads

OpenMP(C言語: gcc)でスレッドを動かし、mpi4pyからMPIでプロセスを生成し、rankを引数として、2プロセス、4スレッドで動かすことができました。
5. SQUIDで動かす
OpenMPI + OpenMPは実際大規模並列環境で動かします。今回は大阪大学サイバーメディアセンターSQUIDで動かしてみます。
(1) omp_program_with_rank.c の作成とコンパイル・実行
gcc -fopenmp -o omp_program_with_rank omp_program_with_rank.c
./omp_program_with_rank 0
(2) run_mpi_with_rank.py の作成と実行
run_mpi_with_rank.pyの作成後、ジョブスクリプトを作成します。
[run_mpi_with_rank.sh]
#!/bin/bash
#------- qsub option -----------
#PBS -q SQUID
#PBS --group=GXXXXX
#PBS -m eab
#PBS -M mizuno@mail.address.jp
#PBS -l cpunum_job=76
#PBS -l elapstim_req=00:01:00
#PBS -l memsz_job=248GB
#PBS -b 1
#------- Program execution -----------
module load BasePy/2021
module load BaseCPU
source /sqfs/work/GXXXXX/vXXXXXX/test-env/bin/activate
cd $PBS_O_WORKDIR
mpiexec -np 8 python3 run_mpi_with_rank.py > run_mpi_with_rank.txt
view raw gistfile1.txt hosted with ❤ by GitHub
qsub run_mpi_with_rank.sh
作成されたrun_mpi_with_rank.txtを確認すると動いています。これでSQUIDでも実行できました。

0 件のコメント:

コメントを投稿