研究室でできる自作計算機クラスタの作り方。
Introduction: 計算機クラスタの構築
当研究室では高性能なCPU/GPUを搭載したマシンを数台所有していますが、研究室の学生が計算したいときにアイドル状態の計算機に計算を自動的に割り振るためにジョブキューイングシステムを導入しました。
ちなみに計算機が1台しかない場合でも、キューイングシステムを作っておくことで、前の計算が終わったと同時に次の計算が実行されるようになったりと便利な面があります。
環境
- OS: Ubuntu 22.04 or Rocky Linux 8.8 or Almalinux 8。たぶんRocky/Alma linux 9以降でも動作する。
- Network: Gigabit EthernetとLANケーブル cat.5e以上が望ましい
- Job queuing system: Torque 6.1.3
- CentOS, Rocky, Almaの場合は、SELinuxをdisabledにしておいた方がおいたほうが良い(※未検証ですが私はいつもdisabledにしています)
Torque 6.1.3は、(以下の要領でパッチを当てさえすれば)最近のLinux系であればある程度どれでも動くようになっていると思います。
登場する計算機
以降の説明では管理ノード(ヘッドノードとも)と計算ノードの2種類が登場します。管理ノード・計算ノードの名前とIPアドレスは以下の通りとします。
- 管理ノード
- keisan_master: 192.168.1.1
- 計算ノード
- keisan1: 192.168.1.2
- keisan2: 192.168.1.3
これらは後ほどの/etc/hosts
, /etc/hosts.equiv
設定時に関わってきます。管理ノードの名前や計算ノードの名前・IPアドレスは自由に設定できます。この辺の設定は https://www.server-world.info/query?os=Rocky_Linux_8&p=initial_conf&f=3 などを読んでください。
また、これらの計算機はすべてNISによるアカウント情報の共有、NFS(autofsなどでも可)によるファイルの共有が常時行われているものと仮定します。これにより、管理ノード・計算ノードのいずれにもユーザーアカウントが共有され、ユーザーのファイルが常時同じになるよう更新されます。こうすることで、あるユーザーが管理ノードでジョブを実行するようにqsub
コマンドを入れると、管理ノードは空いている計算ノードに計算を委託する司令を与え、計算ノードはそのユーザー名を用いて計算を行います。そして計算の結果ファイルは自動的に全ノードにリアルタイムで共有されることになります。
NIS, NFSを用いたこれらの計算機の設定はここでは触れません。https://www.server-world.info/query?os=Rocky_Linux_8&p=nis&f=1 とか https://www.server-world.info/query?os=Rocky_Linux_8&p=nfs&f=1 などを参考にしてください。
Torque 6.1.3
参考にしたログ: https://kojipkgs.fedoraproject.org//packages/torque/6.1.3/8.el9/data/logs/x86_64/build.log
まずsudo su -
をしてrootユーザーになっておきます。先に必要なパッケージをインストールしておきます。
# Ubuntuの場合
apt -y install autoconf automake libtool libboost-all-dev libjsoncpp-dev tcl tk tcl-dev tk-dev
# Rocky Linux 8, AlmaLinux 8, RedHat系OSの場合
dnf -y install epel-release
dnf -y install libtool openssl-devel libxml2-devel boost-devel jsoncpp jsoncpp-devel gcc gcc-c++ git
次に、fedoraprojectのページからtorqueのソースコードとそれらのパッチをダウンロードしてパッチを当てつつ、./configure
でインストール準備を開始します。
ところで、以下に書くようなソースコードからのインストールをしなくてもdnf
やyum
を探せばtorque 6.1.3(ver.9の場合)またはtorque 4.2.10(ver.8の場合)をインストールする事もできますが(参考:https://rpmfind.net/linux/rpm2html/search.php?query=torque(x86-64) )、これだとnumaコア設定のものしか使えないのが気持ち悪いのでやめておきました。
Torque本体のインストール
管理ノードと計算ノードすべてにTorque 6.1.3をインストールします。Rocky, Almalinux 8の場合、デフォルトのGCCコンパイラのバージョンが8ですが、Torque 6.1.3のコンパイルに対してgcc ver.8ではコンパイルに失敗します。このため、必ずgcc-9またはgcc-11を使うように設定してください。Ubuntu 22.04やRocky, Almaの9ではデフォルトGCCで大丈夫だと思います。
gccのバージョンはターミナルからgcc --version
で確認できます。Rocky, Almalinux 8の場合は以下のようにしてgcc-11を入れるのがおすすめです。
# gcc-toolset-11をインストール
$ dnf install gcc-toolset-11
$ scl enable gcc-toolset-11 bash # または scl enable gcc-toolset-11 zsh
$ which gcc
$ gcc --version # バージョン確認
gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GCCのバージョンを確認したら、続いてTorqueをインストールします。
以降、$
で始まるコマンドのみ入力してください。
# ソースコードのダウンロード
$ wget https://src.fedoraproject.org/lookaside/pkgs/torque/torque-6.1.3.tar.xz/sha512/9cace317a6331c8a043a11115161cd9a852623ce0ccbc6d745fcc16963a8fe63ed8e4c2d0922a9bd950a2aa6273246340ea32488c88d2e9e476067c3429f1b85/torque-6.1.3.tar.xz
# 解凍
$ tar Jxvf torque-6.1.3.tar.xz
$ cd torque
# パッチファイルのダウンロード
# Patch #1 (torque-munge-size.patch)
$ wget https://src.fedoraproject.org/rpms/torque/raw/epel9/f/torque-munge-size.patch
# Patch #2 (torque-6.1.3-port-args.patch):
$ wget https://src.fedoraproject.org/rpms/torque/raw/epel9/f/torque-6.1.3-port-args.patch
# Patch #3は存在していない様子
# Patch #4 (torque-6.1.3-system-jsoncpp.patch):
$ wget https://src.fedoraproject.org/rpms/torque/raw/epel9/f/torque-6.1.3-system-jsoncpp.patch
# Patch #5 (torque-6.1.3-bool-fix.patch):
$ wget https://src.fedoraproject.org/rpms/torque/raw/epel9/f/torque-6.1.3-bool-fix.patch
# Patch #6 (torque-6.1.3-autoconf-fixes.patch):
$ wget https://src.fedoraproject.org/rpms/torque/raw/epel9/f/torque-6.1.3-autoconf-fixes.patch
# 以下パッチを当てていく
$ patch --no-backup-if-mismatch -p1 -b --suffix .munge-size --fuzz=0 < torque-munge-size.patch
# patching file src/include/libpbs.hと表示が出る
$ patch --no-backup-if-mismatch -p1 -b --suffix .port-args --fuzz=0 < torque-6.1.3-port-args.patch
# patching file contrib/init.d/pbs_mom.in
$ patch --no-backup-if-mismatch -p1 -b --suffix .system-jsoncpp --fuzz=0 < torque-6.1.3-system-jsoncpp.patch
# patching file configure.ac
# patching file src/include/machine.hpp
# patching file src/include/Makefile.am
# patching file src/include/pbs_job.h
# patching file src/lib/Libutils/Makefile.am
# patching file src/resmom/catch_child.c
# patching file src/resmom/mom_server.c
# patching file src/resmom/parse_config.c
# patching file src/resmom/prolog.c
# patching file src/resmom/requests.c
# patching file src/server/job.cpp
# patching file src/server/node_manager.c
# patching file src/server/pbsnode.cpp
# patching file src/test/catch_child/scaffolding.c
# patching file src/test/job/test_uut.c
# patching file src/test/machine/scaffolding.c
# patching file src/test/machine/test_uut.c
# patching file src/test/node_manager/scaffolding.c
# patching file src/test/node_manager/test_uut.c
# patching file src/test/numa_chip/scaffolding.c
# patching file src/test/numa_chip/test_uut.c
# patching file src/test/numa_socket/scaffolding.c
# patching file src/test/numa_socket/test_uut.c
# patching file src/test/parse_config/scaffolding.c
# patching file src/test/parse_config/test_uut.c
# patching file src/test/prolog/scaffolding.c
$ patch --no-backup-if-mismatch -p1 -b --suffix .bool-fix --fuzz=0 < torque-6.1.3-bool-fix.patch
# patching file src/drmaa/src/compat.h
# patching file src/include/pbs_ifl.h
$ patch --no-backup-if-mismatch -p1 -b --suffix .cleanup --fuzz=0 < torque-6.1.3-autoconf-fixes.patch
# patching file acinclude.m4
# patching file buildutils/ac_c_bigendian_cross.m4
# patching file buildutils/acx_pthread.m4
# patching file buildutils/ax_cflags_gcc_option.m4
# patching file buildutils/tac_tcltk.m4
# patching file buildutils/tcl.m4
# patching file configure.ac
$ autoreconf -ifv
$ ./configure CFLAGS="-O2 -Wno-deprecated-declarations -Wno-cast-function-type -fpermissive" \
CXXFLAGS="-O2 -Wno-deprecated-declarations -Wno-cast-function-type -fpermissive" \
--disable-static --with-tcp-retry-limit=2 --without-debug \
--with-default-server=localhost --with-tcl \
--with-tk --with-rcp=/usr/bin/rcp --disable-static --prefix=/usr/local
# configureでエラーが無ければインストール開始
$ make -j8 CC=g++ && make install
エラーなくmake install
が終わればOKです。
Torque packagesのインストール
Torqueのmake install
が終わったら、そのままのディレクトリでmake packages
を入力して必要なパッケージをインストールします。
$ make packages
Building packages from /root/torque/tpackages
$ rm -rf /root/torque/tpackages
$ mkdir /root/torque/tpackages
Building ./torque-package-server-linux-x86_64.sh ...
libtool: warning: remember to run 'libtool --finish /usr/local/lib'
Building ./torque-package-mom-linux-x86_64.sh ...
libtool: warning: remember to run 'libtool --finish /usr/local/lib'
Building ./torque-package-clients-linux-x86_64.sh ...
libtool: warning: remember to run 'libtool --finish /usr/local/lib'
Building ./torque-package-gui-linux-x86_64.sh ...
Building ./torque-package-devel-linux-x86_64.sh ...
libtool: warning: remember to run 'libtool --finish /usr/local/lib'
Building ./torque-package-doc-linux-x86_64.sh ...
Makefile:1202: warning: ignoring prerequisites on suffix rule definition
Makefile:1206: warning: ignoring prerequisites on suffix rule definition
Makefile:1210: warning: ignoring prerequisites on suffix rule definition
Makefile:1214: warning: ignoring prerequisites on suffix rule definition
Makefile:1202: warning: ignoring prerequisites on suffix rule definition
Makefile:1206: warning: ignoring prerequisites on suffix rule definition
Makefile:1210: warning: ignoring prerequisites on suffix rule definition
Makefile:1214: warning: ignoring prerequisites on suffix rule definition
Makefile:1202: warning: ignoring prerequisites on suffix rule definition
Makefile:1206: warning: ignoring prerequisites on suffix rule definition
Makefile:1210: warning: ignoring prerequisites on suffix rule definition
Makefile:1214: warning: ignoring prerequisites on suffix rule definition
Makefile:1202: warning: ignoring prerequisites on suffix rule definition
Makefile:1206: warning: ignoring prerequisites on suffix rule definition
Makefile:1210: warning: ignoring prerequisites on suffix rule definition
Makefile:1214: warning: ignoring prerequisites on suffix rule definition
Makefile:1202: warning: ignoring prerequisites on suffix rule definition
Makefile:1206: warning: ignoring prerequisites on suffix rule definition
Makefile:1210: warning: ignoring prerequisites on suffix rule definition
Makefile:1214: warning: ignoring prerequisites on suffix rule definition
Done.
続いて次のコマンドを実行します。torque-package-server-linux-x86_64.sh
,torque-package-mom-linux-x86_64.sh
とtorque-package-devel-linux-x86_64.sh
の3種類がありますが、キューイングシステムにおける司令塔となる管理ノードには./torque-package-server-linux-x86_64.sh
を、管理ノードから司令を受けて計算を引き受ける計算ノードには./torque-package-mom-linux-x86_64.sh
と./torque-package-clients-linux-x86_64.sh
をインストールしておきます。ただ別に3つとも実行しておいて問題ないのでそうしておくと大丈夫です。
# torqueパッケージのインストール
$ ./torque-package-server-linux-x86_64.sh --install
Installing TORQUE archive...
Done.
$ ./torque-package-mom-linux-x86_64.sh --install
$ ./torque-package-clients-linux-x86_64.sh --install
次に、管理ノードと計算ノードの両方に管理ノードのサーバーの名前(keisan_master
)を/var/spool/torque/server_name
というファイルに書き込みます。このサーバー名は後ほど設定することになる/etc/hosts
ファイルに書き込むホスト名(マシン名)と対応している必要があります。
$ echo "keisan_master" > /var/spool/torque/server_name
$ cat /var/spool/torque/server_name
keisan_master
firewall-cmdコマンドでtorqueのためにポートを開放する
Redhat系OS(Fedora, CentOS, Almalinux, RockyLinux)の場合は、ポート開放処理をする必要があります。Ubuntu OSの場合はデフォルトでポートが開放状態になっていますが、ufwなどでファイアウォールを起動している場合は、ufwについて指定のポート番号を開放する処理を行う必要があります。
#Redhat系OS(CentOS, Almalinux, RockyLinux)の場合
$ firewall-cmd --add-port=15001/tcp --permanent
$ firewall-cmd --add-port=15002/tcp --permanent
$ firewall-cmd --add-port=15003/tcp --permanent
$ firewall-cmd --add-service=rsh --permanent
# 最後にかならずポート開放設定を反映させる
$ firewall-cmd --reload
torque.setup
管理ノードでtorque.setup
を実行し、初期設定を行います。
$ cd /root/torque
$ bash torque.setup root
initializing TORQUE (admin: root)
You have selected to start pbs_server in create mode.
If the server database exists it will be overwritten.
do you wish to continue y/(n)?
y
を押して次に進みます。
nodesファイルの作成
計算に使用するノード(※管理ノードにも計算させる場合その名前も含む)の設定をすべて書いたファイルを、管理ノードの/var/spool/torque/server_priv/nodes
に書き込みます。
keisan_master np=8
keisan1 np=16 gpus=1
keisan2 np=16 gpus=1 alphafold
ここでnodes
ファイルの書き方は https://docs.adaptivecomputing.com/torque/4-1-4/help.htm#topics/1-installConfig/serverNodeFileConfig.htm や https://www.hpc.co.jp/images/pdf/manual/TorqueManual.pdf などのページを参考にしてください。npにはそのマシンのコア数を、gpusのところには搭載されているGPUの台数を書くことで、その上限値を設定することができます。またその後にプロパティ(properties) と呼ばれる属性を書くことが可能です。このプロパティはユーザーがジョブ投入時に指定することで効果を発揮します。
このファイルは後からも変更可能です。計算ノードを追加した場合、このファイルを追記して後述のpbs_serverプロセスを再起動することで有効になります。
計算ノード名とIPアドレスの設定
管理ノードと計算ノードのすべての/etc/hosts
と/etc/hosts.equiv
ファイルを編集して、計算クラスタに関わる全ノードのホスト名(マシン名)とIPアドレスのアドレスの対応表を作っておく必要があります。書式は以下の通りです。
/etc/hosts
の方
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.1 keisan_master
192.168.1.2 keisan1
192.168.1.3 keisan2
/etc/hosts.equiv
の方
keisan_master
keisan1
keisan2
後で計算ノードを追加する場合、忘れずにこれらのファイルも全ノードにおいて更新しておく必要があります。
pbs_serverの起動
管理ノードには以下の処理を行います。解凍されているtorqueのディレクトリの中にあるcontrib
以下にあるサービス制御のファイルを/usr/lib/systemd/system/
にコピーし、その後systemctl
コマンドでサービスを起動します。
管理ノードのサービスはpdb_server
とtrqauthd
とpdb_sched
です。この3つを起動させ、statusチェックでエラーが出ていないことを必ず確認してください。
cd /root/torque
cp contrib/systemd/pbs_server.service /usr/lib/systemd/system/
cp contrib/systemd/trqauthd.service /usr/lib/systemd/system/
cp contrib/systemd/pbs_sched.service /usr/lib/systemd/system/
systemctl enable pbs_server.service
systemctl start pbs_server.service
systemctl enable trqauthd.service
systemctl start trqauthd.service
systemctl enable pbs_sched.service
systemctl start pbs_sched.service
systemctl status pbs_sched
systemctl
はLinuxでサービスを制御するためのコマンドです。簡単な説明と意味は https://qiita.com/wms2a4i1/items/04a1250229b12da33b87 などを読んでください。
エラーがあった場合は原因を特定し修正した上で、systemctl restart foo.service
でそのサービスを再起動し、status
で状態を再確認します。(※.service
部分の入力は省略可能)
pbs_momの起動
計算ノード(計算を実行させるノード)には以下の処理を行います。計算ノードで必要となるサービスはpbs_mom
だけですが、trqauthd
もしておくと状態確認上で便利なことがあります。
cd /root/torque
cp contrib/systemd/pbs_mom.service /usr/lib/systemd/system/
cp contrib/systemd/trqauthd.service /usr/lib/systemd/system/
systemctl enable pbs_mom.service
systemctl start pbs_mom.service
systemctl status pbs_mom
systemctl enable trqauthd.service
systemctl start trqauthd.service
systemctl status trqauthd
(あまりないですけれど)httpdを入れてある場合には、/usr/lib/systemd/system/httpd.service
のPrivateTmp
をfalse
にしておくべきらしいです。
sed -i -e "s/PrivateTmp=true/PrivateTmp=false/g" /usr/lib/systemd/system/httpd.service
systemctl daemon-reload
systemctl restart httpd
設定の確認
ここまでの設定がうまく行っていればsystemctl status なんちゃら
としたときに以下のような表示になります。
$ systemctl status trqauthd
● trqauthd.service - TORQUE trqauthd daemon
Loaded: loaded (/lib/systemd/system/trqauthd.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-08-13 18:53:11 JST; 13min ago
Main PID: 1568 (trqauthd)
Tasks: 1 (limit: 38308)
Memory: 872.0K
CPU: 3ms
CGroup: /system.slice/trqauthd.service
└─1568 /usr/local/sbin/trqauthd -F
8月 13 18:53:11 keisan_master systemd[1]: Started TORQUE trqauthd daemon.
8月 13 18:53:11 keisan_master trqauthd[1568]: Currently no servers active. Default server will be listed as active server. E>
8月 13 18:53:11 keisan_master trqauthd[1568]: Active server name: keisan_master pbs_server port is: 15001
8月 13 18:53:11 keisan_master trqauthd[1568]: trqauthd port: /tmp/trqauthd-unix
Active:
の部分が緑色でactive (running)
となっているとOKです。赤色でfailed
となっている場合は稼働していません。この場合は設定を確認または変更したあとsystemctl restart <該当のサービス名>
として再起動し、activeになることを確認します。
$ systemctl status pbs_sched
* pbs_sched.service - TORQUE pbs_sched daemon
Loaded: loaded (/lib/systemd/system/pbs_sched.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-08-13 19:16:07 JST; 8s ago
Process: 3272 ExecStart=/usr/local/sbin/pbs_sched -d $PBS_HOME $PBS_ARGS (code=exited, status=0/SUCCESS)
Main PID: 3273 (pbs_sched)
Tasks: 1 (limit: 38308)
Memory: 2.9M
CPU: 3ms
CGroup: /system.slice/pbs_sched.service
`-3273 /usr/local/sbin/pbs_sched -d /var/spool/torque
Aug 13 19:16:07 keisan_master systemd[1]: Starting TORQUE pbs_sched daemon...
Aug 13 19:16:07 keisan_master systemd[1]: Started TORQUE pbs_sched daemon.
$ systemctl status pbs_server
● pbs_server.service - TORQUE pbs_server daemon
Loaded: loaded (/lib/systemd/system/pbs_server.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2023-08-13 18:53:11 JST; 26s ago
Main PID: 1569 (pbs_server)
Tasks: 10 (limit: 38308)
Memory: 18.0M
CPU: 17ms
CGroup: /system.slice/pbs_server.service
└─1569 /usr/local/sbin/pbs_server -F -d /var/spool/torque
8月 13 18:53:11 keisan_master systemd[1]: Started TORQUE pbs_server daemon.
8月 13 18:53:11 keisan_master PBS_Server[1569]: LOG_ERROR::tcp_connect_sockaddr,
pbsnodes -a
と打ったときに、計算ノードすべての表示が現れているとOKです。
$ pbsnodes -a
keisan_master
state = free
power_state = Running
np = 8
ntype = cluster
status = opsys=linux,uname=Linux keisan_master 4.18.0-425.19.2.el8_7.x86_64 #1 SMP Tue Apr 4 22:38:11 UTC 2023 x86_64,sessions=2655 2100 2860,nsessions=3,nusers=1,idletime=2848,totmem=205082836kb,availmem=199625776kb,physmem=196694232kb,ncpus=8,loadave=0.00,gres=,netload=382925861,state=free,varattr= ,cpuclock=Fixed,version=6.1.3,rectime=1697965154,jobs=
mom_service_port = 15002
mom_manager_port = 15003
keisan1
state = free
power_state = Running
np = 16
ntype = cluster
status = opsys=linux,uname=Linux keisan1 4.18.0-477.27.1.el8_8.x86_64 #1 SMP Wed Sep 20 15:55:39 UTC 2023 x86_64,nsessions=0,nusers=0,idletime=182861,totmem=101251836kb,availmem=100240860kb,physmem=97057536kb,ncpus=48,loadave=0.00,gres=,netload=101274558,state=free,varattr= ,cpuclock=Fixed,macaddr=ac:1f:6b:75:cd:da,version=6.1.3,rectime=1697965133,jobs=
mom_service_port = 15002
mom_manager_port = 15003
gpus = 1
keisan2
state = free
power_state = Running
np = 16
properties = alphafold
ntype = cluster
status = opsys=linux,uname=Linux keisan2 4.18.0-477.27.1.el8_8.x86_64 #1 SMP Wed Sep 20 15:55:39 UTC 2023 x86_64,nsessions=0,nusers=0,idletime=183146,totmem=101251836kb,availmem=100246376kb,physmem=97057536kb,ncpus=48,loadave=0.07,gres=,netload=83318341,state=free,varattr= ,cpuclock=Fixed,macaddr=ac:1f:6b:6c:8c:fe,version=6.1.3,rectime=1697965144,jobs=
mom_service_port = 15002
mom_manager_port = 15003
gpus = 1
このうち、state = free
であれば管理サーバーからの計算依頼を受け付けている状態ですが、state = down
の場合は管理サーバー・計算サーバー間でのtorqueでの通信ができておらず、計算を受け入れられない状態です。このstate = down
は解決しなければならない状態です。
キューイングシステムの作成
queueの作成と設定
以降の処理は管理ノードにおいて行います。デフォルトで設定するbatch
という名前のqueueタイプを削除して、default
という名前のqueueタイプを作成します。ちなみにターミナルからはqmgr -c 'p s'
と入力することで現在の設定の一覧を見ることができます。管理ノードにおいてqmgr
コマンドをターミナルから入力すると、以降標準入力からインタラクティブに設定をどんどん作ることができます。
#ターミナルからqmgrを入力してqmgrモードに入る
qmgr
# デフォルトのbatchキューの削除
delete queue batch
# "default"キューの作成
# 最大で連続72時間しか使えないようにする。デフォルトは24時間指定。
create queue default
set queue default queue_type = Execution
set queue default max_running = 32
set queue default resources_max.walltime = 72:00:00
set queue default resources_default.walltime = 24:00:00
set queue default enabled = True
set queue default started = True
# "week"キューの作成
# 最大で連続168時間使える。デフォルトは24時間指定。
create queue week
set queue week queue_type = Execution
set queue week max_running = 4
set queue week resources_max.walltime = 168:00:00
set queue week resources_default.walltime = 24:00:00
set queue week enabled = True
set queue week started = True
#PBS schedulingをONにする.
#これを使うと自動でジョブを振り分けてくれる。`systemctl status pbs_sched`でスケジューラのdaemonが働いているか確認できる。
set server scheduling = True
#他のユーザーからジョブを見られるようにする
set server query_other_jobs = True
#ジョブ終了後3秒でqstatのリストから消えるようにする
set server keep_completed = 3
quit
starving jobsエラーへの対処
デフォルトでは、一定時間ジョブが投入されない状態が続いていると、全ユーザーに対してNot Running: Draining system to allow starving job to run
というエラーが表示されてジョブが実行されなくなる状態が発生することがあります。正直これは最初からそうならないように設定しておいたほうがいいので、以下のように設定変更しておきます。
管理ノードの/var/spool/torque/sched_priv/sched_config
の以下の行を変更します。
help_starving_jobs true ALL
これを
help_starving_jobs false ALL
に変更します。この後、PBSスケジューラを再起動するために、systemctl restart pbs_sched
を実行します。再起動後、systemctl status pbs_sched
で緑信号(Running)が表示されれば成功です。
postfixでジョブ終了メール通知を遅れるようにする
(書きかけ)
Torqueによるジョブキューイングシステム
qsub
コマンドを使うことで待機状態の計算ノードを自動サーチして計算をさせることができます。
ジョブ投入テスト
keisan_masterにログインして以下のスクリプトを作ってみて、実行できるかどうか確かめてみましょう。
#!/bin/sh
#PBS -l nodes=1:ppn=16
#PBS -q default
#PBS -l walltime=0:30:00
## must include these lines
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
# show the calculation node
echo `hostname`
# run the environment module
. /home/apps/Modules/init/profile.sh
## Write your qsub script from here.
# Output message
echo "Hello keisan_master!!"
# wait for 5 seconds.
sleep 5s
これをホームディレクトリ上にtest.sh
という名前で作成し、qsub -N Hellotest test.sh
と入力して実行してみましょう。すると JOB_ID
.keisan_master
というメッセージが標準出力に現れ、5秒後にはそのディレクトリにHellotest.o<JOB_ID>
という名前で、中にHello keisan_master!!
という出力のファイルが現れているはずです。ここまでできていれば成功です。
keisan_masterのqsub
システムではデフォルト設定でこの標準出力ファイル・標準エラー出力ファイルが切り分けられています。
エラーが何も起きなかったときの標準エラー出力ファイルHellotest.e<JOBID>
には何もなくて0バイトの空ファイルになっているはずです。今回のテストではエラーは起きていないので空のはずです。
-M
にメールアドレスを指定すると、そのメールアドレスにジョブの結果が送信されるようになります(postfix連携でメール通知を設定している場合)。
ジョブの確認
上記のqsub
は計算処理をkeisan_masterにつながる計算ノードの空いているマシンに割り当てて自動実行させるためのコマンドです。このqsub
で計算をさせることを 「ジョブを投入する」 と言います。
qstatコマンド
投入されたジョブがどのマシンで動いているか、ジョブが終了したかを確認するためにはqstat
コマンドを使います。
$ qstat
Job ID Name User Time Use S Queue
------------------- ---------------- --------------- -------- - -----
9.keisan_master calc_order.sh sakakibara 02:16:39 R default
15.keisan_master Hellotest moriwaki 0 R default
-
Job ID
は先ほど出てきた、qsub
したときに返ってくるジョブのIDです。 -
Name
はqsub
オプションの-N
で付けた名前です。この名前をつけておくと便利ですので積極的に使いましょう。 -
User
は投入したユーザー。 -
Time Use
は処理開始からのCPUの累計計算時間。 -
S
はStatusで、R
が正常運行、E
はエラー発生、C
は終了処理中、Q
は投入可能なマシンが空いたら投入されるのを待っている状態、H
は予約されているとき(後述)などです。 -
Queue
はキューの種類です。これは投入するシェルスクリプトの#PBS -q default
で指定します。
qstat
コマンドで何も表示されないというのは、ご自身を含めて今は誰もkeisan_master上で計算ジョブを実行させていないということです。Hellotestはqsub
されてから5秒後くらいには実行が完了して消えるようになっています。
qstat
は他にも色々便利なオプションがあります。man qsub
とかman qstat
とかでマニュアルを確認してみてください。
詳細なジョブモニタリング
qstat -an1st
を実行すると
$ qstat -an1st
keisan_master:
Req'd Req'd Elap
Job ID Username Queue Jobname SessID NDS TSK Memory Time S Time
------------------ ----------- -------- ---------------- ------ ----- ------ --------- --------- - ---------
1485.keisan_master moriwaki default 3wae 26159 1 16 -- 72:00:00 R 00:12:49 keisan1/0-15
Job started on Fri Jun 01 at 18:41
1486.keisan_master moriwaki default 4elr 86283 1 16 -- 72:00:00 R 00:12:23 keisan2/0-15
Job started on Fri Jun 01 at 18:41
というように表示されます。上記qstat
コマンドと比べると右端にElapse Time(実際のジョブ作動時間)、計算ノード(上の例で言うとkeisan1, keisan2)、開始時間などの情報が増えています。こっちを使うことを推奨します。
ジョブの削除
ジョブを消したくなったときにはqdel <jobid>
で消すことができます。例えばジョブ番号25500を消したい場合はqdel 25500
と入力します。
ジョブ投入後の計算ノードの変更
「ジョブを投入したが、その指定ではQueue状態で待機中のままになっているため、別のgroupの空いている計算ノードにジョブを入れ直したい」という場合、以下の手順で解決できます。
-
qstat
でQ
状態(ジョブ投入待ち)になっているジョブ番号を確認する。以下ではその番号を99999
とする。 -
qalter
コマンドで投入待ちのジョブのプロパティを変更できる。qalter -l "nodes=xx:ppn=xx:yyy,walltime=72:00:00" 99999
のような形で実行する。 -
qstat -f 99999
でジョブのプロパティが変わっていることを確認する。 -
qhold 99999
としてH
(保留状態)にし、その後qrls 99999
で保留解除すると、ジョブが動き出す。
つまり、1行でつなげると
$ jobid=99999 && qalter -l "nodes=1:ppn=16:groupB,walltime=72:00:00" ${jobid} && qhold ${jobid} && qrls ${jobid}
のようになります。jobid
の番号やノードのプロパティを適宜変えて使ってください。
ジョブの予約
あるジョブAが終わったことを見計らって別のジョブBを実行させたいということがあると思います。このような場合はqsub
の-W
オプションを使って以下のようにやります。
$ qsub jobA.sh
18.keisan_master
$ qsub -W depend=afterany:18 jobB.sh
19.keisan_master
こんな感じでdepend=afterany:18.keisan_master
の部分にjobAでのJOBIDを入力します。このときqstat
では以下のように表示され処理待ちのHが映し出されます。
Job ID Name User Time Use S Queue
----------------- ---------------- --------------- -------- - -----
18.keisan_master jobA.sh moriwaki 0 R default
19.keisan_master jobB.sh moriwaki 0 H default
-
-W depend=
の後にはafterany
以外にも色々オプションがあります。詳しくは公式マニュアルで。afterany, afterok, afterとかは結構使うんじゃないかな? - すでに終了済みのジョブに対して
depend=afterany
をやろうとすると、qsub: submit error (Invalid Job Dependency)
と言われて投入できません。
ジョブへの引数渡し
コマンドラインでは、-v 変数1=値1,変数2=値2,...
というオプションを指定することで、qsub
する実行ファイルに変数を渡すこともできます。たとえば、実行ファイルの中で、実行するコマンドのコマンド引数を次々と変えてqsubしたいときは、以下のサンプルを参考にしてください。
#!/bin/sh
#PBS -l nodes=1:ppn=4,walltime=12:00:00
#PBS -q default
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
# Error if a variable VAR1 is not set
test $VAR1 || { echo "VAR1 is not set." ; exit 1 ; }
# run the environment module (keisan_master)
. /home/apps/Modules/init/profile.sh
module load hh-suite/3.3
hhblits -cpu 4 \
-i /home/moriwaki/2021/af2_atp_augumetation/pdb_unifasta/$VAR1.fasta \
-d /mnt/database/UniRef30_2021_06/UniRef30_2021_06 \
-oa3m /home/moriwaki/2021/af2_atp_augumetation/hhblits_every_seq/hhblits/$VAR1_out.a3m \
-n 3 -e 0.001 -maxseq 1000000 -realign_max 100000 -maxfilt 100000 -min_prefilter_hits 1000
そしてqsubするときに、
$ qsub -v VAR1=A999999 run_hhblits.sh
とすると、シェルスクリプトrun_hhblits.sh
の$VAR1
にA99999
という値が代入された状態でqsubすることができます。これは同じフォーマットを使って入力とするファイル名のみを変更して連続投入したいというときに便利です。
walltimeとqueueの種類の選択
#PBS -l walltime=24:00:00
とすると、ジョブ投入から24時間後に自動で強制終了するような設定になります。この上限時間については2つのキューで異なっており、この時間内であれば任意に時間を減らすことが可能です。
現在のところ、keisan_masterクラスタにはdefault
とweek
の2つのqueueを設定しています。walltimeの指定をしなければ最大 3日間 (72:00:00) 処理を続けることができるdefault queueに設定していますが、queueの種類はシェルスクリプトの中で
#!/bin/sh
#PBS -l nodes=1:ppn=4,walltime=168:00:00
#PBS -q week
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
...
とすることで変更することができます。week
キューは最大1週間(168時間) 動作させることができますが、初期値は24時間に設定してあります。
詳細はtorqueシステムのコマンドの1つqmgr -c "p s"
で見ることができます。
計算マシンの種類と使用するcore数の選択
nodesのところに計算ノード名を直接指定すると、明示的にその計算ノードに投入することができます。
#!/bin/sh
#PBS -l nodes=keisan1:ppn=16
#PBS -q default
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
...
を指定すると、keisan1マシンの16コアを確保して計算を実行するようになります。また、propertyを使った指定も可能で、keisan_master上でpbsnodes
を入力した時のpropertiesに出ている値を入力することでそのマシン属性を指定することができます。
#!/bin/sh
#PBS -l nodes=1:ppn=16:gpus=1:alphafold
#PBS -q default
また、実はqsub
するときに、ターミナル上から引数を指定することで上記の設定を追加(または上書き)することもできます。一例として
[moriwaki@hoge]$ qsub -l 'nodes=keisan2:ppn=16:alphafold' -q default run.sh
とすれば、そのノード設定・キュー設定で投入することができます。これも使い方によっては便利です。
「ジョブを投入したがQueue状態で待機中のままになっており、空いている計算ノードにジョブを入れ直したい」という場合、以下の手順で解決できるかもしれません。
-
qstat
でQ
状態(ジョブ投入待ち)になっているジョブ番号を確認する。以下ではその番号を99999
とする。 -
qalter
コマンドで投入待ちのジョブのプロパティを変更できる。qalter -l "nodes=xx:ppn=xx:yyy,walltime=72:00:00"
99999のような形で実行する。 -
qstat -f 99999
でジョブのプロパティが変わっていることを確認する -
qhold 99999
としてH
(保留状態)にし、その後qrls 99999
で保留解除すると、ジョブが動き出す
GPU数の指定
使用するgpu数の指定を行うことができます。例はこんな感じ(計算ノードをkeisan1に指定、コア数16コア、制限時間72時間の例)。
#!/bin/sh
#PBS -l nodes=keisan1:ppn=16:gpus=1,walltime=72:00:00
#PBS -q default
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
...
2機のGPUを持っている場合、#PBS -l gpus=2
のようにして最大2機までのGPUを指定することができます。gpus=1
として1機のみを指定した場合、GPUの様子を観察するコマンドnvidia-smi
では1台分しか見かけ上検出することができず、GPUのIDも0始まりになるので、コアな使い方をする人は要注意です。
標準出力と標準エラー出力の設定 (optional)
#!/bin/sh
#PBS -l nodes=1:ppn=1
#PBS -q default
#PBS -k oe
test $PBS_O_WORKDIR && cd $PBS_O_WORKDIR
...
このように#PBS -k oe
を書いておくと、ジョブの実行中でも標準出力と標準エラー出力がユーザーのディレクトリ上に現れるようになります。指定しない場合は、ジョブが終了したときに初めてユーザーのディレクトリ上に表示されるようになります。
PBS torqueシステムで使える便利な変数
ほとんどのPBS torqueシステムでデフォルトで使える変数の例
-
$PBS_JOBNAME
User specified jobname -
$PBS_O_WORKDIR
Job’s submission directory -
$PBS_TASKNUM
Number of tasks requested -
$PBS_O_HOME
Home directory of submitting user -
$PBS_MOMPORT
Active port for mom daemon -
$PBS_O_LOGNAME
name of submitting user -
$PBS_NODENUM
Node offset number -
$PBS_O_SHELL
Script shell -
$PBS_O_JOBID
Unique pbs job id -
$PBS_O_HOST
Host on which job script is currently running -
$PBS_QUEUE
Job queue -
$PBS_NODEFILE File
containg line delimted list on nodes allocated to the job -
$PBS_O_PATH
Path variable used to locate executables within job script