User Tools

Site Tools


自作クラスタ計算機:pbs_proの基本設定

概要

  • 一人でクラスタ計算機を使用する場合は問題ありませんが、もし複数人で使用する場合は、プログラムの実行が同じノードでかち合ってしまう可能性があります。
  • これを避けるため、各ユーザーのプログラムの実行を管理するジョブ管理ソフト PBS Professional (PBS Pro) を使用します
  • もちろん、一人でクラスタ計算機を利用する場合でも、複数のジョブの実行を管理してくれるので非常に便利です

環境

  • Ubuntu 20.04 LTS
  • 管理ノードと計算ノードで、OSはバージョンも含めて同一のものを使用してください

構成

PBS Proによるジョブ管理システムは、次のコンポーネントより構成されます

コンポーネント名識別子役割
Serverpbs_serverユーザーからジョブの投入や取り消しなどのコマンドを受け付けます
Schedulerpbs_schedジョブの実行開始や終了のタイミング、どのノードで実行するか、などを管理します
Communication daemonpbs_commノード間の通信を仲介します
Job Executorpbs_momジョブを実行します。momは Machine Oriented Mini-server の略で、全ての実行中のジョブの母親という意味も込められています
  • 上の3つはまとめてフロントエンド (front end) と呼ばれ、同じノード(今回のクラスタ計算機では管理ノード)にまとめるのが普通です。
  • ジョブ・エグゼキュータは計算ノードで動かします。
  • ジョブのコマンドは計算ノードのある1つに送られて、そこで実行されます。この計算ノードをMother superiorノードと呼びます。
    • 他の計算ノードはSisterノードと呼ばれます。Mother superiorノードは(自分を含めた)計算ノードにMPI並列計算のプロセスを割り振ります。

PBSの設置

以下ではNFSサーバによって、管理ノードの

  • /home
  • /opt

が計算ノードと共有されているとします。 また、hostsファイルはNISによって共有されているとします。

準備

hostsファイルの編集

管理ノードで行います

  1. /etc/hosts に、管理ノードと計算ノードのプライベートLAN内におけるIPアドレスとホスト名を登録します
    $ sudo vi /etc/hosts
    hosts
    127.0.0.1	localhost
    127.0.0.1	kanri
    192.168.0.1	kanri
    192.168.0.11    keisan11
    192.168.0.12    keisan12
    192.168.0.13    keisan13
    (以下略)
    • Ubuntuでは自己参照アドレスに127.0.1.1が割り当てられていますが、このままだと後述のQmgrがなぜか編集できなくなるので変更します。
  2. NISの情報を更新します
    $ sudo make -C /var/yp

必要なパッケージのインストール

管理ノードと計算ノードのそれぞれで、アップデートと(必要ならば)再起動を行います

$ sudo apt update
$ sudo apt upgrade
$ sudo reboot

PBS Proには次のパッケージが必要です。

  • PBS Proのコンパイルに必要なもの(管理ノードにインストール)
    $ sudo apt install gcc make libtool libhwloc-dev libx11-dev \
          libxt-dev libedit-dev libical-dev ncurses-dev perl \
          postgresql-server-dev-all postgresql-contrib python3-dev tcl-dev tk-dev swig \
          libexpat-dev libssl-dev libxext-dev libxft-dev autoconf \
          automake
  • PBS Proの実行に必要なもの(管理ノードと計算ノードの両方にインストール)
    $ sudo apt install expat libedit2 postgresql python3 postgresql-contrib sendmail-bin tcl tk libical3 postgresql-server-dev-all libhwloc-dev   # OpenPBS v20
    $ sudo apt install expat libedit2 postgresql python3 postgresql-contrib sendmail-bin tcl tk libical3 postgresql-server-dev-all   # PBS Pro v19

管理ノードでの作業

ここでは /opt/pbs/ にPBS Proを設置することにします。

  1. GitHubのPBS Proの配布ページから最新版のソースコードをダウンロードします
    $ sudo apt install git
    $ git clone https://github.com/openpbs/openpbs.git
    $ cd openpbs
  2. プログラムをコンパイルします
    $ ./autogen.sh
    $ ./configure -prefix=/opt/pbs
    $ make
    • 現在のバージョン(pbs20.0.0)ではPythonのバージョンが3.5であることを要求してくるので、configureで文句を言われたときはpyenvなどを使って変更してください。
  3. PBSのインストールを完了させます
    $ sudo make install
    $ sudo /opt/pbs/libexec/pbs_postinstall
    • (Ubuntu20.04 & pbs20.0.0) pbs_postinstallの際に“update-rc.d: error: no runlevel symlinks to modify, aborting!”と出てきたら自動起動の設定に失敗しています。手動で次のようにしてください
      $ sudo update-rc.d pbs defaults
  4. 設定ファイルで PBS_START_SERVER, PBS_START_SCHED, PBS_START_COMM をすべて1にして、このノードがフロントエンドであることを設定します。
    $ sudo vi /etc/pbs.conf
    pbs.conf
    PBS_SERVER=kanri
    PBS_START_SERVER=1
    PBS_START_SCHED=1
    PBS_START_COMM=1
    PBS_START_MOM=0
    PBS_EXEC=/opt/pbs
    PBS_HOME=/var/spool/pbs
    PBS_CORE_LIMIT=unlimited
    PBS_SCP=/usr/bin/scp
  5. 必要な実行権限を付与します
    $ sudo chmod 4755 /opt/pbs/sbin/pbs_iff /opt/pbs/sbin/pbs_rcp
  6. PBSを起動します
    $ sudo /etc/init.d/pbs start
  7. 環境変数を読み込む設定をします。すべてのユーザーがPBSを使えるように /etc/bash.bashrcを編集します
    $ sudo vim /etc/bash.bashrc 
    bash.bashrc
    (略)
    . /etc/profile.d/pbs.sh
  8. いったんログアウトして、再ログインします

計算ノードでの作業

  1. 計算ノードでPBSのインストールを完了させます
    $ sudo /opt/pbs/libexec/pbs_postinstall
    • (Ubuntu20.04 & pbs20.0.0) pbs_postinstallの際に“update-rc.d: error: no runlevel symlinks to modify, aborting!”と出てきたら自動起動の設定に失敗しています。手動で次のようにしてください
      $ sudo update-rc.d pbs defaults
  2. 設定ファイルで PBS_START_MOM=1 とすることで、このノードが計算ノードであることを指定します。またPBSサーバのホスト名を PBS_SERVER で設定します。
    $ sudo vi /etc/pbs.conf
    pbs.conf
    PBS_SERVER=kanri
    PBS_START_SERVER=0
    PBS_START_SCHED=0
    PBS_START_COMM=0
    PBS_START_MOM=1
    PBS_EXEC=/opt/pbs
    PBS_HOME=/var/spool/pbs
    PBS_CORE_LIMIT=unlimited
    PBS_SCP=/usr/bin/scp
  3. 計算ノードでもPBSを起動します
    $ sudo /etc/init.d/pbs start

計算ノードでの作業はこれで終わりですので、ログアウトして構いません。

動作確認

すべて管理ノードで作業します

Qmgr

QmgrはPBSの設定を管理するソフトで、操作には管理者権限が必要です。 このページでは必ず設定が必要なものだけを紹介します。

Qmgrは次のようにして起動します。

$ sudo -i qmgr

現在どのような設定がされているかは次のようにして確認します

Qmgr: print server
  • ちなみに全部入力しなくても、頭文字だけで “p s” とするだけでも表示されます

Qmgrを終了するにはqあるいはexitと入力します

Qmgr: q

また、Qmgr用のプロンプトを起動せずに操作することもできます

$ sudo -i qmgr -c "print server"

ユーザーの登録

計算ノードからでもPBSが使えるようにします

Qmgr: set server flatuid = True

qstatコマンドで他のユーザーのジョブの実行状況が見えるようにします

Qmgr: set server query_other_jobs = True

計算ノードの登録

計算ノードのホスト名を入力します

Qmgr: create node keisan11
Qmgr: create node keisan12
...

ノードあたりに使用できる最大スレッド数も指定できます(ここでは24コア)。

Qmgr: set node keisan11 resources_available.ncpus=24
Qmgr: set node keisan12 resources_available.ncpus=24
...

ノードの設定状況も確認できます

Qmgr: print node keisan11
#
# Create nodes and set their properties.
#
#
# Create and define node yagami11
#
create node yagami11
set node keisan11 state = free
set node keisan11 resources_available.arch = linux
set node keisan11 resources_available.host = keisan11
set node keisan11 resources_available.mem = 131666992kb
set node keisan11 resources_available.ncpus = 24
set node keisan11 resources_available.vnode = keisan11
set node keisan11 resv_enable = True

使わなくなったノードはdeleteで消せます

Qmgr: delete node keisan11

登録された計算ノードはpbsnodesコマンドを使って確認します

$ pbsnodes -a
  • 計算ノードになんらかのトラブルがあって認識されていない場合は state = down と表示されます。管理ノードから計算ノードにSSHで正しく接続できるにも関わらずこのようなメッセージが出る場合は、計算ノードのPBSを再起動します
    $ sudo /etc/init.d/pbs restart

ジョブの実行

試しに「60秒間何もしない」というジョブを投げてみます。 クラスタ計算機を使用するユーザーで管理ノードにログインしてください。 qsubはジョブを投入するコマンドです

$ echo 'sleep 60' | qsub

ジョブの現在の状態はqstatコマンドで確認できます

$ qstat -s

kanri: 
                                                            Req'd  Req'd   Elap
Job ID          Username Queue    Jobname    SessID NDS TSK Memory Time  S Time
--------------- -------- -------- ---------- ------ --- --- ------ ----- - -----
1.kanri        sugimoto workq    STDIN        9007   1   1    --    --  R 00:00
   Job run at Tue Dec 03 at 04:56 on (keisan11:ncpus=1)

Sの列が状態を表し、Qだと実行待ち、Rだと実行中を意味します。 ジョブが計算ノードkeisan11で実行されていることがわかります。

ジョブを終了または削除したい場合は qdel を使います

$ qdel 1.kanri
  • $ qdel 1 でも可

プログラムの実行

MPIの設置

  • OpenMPI, MPICH2, Intel MPIなどのMPIライブラリを管理ノードの /usr/local や /opt などにインストールし、NFSによって各計算ノードに共有してください

ソースコード

実際にPBSを使ってクラスタ計算機にプログラムを投げてみます。 次のプログラムを使用します。

test.c
#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;
}

コンパイルは次のようにします。

$ mpicc -o hello hello.c
$ mpiicc -o hello hello.c   # Intel MPIを使用する場合

ジョブ投入用スクリプト

次のスクリプトを作成します。

run.sh
#!/bin/bash
#PBS -V
#PBS -l select=2:ncpus=24:mpiprocs=24
 
cd $PBS_O_WORKDIR
 
mpirun ./hello
  • #PBS -V … 現在の環境を計算ノードでも引き継ぎます
  • #PBS -l … 使用するリソースの量を指定します
    • select … ノードの数。指定しなければ1になります
    • ncpus … ノードあたりに確保するコアの数。指定しなければ1になります
    • mpiprocs … ノードあたりのMPIプロセスの数。指定しなければMPI実行時に $ mpirun -n 48 ./hello とMPIプロセス数を明示する必要があります
  • ジョブを受け付けたPBSサーバは、#PBSで始まる行を読み込んで設定を行ったのち、Mother superiorノードにシェルスクリプトを送ります
  • シェルスクリプトを受け取ったMother superiorノードは、管理ノードのユーザ名と同じユーザ名のホームディレクトリで実行します。$PBS_O_WORKDIRには管理ノードで実行したときのディレクトリのパスが格納されているので、計算ノード内の同じ名前のディレクトリに移動します
  • MPIのホストファイル(プログラムを実行するノードのホスト名が書かれたファイル)は、Mother superiorノードの $PBS_NODEFILE = /var/spool/pbs/aux/<Job ID> に生成されたものが使われます

実行権限を付与します。

$ chmod +x run.sh

ジョブを実行します

$ qsub run.sh
1.kanri

結果を見てみます

$ cat run.sh.o1
Hello world: rank 0 of 48 running on keisan11
Hello world: rank 1 of 48 running on keisan11
(略)
Hello world: rank 23 of 48 running on keisan11
Hello world: rank 24 of 48 running on keisan12
Hello world: rank 25 of 48 running on keisan12
(略)
Hello world: rank 47 of 48 running on keisan12

(追記:2023/01/25)

oneAPIをアップデートしたら、ノード間並列をするときにエラーが出るようになってしまいました。 (バージョン:Intel(R) MPI Library 2021.5 for Linux) 次のようにしてください。

run.sh
#!/bin/bash
#PBS -V
#PBS -l select=2:ncpus=24:mpiprocs=24
 
cd $PBS_O_WORKDIR
 
mpirun -bootstrap ssh ./hello

参考:https://community.intel.com/t5/Intel-oneAPI-HPC-Toolkit/faild-running-intel-oneAPI-MPI-mpihell-f90-example-on-multiple/m-p/1357061

OpenMPを使用する場合

OpenMPのみ、あるいはMPI+OpenMPのハイブリッドで使用する場合は、次のようにOpenMPのスレッド数を指定してください

run.sh
#!/bin/bash
#PBS -V
#PBS -l select=2:ncpus=24:mpiprocs=2:ompthreads=12
 
cd $PBS_O_WORKDIR
 
mpirun ./hello
  • ompthreadsはMPIの1プロセスあたりのOpenMPのスレッド数です
  • 基本的には mpiprocs * ompthreads = ncpus となるようにします

Fairshare

複数のユーザーが同時に使用する場合に、うまく計算資源を割り当てる機能です。

ノードごとの負荷の分散

ジョブを投入したら、デフォルトでは1番目の計算ノードにジョブを埋めていき、その計算ノードのリソースが全て埋まってから次の計算ノードでジョブが走るようになります。 これを、各ノードの負荷を分散させるようにジョブが投入されるように変更します。

設定ファイル /var/spool/pbs/sched_priv/sched_config から node_sort_key を探して次のように変更します。

  • 使用しているCPUのコア数が一番少ないノードにジョブを割り当てたい場合
    sched_config
    node_sort_key: "ncpus LOW assigned"     ALL
  • 使用していないCPUのコア数が一番多いノードにジョブを割り当てたい場合
    sched_config
    node_sort_key: "ncpus HIGH unused"     ALL

(各計算ノードのコア数がすべて同じ場合は、どちらも同じ結果になります)

PBSを再起動します。

sudo /etc/init.d/pbs restart
  • PBS Professional 2022.1 Administrator's Guide, Sec. 4.9.49

アンインストール

  1. (管理ノードのみ)計算ノードの情報を削除します
    $ sudo -i qmgr -c "delete node @default"
  2. PBSを終了します
    $ sudo /etc/init.d/pbs stop
  3. インストール時に設置されたファイルを削除します
    $ sudo rm -f /etc/pbs.*
    $ sudo rm -f /etc/profile.d/pbs.*
    $ sudo rm -f /etc/rc*.d/*pbs
    $ sudo rm -f /etc/init.d/pbs
    $ sudo rm -rf /var/spool/pbs
    $ sudo rm -rf /opt/pbs/

PBS Proについて

Altair Engineering社が提供するジョブ管理ソフトです。もともとは有償でしたが、2016年にオープンソース化しました

参考

自作クラスタ計算機/pbs_proの基本設定.txt · Last modified: 2023/12/26 23:49 by koudai