kuroの覚え書き

96の個人的覚え書き

AlmaLinux8.7でopenMPI

私の用途としては大量のデータの処理、という方がメインなのでクラスタと言ってもノードをまたぐ並列処理よりもバッチシステムのほうがよく使う。しかしノードをまたぐような大規模解析も時々行うことがあって、これまではスパコンを使ってやっていた。せっかくなので新サーバではMPIも入れてみることにする。

大規模解析としてベイジアンネットワーク解析をするための環境を整える。
まずMPI環境としてopenMPI4.1.0を要求するようなので、それをインストールする。
dnfでも一応インストールできるっぽいが、ここはマニュアルでインストールすることにする。

まずはgccライブラリをインストール
これは全ノードでやる

$ sudo dnf groupinstall "Development Tools"
$ sudo dnf install gcc-gfortran

実はhomebrewでgccがインストールされていて、それがここでインストールするライブラリと競合してエラーを出すので一旦homebrewはアンインストールした。(実際今回のシステムではhomebrewでインストールしたプログラムは使っていない)

ヘッドノードにて

$ wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.0.tar.bz2
$ tar xvf openmpi-4.1.0.tar.gz
$ cd openmpi-4.1.0
$ ./configure --prefix=/usr/local |& tee config.out
・・・・
$ make -j 8 |& tee make.out
・・・・
$ sudo make install |& tee install.out
・・・・
$ cd
$ nano .bashrc
##以下を追記する
##openmpi
MPIROOT=/usr/local/package/openmpi/4.1.0
export PATH=$PATH:$MPIROOT/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MPIROOT/lib

$ source .bashrc

## インストールの確認
$ which mpic++
/usr/local/package/openmpi/4.1.0/bin/mpic++
$ which mpirun
/usr/local/package/openmpi/4.1.0/bin/mpirun

テストプログラムhello.cpp

#include <iostream>
#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv)
{
  int rank, size;
  MPI_Init(&argc, &argv);
  // MPI::Init(argc, argv);

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  // rank = MPI::COMM_WORLD.Get_rank();
  // size = MPI::COMM_WORLD.Get_size();

  std::cout << "rank = " << rank << std::endl;
  std::cout << "size = " << size << std::endl;

  MPI_Finalize();
  // MPI::Finalize();
}

ビルドして動かしてみる

$ mpic++ hello.cpp -o hello
$ mpirun -np 2 ./hello
rank = 0
size = 2
rank = 1
size = 2
  • ヘッドノードで公開鍵の設定

ノード間並列処理をするには公開鍵を登録してパスワード無しで計算ノードにアクセスできるようにして置かなければならない。

$ cd .ssh/
$ ssh-keygen #パスワードは空欄のままにする。ここでパスワードを入れると結局パスワードを入力しないとログインできない。
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ echo "StrictHostKeyChecking no" >> ~/.ssh/config
$ chmod 600 ~/.ssh/id_rsa
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 700 ~/.ssh/
$ chmod 600 ~/.ssh/config

## sshできるかテスト
$ ssh k2-inspur-a6

ノード間並列計算テストプログラムhello2.cpp

#include <stdio.h>
#include "mpi.h"
 
int main( int argc, char *argv[] )
{
    int     rank, size, len;
    char    name[MPI_MAX_PROCESSOR_NAME];
 
    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    MPI_Comm_size( MPI_COMM_WORLD, &size );
    MPI_Get_processor_name( name, &len );
    name[len] = '\0';
 
    printf( "Hello world: rank %d of %d running on %s\n", rank, size, name );
 
    MPI_Finalize();
    return 0;
}
$ nano hostfile
## HyperthreadingはMPIでは効率が逆に低下するのでslotsには物理コア数以下を記載する。
k1-inspur-a6 slots=1
k2-inspur-a6 slots=1
k3-inspur-a6 slots=1

$ mpic++ hello2.cpp -o hello2
$ sudo systemctl stop firewalld #ファイアウォールは止めなければならない
$ mpirun --hostfile hostfile -n 3 ./hello2 
Hello world: rank 0 of 3 running on k1-inspur-a6.klab.kuro.jp
Hello world: rank 2 of 3 running on k3-inspur-a6.klab.kuro.jp
Hello world: rank 1 of 3 running on k2-inspur-a6.klab.kuro.jp