PBS Proによるジョブ管理システムは、次のコンポーネントより構成されます
| コンポーネント名 | 識別子 | 役割 |
|---|---|---|
| Server | pbs_server | ユーザーからジョブの投入や取り消しなどのコマンドを受け付けます |
| Scheduler | pbs_sched | ジョブの実行開始や終了のタイミング、どのノードで実行するか、などを管理します |
| Communication daemon | pbs_comm | ノード間の通信を仲介します |
| Job Executor | pbs_mom | ジョブを実行します。momは Machine Oriented Mini-server の略で、全ての実行中のジョブの母親という意味も込められています |
以下ではNFSサーバによって、管理ノードの
が計算ノードと共有されているとします。 また、ユーザー情報とhostsも共有されているとします。
パスフレーズ無しで計算ノードにSSHログインできるようにします。 PBSを使用する全ユーザーは、管理ノードで以下を実行してください。
$ ssh-keygen -N "" $ cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys $ chmod 600 ~/.ssh/authorized_keys $ echo "StrictHostKeyChecking no" >> ~/.ssh/config
管理ノードと計算ノードで行います
$ sudo nano /etc/hosts
127.0.0.1 localhost #127.0.1.1 head # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
管理ノードと計算ノードのそれぞれで、アップデートと(必要ならば)再起動を行います
$ sudo apt update $ sudo apt upgrade $ sudo reboot
OpenPBSには次のパッケージが必要です。
$ 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 g++ libcjson-dev
$ sudo apt install expat libedit2 postgresql python3 postgresql-contrib sendmail-bin tcl tk libical3 postgresql-server-dev-all libhwloc-dev libcjson-dev # OpenPBS v23
ここでは /opt/pbs/ にOpenPBSを設置することにします。
$ sudo apt install git $ git clone https://github.com/openpbs/openpbs.git $ cd openpbs
$ ./autogen.sh $ ./configure -prefix=/opt/pbs $ make
$ sudo make install $ sudo /opt/pbs/libexec/pbs_postinstall
$ sudo update-rc.d pbs defaults
$ sudo nano /etc/pbs.conf
PBS_SERVER=head 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
$ sudo chmod 4755 /opt/pbs/sbin/pbs_iff /opt/pbs/sbin/pbs_rcp
$ sudo /etc/init.d/pbs start
$ sudo nano /etc/bash.bashrc
(略) . /etc/profile.d/pbs.sh
$ sudo /opt/pbs/libexec/pbs_postinstall
$ sudo update-rc.d pbs defaults
$ sudo nano /etc/pbs.conf
PBS_SERVER=head 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
$ sudo /etc/init.d/pbs start
計算ノードでの作業はこれで終わりですので、ログアウトして構いません。
すべて管理ノードで作業します
QmgrはPBSの設定を管理するソフトで、操作には管理者権限が必要です。 このページでは必ず設定が必要なものだけを紹介します。
Qmgrは次のようにして起動します。
$ sudo -i qmgr
現在どのような設定がされているかは次のようにして確認します
Qmgr: print server
Qmgrを終了するにはqあるいはexitと入力します
Qmgr: q
また、Qmgr用のプロンプトを起動せずに操作することもできます
$ sudo -i qmgr -c "print server"
管理サーバーと計算ノードでUIDが一致していなくてもジョブを投入できるようになります。
Qmgr: set server flatuid = True
qstatコマンドで他のユーザーのジョブの実行状況が見えるようにします
Qmgr: set server query_other_jobs = True
計算ノードのホスト名を入力します
Qmgr: create node node11 Qmgr: create node node12 ...
ノードあたりに使用できる最大スレッド数も指定できます(ここでは24コア)。
Qmgr: set node node11 resources_available.ncpus=24 Qmgr: set node node12 resources_available.ncpus=24 ...
ノードの設定状況も確認できます
Qmgr: print node node11 # # Create nodes and set their properties. # # # Create and define node node11 # create node node11 set node node11 state = free set node node11 resources_available.arch = linux set node node11 resources_available.host = node11 set node node11 resources_available.mem = 131666992kb set node node11 resources_available.ncpus = 24 set node node11 resources_available.vnode = node11 set node node11 resv_enable = True
使わなくなったノードはdeleteで消せます
Qmgr: delete node node11
登録された計算ノードはpbsnodesコマンドを使って確認します
$ pbsnodes -a
$ sudo /etc/init.d/pbs restart
試しに「60秒間何もしない」というジョブを投げてみます。 クラスタ計算機を使用するユーザーで管理ノードにログインしてください。 qsubはジョブを投入するコマンドです
$ echo 'sleep 60' | qsub
ジョブの現在の状態はqstatコマンドで確認できます
$ qstat -s
head:
Req'd Req'd Elap
Job ID Username Queue Jobname SessID NDS TSK Memory Time S Time
--------------- -------- -------- ---------- ------ --- --- ------ ----- - -----
0.head sugimoto workq STDIN 9007 1 1 -- -- R 00:00
Job run at Tue Dec 03 at 04:56 on (node11:ncpus=1)
Sの列が状態を表し、Qだと実行待ち、Rだと実行中を意味します。 ジョブが計算ノードnode11で実行されていることがわかります。
ジョブを強制終了したい場合は qdel を使います
$ qdel <Job ID>
実際にPBSを使ってクラスタ計算機にプログラムを投げてみます。 次のプログラムを使用します。
#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 test test.c $ mpiicx -o test test.c # Intel MPIを使用する場合
次のスクリプトを作成します。
#!/bin/bash #PBS -V #PBS -l select=2:ncpus=24:mpiprocs=24 cd $PBS_O_WORKDIR mpirun ./test
実行権限を付与します。
$ chmod +x run.sh
ジョブを実行します
$ qsub run.sh 1.head
結果を見てみます
$ cat run.sh.o1 Hello world: rank 0 of 48 running on node11 Hello world: rank 1 of 48 running on node11 (略) Hello world: rank 23 of 48 running on node11 Hello world: rank 24 of 48 running on node12 Hello world: rank 25 of 48 running on node12 (略) Hello world: rank 47 of 48 running on node12
oneAPIをアップデートしたら、ノード間並列をするときにエラーが出るようになってしまいました。 (バージョン:Intel(R) MPI Library 2021.5 for Linux) 次のようにしてください。
#!/bin/bash #PBS -V #PBS -l select=2:ncpus=24:mpiprocs=24 cd $PBS_O_WORKDIR mpirun -bootstrap ssh ./hello
OpenMPのみ、あるいはMPI+OpenMPのハイブリッドで使用する場合は、次のようにOpenMPのスレッド数を指定してください
#!/bin/bash #PBS -V #PBS -l select=2:ncpus=24:mpiprocs=2:ompthreads=12 cd $PBS_O_WORKDIR mpirun ./hello
複数のユーザーが同時に使用する場合に、うまく計算資源を割り当てる機能です。
ジョブを投入したら、デフォルトでは1番目の計算ノードにジョブを埋めていき、その計算ノードのリソースが全て埋まってから次の計算ノードでジョブが走るようになります。 これを、各ノードの負荷を分散させるようにジョブが投入されるように変更します。
設定ファイル /var/spool/pbs/sched_priv/sched_config から node_sort_key を探して次のように変更します。
node_sort_key: "ncpus LOW assigned" ALL
node_sort_key: "ncpus HIGH unused" ALL
(各計算ノードのコア数がすべて同じ場合は、どちらも同じ結果になります)
PBSを再起動します。
sudo /etc/init.d/pbs restart
$ sudo -i qmgr -c "delete node @default"
$ sudo /etc/init.d/pbs stop
$ 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/
SupermicroのIPMI LANポートが搭載されたマザーボードでは、そのポートにローカルIPアドレス169.254.3.1が自動で割り振られた上で、管理ノードにこのIPがこの計算ノードのIPアドレスだと登録されてしまうことがあります。 実際、計算ノードにログインして、ログを確認すると
$ sudo tail -n 10 /var/spool/pbs/mom_logs/20260629 06/29/2026 07:11:24;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Connected to pbs_comm head:17001 06/29/2026 07:11:24;0001;pbs_mom;Svr;net_restore_handler;net restore handler called 06/29/2026 07:11:24;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Connection to pbs_comm head:17001 down 06/29/2026 07:11:24;0001;pbs_mom;Svr;net_down_handler;net down handler called 06/29/2026 07:11:26;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Registering address 169.254.3.1:15003 to pbs_comm head:17001 06/29/2026 07:11:26;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Registering address 192.168.0.27:15003 to pbs_comm head:17001 06/29/2026 07:11:26;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Connected to pbs_comm head:17001 06/29/2026 07:11:26;0001;pbs_mom;Svr;net_restore_handler;net restore handler called 06/29/2026 07:11:26;0c06;pbs_mom;TPP;pbs_mom(Thread 0);Connection to pbs_comm head:17001 down 06/29/2026 07:11:26;0001;pbs_mom;Svr;net_down_handler;net down handler called
となっています。
169.254.3.1が割り当てられてしまっているポートを確認します
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enxbe3af2b6059f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether be:3a:f2:b6:05:9f brd ff:ff:ff:ff:ff:ff
inet 169.254.3.1/24 metric 1024 brd 169.254.3.255 scope global dynamic enxbe3af2b6059f
valid_lft 861890sec preferred_lft 861890sec
inet6 fe80::bc3a:f2ff:feb6:59f/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
3: eno1np0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 7c:c2:55:84:d2:e8 brd ff:ff:ff:ff:ff:ff
altname enp61s0f0np0
altname enx7cc25584d2e8
inet 192.168.0.27/24 metric 100 brd 192.168.0.255 scope global dynamic eno1np0
valid_lft 231sec preferred_lft 231sec
inet6 fe80::7ec2:55ff:fe84:d2e8/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
4: eno2np1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 7c:c2:55:84:d2:e9 brd ff:ff:ff:ff:ff:ff
altname enp61s0f1np1
altname enx7cc25584d2e9
enxbe3af2b6059fというポートに169.254.3.1が割り当てられてしまっていることがわかるため、netplanの設定でIPアドレスが割り当てられないようにします。
$ sudo nano /etc/netplan/00-installer-config.yaml
network:
ethernets:
eno1np0:
dhcp4: true
dhcp6: true
dhcp-identifier: mac
enxbe3af2b6059f:
addresses: []
version: 2
$ sudo netplan apply $ sudo /etc/init.d/pbs restart