LoginSignup
6
5

OpenPBSクラスターを構築する【Ubuntu22.04編】

Posted at

本稿では、OpenPBSのクラスターをUbuntu 22.04 LTS上で構築する方法について述べる。

以下、Altair EngineeringのOpenPBSを、OpenPBSまたは単にPBSと呼ぶ。

OpenPBSの基本的な使い方については前回の記事を参照されたい。

概要

本稿では以下の内容を扱う。

  • PBSのインストール
  • PBSクラスターの構築
    • ノードの設定
    • キューの構築
  • MPIのインストール
  • フック(プラグイン)の作成・導入

UbuntuのバージョンはUbuntu Server 22.04.4 LTSを、Pythonのバージョンは3.11を使用する。

構成

  • サーバーノードを1つ
    • ホスト名はkanri
    • これはジョブの受付、クラスターの管理などを受け持つ。ジョブの計算もする。
    • 4コア
  • 計算ノードを1つ
    • ホスト名はcom1
    • これはジョブの計算を担う
    • 8コア

以下、本稿ではコマンドの先頭に記す%をプロンプトとし、場合によってはその前にどのホストでの実行かを示す@kanri@com1を付けることとする。

前準備

  • SSHの設定:それぞれのユーザーについて、各ノードで互いに自分の鍵認証でSSH接続できるようにしておく。
  • /homeディレクトリをNFSなどでノード間で共有している状態を仮定する。

/etc/hosts

/etc/hostsには各ノードで以下のように記述して、名前解決できるようにしておく。ここでループバックアドレス127.0.0.1localhost以外のホスト名が記述されていたら、それを削除する。

% cat /etc/hosts
127.0.0.1       localhost
192.168.0.11    kanri
192.168.0.12    com1

127.0.0.1 kanri127.0.0.1 com1などというアドレスが存在している場合、PBSサーバープロセスを起動できない問題が生じるので削除しておく(この行はUbuntuのインストール時に追加される)。

ポートの開放

ファイアーウォールを構成している場合は、15001番から15009番と17001番を開放する。

% sudo ufw allow 15001:15009/tcp
% sudo ufw allow 17001

本稿のテスト環境ではファイアーウォールを有効にせず進めるので、有効にする場合の詳しい情報については提供することができない。

インストール

パッケージマネージャーの更新

パッケージマネージャーを最新の状態にしておく。

% sudo apt update
% sudo apt upgrade -y

依存関係パッケージのインストール

ビルド時依存関係のパッケージをインストールする。

% sudo apt install gcc make libtool libhwloc-dev libx11-dev libxt-dev libedit-dev \
   libical-dev ncurses-dev perl tcl-dev tk-dev swig libexpat-dev libssl-dev \
   libxext-dev libxft-dev autoconf automake g++ python3.11 python3.11-dev \
   postgresql-contrib postgresql-server-dev-all

実行時依存関係のパッケージをインストールする。

% sudo apt install expat libedit2 postgresql python3.11 python3.11-dev \
  sendmail-bin sudo tcl tk libical3 postgresql-contrib postgresql-server-dev-all

ビルドはサーバーノードで行って、計算ノードではインストールするだけならば、計算ノードには後者があればよい。

OpenPBSのインストール

ソースコードをダウンロードして解凍する

GitHubのリリースページからソースコードのTarballをダウンロードする(現在のPBSの最新版は23.06.06)。

% wget https://github.com/openpbs/openpbs/archive/refs/tags/v23.06.06.tar.gz

ダウンロードしたファイルをtarコマンドで解凍して、そのディレクトリへ移動する。

% tar xvzf v23.06.06.tar.gz
% cd openpbs-23.06.06

パッチを当てる

システムのTclを使うように指示し、Python3.11でビルドできるようにするためのパッチを当てる。パッチは2つあり、以下の通りである。

--- m4/with_tcl.m4      2023-06-06 00:40:11.000000000 +0900
+++ m4/with_tcl.m4.patched      2024-03-07 23:03:58.144195644 +0900
@@ -82,10 +82,10 @@
   AC_SUBST(tk_version)
   AS_IF([test x$TCL_INCLUDE_SPEC = x],
     # Using developer installed tcl
-    [tcl_inc="-I$tcl_dir/include"]
-    [tcl_lib="$tcl_dir/lib/libtcl$TCL_VERSION.a $TCL_LIBS"]
-    [tk_inc="-I$tcl_dir/include"]
-    [tk_lib="$tcl_dir/lib/libtcl$TCL_VERSION.a $tcl_dir/lib/libtk$TK_VERSION.a $TK_LIBS"],
+#    [tcl_inc="-I$tcl_dir/include"]
+#    [tcl_lib="$tcl_dir/lib/libtcl$TCL_VERSION.a $TCL_LIBS"]
+#    [tk_inc="-I$tcl_dir/include"]
+#    [tk_lib="$tcl_dir/lib/libtcl$TCL_VERSION.a $tcl_dir/lib/libtk$TK_VERSION.a $TK_LIBS"],
     # Using system installed tcl
     [tcl_inc="$TCL_INCLUDE_SPEC"]
     [tcl_lib="$TCL_LIB_SPEC $TCL_LIBS"]
--- pbs_python_external.c       2023-06-05 15:40:11.000000000 +0000
+++ pbs_python_external.c.new   2024-03-08 05:48:52.773168993 +0000
@@ -54,7 +54,7 @@
 #ifdef PYTHON

 #include <pbs_python_private.h> /* private python file  */
-#include <eval.h>		/* For PyEval_EvalCode  */
+#include <ceval.h>		/* For PyEval_EvalCode  */
 #include <pythonrun.h>		/* For Py_SetPythonHome */
 #include <sys/types.h>
 #include <sys/stat.h>

前者のパッチファイルの名前をfirst.patch、後者のそれをsecond.patchと仮定しよう。カレントディレクトリで以下のコマンドを実行してパッチを適用する。

% patch m4/with_tcl.m4  < first.patch
% patch src/lib/Libpython/pbs_python_external.c < second.patch

このとき、必要なら--ignore-whitespaceオプションを付ける。

環境変数を準備する

Ubuntu 22.04の環境に合わせて、ビルドを通すために次の環境変数を設定する。

% export CFLAGS="-I/usr/include/tcl8.6"
% export LDFLAGS="-lm -ltk -ltcl"
% export PYTHON="/usr/bin/python3.11"

ビルド

インストール先は/opt/pbsとする。なお、sendmailコマンドの場所をtype sendmailで確認しておく。

authgen.shconfigureを実行して構成を行い、その後makeコマンドでビルドする。makeの並列数はCPUに合わせて任意に変更して欲しい。

% ./autogen.sh
% ./configure --prefix=/opt/pbs --with-sendmail=/usr/sbin/sendmail
% make -j8

インストール

ビルドが完了したら、各ノードでmake installコマンドを実行してPBSをインストールする。

@kanri % sudo make install
@com1 % sudo make install

以下のディレクトリが生成されて、中にファイルが配置されていればビルドは成功である。

% ls -1 /opt/pbs/
bin
etc
include
lib
libexec
sbin
share
unsupported

インストール後

pbs_postinstallスクリプト

PBSにはインストール後に実行しなければならないスクリプトpbs_postinstallが存在する。このスクリプトは/opt/pbs/libexecディレクトリに配置されているので次のコマンドでこのスクリプトを実行する。

@kanri % sudo /opt/pbs/libexec/pbs_postinstall
@com1 % sudo /opt/pbs/libexec/pbs_postinstall

以下のようなメッセージが表示されれば完了である。

% sudo /opt/pbs/libexec/pbs_postinstall
*** PBS Installation Summary
***
*** Postinstall script called as follows:
*** /opt/pbs/libexec/pbs_postinstall ''
***
*** No configuration file found.
*** Creating new configuration file: /etc/pbs.conf
*** Replacing /etc/pbs.conf with /etc/pbs.conf.23.06.06
*** /etc/pbs.conf has been created.
***
*** Registering PBS as a service.
update-rc.d: error: no runlevel symlinks to modify, aborting!
Synchronizing state of pbs.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable pbs
Created symlink /etc/systemd/system/multi-user.target.wants/pbs.service → /lib/systemd/system/pbs.service.
***
*** PBS_HOME is /var/spool/pbs
*** Creating new file /var/spool/pbs/pbs_environment
*** WARNING: TZ not set in /var/spool/pbs/pbs_environment
***
*** The PBS server has been installed in /opt/pbs/sbin.
*** The PBS scheduler has been installed in /opt/pbs/sbin.
***
*** The PBS communication agent has been installed in /opt/pbs/sbin.
***
*** The PBS MOM has been installed in /opt/pbs/sbin.
***
*** The PBS commands have been installed in /opt/pbs/bin.
***
*** End of /opt/pbs/libexec/pbs_postinstall

ここで、update-rc.d: error: no runlevel symlinks to modify, aborting!というエラーが出た場合には、以下のコマンドを実行して自動起動の設定をしておく。

% sudo update-rc.d pbs defaults

パーミッションの変更

qsubqstatなどのコマンドを一般ユーザーが使えるようにするために、特定の2つの実行ファイルに特殊なアクセス権限に変更しておく。

@kanri % sudo chmod 4755 /opt/pbs/sbin/pbs_iff /opt/pbs/sbin/pbs_rcp

パスを通す

環境変数を読み込む設定を行う。すべてのユーザーでPBSのコマンドを使えるように、/etc/bash.bashrcに記述を追加する。このコマンドはroot権限で実行する。

@kanri # echo "source /etc/profile.d/pbs.sh" >> /etc/bash.bashrc

クラスターの構成

インストール後スクリプトを実行すると/etc/pbs.conf/var/spool/pbsディレクトリなどが用意される。pbs.confには、そのノードの役割に応じた設定を記述する。

pbs.conf

サーバーノード

サーバーノードではサーバー、スケジューラー、コミュニケーターのデーモンを実行するのでそれぞれ、PBS_START_SERVERPBS_START_SCHEDPBS_START_COMMを値1に設定する。また、計算も実行するのでPBS_START_MOMは値1に設定する。

@kanri % cat /etc/pbs.conf
PBS_SERVER=kanri
PBS_START_SERVER=1
PBS_START_SCHED=1
PBS_START_COMM=1
PBS_START_MOM=1
PBS_EXEC=/opt/pbs
PBS_HOME=/var/spool/pbs
PBS_CORE_LIMIT=unlimited
PBS_SCP=/usr/bin/scp

計算ノード

計算ノードでは上の3つは実行する必要がないので値0に設定し、PBS_START_MOMの値を1に設定する。

@com1 % cat /etc/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

mom_priv/config

/homeディレクトリをNFSなどで共有している前提なので、ジョブの結果のファイルの転送にSCPではなくCPを使うようにPBSに指示する。具体的には/var/spool/pbs/mom_priv/configを以下のように記述する。

% sudo cat /var/spool/pbs/mom_priv/config
$restrict_user_maxsysid 999
$clienthost kanri
$usecp *:/home/ /home/
  • $clienthostには、サーバーノードのホスト名を記述する。

  • $usecpには、$usecp <hostname>:<source directory> <destination directory>のように記述する。上の設定例では全てのホストの/homeディレクトリ内の移動にCPを使うように指示している。詳細は参考文献1のページAG-441を参照。

pbs_environment

/var/spool/pbs/pbs_enviromentはジョブ実行時の環境変数を設定するファイルである。此のファイルにタイムゾーンの情報を追加する。

% sudo cat /var/spool/pbs/pbs_environment
PATH=/bin:/usr/bin
TZ="Asia/Tokyo"

デーモンの起動

ここで、PBSのデーモンを起動する。

@com1  % sudo /etc/init.d/pbs start
...
@kanri % sudo /etc/init.d/pbs start
Starting PBS
PBS Home directory /var/spool/pbs needs updating.
Running /opt/pbs/libexec/pbs_habitat to update it.
***
*** Setting default queue and resource limits.
***
cp: cannot stat '/usr/pgsql-14.11/lib/*': No such file or directory
cp: cannot stat '/usr/pgsql-14.11/lib/*': No such file or directory
cp: cannot stat '/usr/pgsql-14.11/share/timezonesets/*': No such file or directory
cp: cannot stat '/usr/pgsql-14.11/share/timezonesets/*': No such file or directory
cp: cannot stat '/usr/lib/postgresql/14/bin/pg_resetxlog': No such file or directory
*** End of /opt/pbs/libexec/pbs_habitat
Home directory /var/spool/pbs updated.
/opt/pbs/sbin/pbs_comm ready (pid=14344), Proxy Name:amphibole:17001, Threads:4
PBS comm
PBS mom
PBS sched
Connecting to PBS dataservice...connected to PBS dataservice@amphibole
PBS server

次のコマンドで、デーモンのプロセスIDを確認することができる。

% sudo /etc/init.d/pbs status
pbs_server is pid 14474
pbs_mom is pid 14356
pbs_sched is pid 14358
pbs_comm is 14344

管理者権限がないと以下のようにnot runningと表示されてしまうので注意。

% /etc/init.d/pbs status
pbs_server is not running
pbs_mom is pid 14356
pbs_sched is not running
pbs_comm is not running

この時点でqstatコマンドを実行してエラーが無いか確認しておこう。何も表示されなければ問題ない。

@kanri % qstat

次のようなメッセージが出る場合には、デーモンになにかのエラーが生じているので、 /var/spool/pbs/server_logs以下にあるログファイルを見るのがよいだろう(トラブルシューティングを参照)。

@kanri % qstat
Connection refused
qstat: cannot connect to server kanri (errno=15010)

ノードの設定をする

qmgrコマンド

qmgrコマンドを使ってPBSのノード構成を行う。このコマンドはroot権限が必要である。

@kanri % sudo su
@kanri # qmgr
Qmgr:

Qmgr:というプロンプトが表示され、インタラクティブにコマンドを実行して構成を行うことができる。

ここでは例えば、現在のサーバー設定を表示するにはprint serverコマンドを実行する。

Qmgr: print server
#
# Create queues and set their attributes.
#
#
# Create and define queue workq
#
create queue workq
set queue workq queue_type = Execution
set queue workq enabled = True
set queue workq started = True
#
# Set server attributes.
#
set server scheduling = True
set server default_queue = workq
set server log_events = 511
set server mailer = /usr/sbin/sendmail
set server mail_from = adm
set server query_other_jobs = True
set server resources_default.ncpus = 1
set server default_chunk.ncpus = 1
set server scheduler_iteration = 600
set server resv_enable = True
set server node_fail_requeue = 310
set server max_array_size = 10000
set server pbs_license_min = 0
set server pbs_license_max = 2147483647
set server pbs_license_linger_time = 31536000
set server eligible_time_enable = False
set server max_concurrent_provision = 5
set server max_job_sequence_id = 9999999

quitまたはqと入力することで、Qmgrを終了することができる。

ノードの構成

他のユーザーのジョブを問い合わせできるようにする。

Qmgr: set server query_other_jobs = True

flatuid属性を有効にしてもよい(これについては参考文献2のページUG-6を参照)。

Qmgr: set server flatuid = True

次に計算ノードの登録を行う。

Qmgr: create node com1

計算ノードの利用可能な並列数をここで設定することができる。

Qmgr: set node com1 resources_available.ncpus=8

ノードの構成を表示するにはprint nodeコマンドを使用する。

Qmgr: print node com1
#
# Create nodes and set their properties.
#
#
# Create and define node com1
#
create node com1
set node com1 state = free
set node com1 resources_available.arch = linux
set node com1 resources_available.host = com1
set node com1 resources_available.mem = 8060064kb
set node com1 resources_available.ncpus = 8
set node com1 resources_available.vnode = com1
set node com1 resv_enable = True

代わりにprint node @activeを使用してもよい。

使用されなくなったノードはdeleteコマンドで消すことができる。

Qmgr: delete node com1

登録されたノードはpbsnodesコマンドで確認することができる。

% pbsnodes -a
com1
     Mom = com1
     ntype = PBS
     state = free
     pcpus = 8
     resources_available.arch = linux
     resources_available.host = com1
     resources_available.mem = 8060064kb
     resources_available.ncpus = 8
     resources_available.vnode = com1
     resources_assigned.accelerator_memory = 0kb
     resources_assigned.hbmem = 0kb
     resources_assigned.mem = 0kb
     resources_assigned.naccelerators = 0
     resources_assigned.ncpus = 0
     resources_assigned.vmem = 0kb
     resv_enable = True
     sharing = default_shared
     license = l
     last_state_change_time = Fri Mar  8 00:19:31 2024
     last_used_time = Thu Mar  7 20:44:46 2024

キューを設定する

以下のようなQmgrコマンドを使用して、キューALLを構成する。

create queue ALL
Qmgr: create queue ALL
Qmgr: set queue ALL queue_type = Execution
Qmgr: set queue ALL Priority = 10
Qmgr: set queue ALL resources_default.ncpus = 12
Qmgr: set queue ALL resources_default.nodect = 2
Qmgr: set queue ALL resources_default.nodes =2
Qmgr: set queue ALL max_run_res.ncpus = [u:PBS_GENERIC=12]
Qmgr: set queue ALL enabled = True
Qmgr: set queue ALL started = True

このキューでは最大12コア(kanriの4コアとcom1の8コア)を使用するように構成している。最後に

Qmgr: set queue ALL enabled = True
Qmgr: set queue ALL started = True

の2つのコマンドを実行することで、キューがアクティブになる。

現在アクティブなキューについて、以下のコマンドで設定を表示することができる。

Qmgr: print queue @active
#
# Create queues and set their attributes.
#
#
# Create and define queue workq
#
create queue workq
set queue workq queue_type = Execution
set queue workq enabled = True
set queue workq started = True
#
# Create and define queue ALL
#
create queue ALL
set queue ALL queue_type = Execution
set queue ALL Priority = 10
set queue ALL resources_default.ncpus = 2
set queue ALL resources_default.nodect = 2
set queue ALL resources_default.nodes = 2
set queue ALL max_run_res.ncpus = [u:PBS_GENERIC=12]
set queue ALL enabled = True
set queue ALL started = True

MPIのインストール

すべての計算ノードにおいて、MPIライブラリをインストールすることで、分散メモリ並列計算の環境が整う。ここではOpenMPIを選択することにする(他のオプションとして、MPICHやIntelのoneAPI HPC Toolkitなどがある)。

sudo apt install openmpi-bin libopenmpi-dev

インストールはこれで完了。

OpenMPIの構成について調べてみる。

% ompi_info | grep "Configure command line"
  Configure command line: '--build=x86_64-linux-gnu' '--prefix=/usr' 
     '--includedir=${prefix}/include' '--mandir=${prefix}/share/man' 
     '--infodir=${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' 
     '--disable-option-checking' '--disable-silent-rules'
     '--libdir=${prefix}/lib/x86_64-linux-gnu' '--runstatedir=/run' 
     '--disable-maintainer-mode' '--disable-dependency-tracking' '--disable-silent-rules'
     '--disable-wrapper-runpath' '--with-package-string=Debian OpenMPI' '--with-verbs'
     '--with-libfabric' '--with-psm' '--with-psm2' '--with-ucx'
     '--with-pmix=/usr/lib/x86_64-linux-gnu/pmix2' 
     '--with-jdk-dir=/usr/lib/jvm/default-java' '--enable-mpi-java'
     '--enable-opal-btl-usnic-unit-tests' '--with-libevent=external' 
     '--with-hwloc=external' '--disable-silent-rules' '--enable-mpi-cxx'
     '--enable-ipv6' '--with-devel-headers' '--with-slurm' '--with-sge' 
     '--without-tm' '--sysconfdir=/etc/openmpi' 
     '--libdir=${prefix}/lib/x86_64-linux-gnu/openmpi/lib'
     '--includedir=${prefix}/lib/x86_64-linux-gnu/openmpi/include'

--without-tmが指定されている。理想的には--with-tm=/opt/pbsを指定してビルドしインストールするべきであるが、パッケージマネージャーのバイナリでもとりあえず問題なく動作するようだ。

ジョブを投入する

詳細は前回の記事「ジョブスケジューラーOpenPBS/PBS Proの使い方」を参照のこと。

以下のようなFortranのコードがあるとする。

program main
   use :: mpi_f08
   implicit none

   integer :: ierr, me, petot
   character(8) :: hostname

   call mpi_init(ierr)
   call mpi_comm_size(mpi_comm_world, petot, ierr)
   call mpi_comm_rank(mpi_comm_world, me, ierr)

   ierr = hostnm(hostname)

   print *, hostname, ":", me, '/', petot

   call mpi_finalize()

end program main

これをmpif90コマンドでコンパイルする。

% mpif90 ./main.f90 -o a.out

このコマンドで生成された実行ファイルa.outを次のようなジョブスクリプトsample.shを使って、ジョブをキューに投入する。

#!/bin/bash
### sample script for PBS
#PBS -q ALL
#PBS -N foo
#PBS -l select=1:ncpus=4:mpiprocs=4+1:ncpus=8:mpiprocs=8
#PBS -l walltime=60
#PBS -j oe

cd $PBS_O_WORKDIR
PETOT=$(wc -l < $PBS_NODEFILE)
/opt/pbs/bin/mpiexec -np $PETOT --hostfile $PBS_NODEFILE ./a.out
% qsub sample.sh

ジョブが完了すると、ディレクトリにfoo.oXが生成され、結果を見ることができる。

% cat foo.o*
 kanri   :           0 /          12
 kanri   :           3 /          12
 kanri   :           1 /          12
 kanri   :           2 /          12
 com1    :           5 /          12
 com1    :           6 /          12
 com1    :           7 /          12
 com1    :           9 /          12
 com1    :          10 /          12
 com1    :          11 /          12
 com1    :           8 /          12
 com1    :           4 /          12

フックを導入する

PBSではフック(Hook)と呼ばれるPythonで書かれたプラグインを導入することができる。

フックは、それが実行される段階で区別され、以下のような種類(フックタイプ)が存在する。

  • ジョブフック

    • 実行前フック(サーバーフック)

      • queuejob:ジョブが提出され、キューに入れられる前に実行される

      • modifyjob:キューに入れられた後、ジョブを変更する場合に実行される。

      • movejob:キューに入れられた後、ジョブを移動する場合に実行される。

      • runjob:サーバーがMoM(Machine Oriented Mini-server、計算ノードのデーモンのこと)にジョブを送信する前に実行される。

    • 実行フック(MoMフック)

      • execjob_begin
      • execjob_attach
      • execjob_prologue
      • execjob_launch
      • execjob_postsuspend
      • execjob_preresume
      • execjob_end
      • execjob_epilogue
      • execjob_preterm
  • 非ジョブフック

    • exechost_startup
    • exechost_periodic
    • resvsub
    • resv_end
    • provision
    • periodic

各フックタイプの実行タイミングの詳細については、参考文献3の第4章 "Hook Basics"を参照されたい。

以下では、ドキュメント(参考文献3の234ページ)に例として掲載されている「walltimeが指定されていないジョブをはじく」フックについて、その書き方とその導入方法について見ていこう。

queuejobフックの例

RequireWalltime.py

以下のような、PythonのコードRequireWalltime.pyがあるとする。

import pbs
import sys

eve = pbs.event()
job = eve.job

try:
    if job.Resource_List["walltime"] == None:
        eve.reject("Job has no walltime requested.")

except SystemExit:
    pass

except pbs.UnsetResourceNameError:
    eve.reject("Job has no walltime requested.")

このコードがフックRequreWalltimeの全体であり、次に各行で何をしているかを細かく説明する。

まず、ヘッダーの2行でpbssysモジュールをインポートしている。

その後、pbsの関数event()をコールして結果を変数eveに代入し、さらにeveのコンポーネントjobを変数jobに代入している。

次のtry:セクションでは、条件式job.Resource_List["walltime"] == Noneを評価する。ここで真(ジョブスクリプトにwalltimeを指定しなかった)ならば、関数e.reject()をコールしてジョブを拒否(リジェクト)し、偽ならばなにもしない。

もしj.Resource_List["walltime"]がセットされていない場合には、例外pbs.UnsetResourceNameErrorが投げられて、最後の2行が実行されてジョブは拒否される。

フックのスクリプトでは、拒否されずにプログラム終端に来た場合は、受理(アクセプト)されたものとして扱われる。

pbs.event().job.Resource_Listのオブジェクトには、ジョブスクリプトのヘッダー#PBSで指示された様々な値が格納されている。詳しくは参考文献3を参照して欲しい。

なお、pbs.event().accept()pbs.event().reject()はどちらも、SystemExit例外を投げてフックの実行を終了する。引数の無いtry exceptはすべての例外をキャッチするが、フックの内容自体がtry exceptである場合には、SystemExitを通常に発生するものとして扱うために、次のコードを追加するべきである。

except SystemExit:
   pass

ただし既存のコードに対して、特定の例外のみをキャッチする場合は、これを追加する必要はない。

フックの導入

フックの導入にはqmgrコマンドを使用するが、これを実行するには管理者権限が必要である。

% sudo qmgr -c 'create hook RequireWalltime event=queuejob'
% sudo qmgr -c 'import hook RequireWalltime application/x-python default RequireWalltime.py'
% sudo /etc/init.d/pbs restart

まず最初のコマンドで、RequireWalltimeという名前のフックオブジェクト(この時点では空のオブジェクト)を作成している。このときフックのevent属性をqueuejobに指定している。

次のコマンドで、先に作成したフックオブジェクトに対して実際にPythonコードを読み込ませている。ここでdefaultとは文字のエンコードを指定しており、他にbase64を指定することもできる。コマンドの最後にPythonコードのファイル名を指定する。

フックを導入した後はデーモンを再起動して変更を反映させる必要がある。この例ではフックタイプがqueuejob(ジョブの提出時に実行される)なので、サーバーノードだけでよい。

フックの削除

フックの削除は、以下のようにqmgrのコマンドを実行する。その後、デーモンを再起動する。

% sudo qmgr -c 'delete hook RequireWalltime'
% sudo /etc/init.d/pbs restart

トラブルシューティング

Dataserviceがすぐ終了してしまう

PBSのPostgreSQLのプロセスが起動していない場合は、サーバー(PBS_SERVERデーモン)の正常な起動に失敗している。

% ps aux | grep '^postgres' | grep pbs
postgres    1578  0.0  0.3 230412 28672 ?        Ss   15:46   0:00 /usr/lib/postgresql/14/bin/postgres -D /var/spool/pbs/datastore -p 15007
postgres    1722  0.0  0.2 232828 20060 ?        Ss   15:46   0:00 postgres: postgres pbs_datastore 

上の2つのプロセスが起動しているかを調べるとよい。

PBSのデータサービスが正しく起動しない問題は、デーモンの初回の起動に/etc/init.d/pbs startではなく、systemctl start pbsとしてしまった場合や、/etc/hosts127.0.0.1 kanriなどと記述された状態でpbs_postinstallを実行した場合に生じるようだ(経験的に)。この状態では、/var/spool/pbs以下のなにかのファイルが正しく生成されないためか、PBSサーバーの起動に失敗する。

これに対する処方は、/var/spool/pbs以下を一旦削除し、上記の点を修正した上でpbs_postinstallスクリプトを再度実行することである。その後、改めて/etc/init.d/pbs startを実行する。もっと良い解決策があるかもしれないが、これについてはわからない。

あとがき

本稿ではソースコードからビルドしてインストールする方法を紹介したが、Ubuntu 20.04ではOpenPBSのバイナリが提供されているらしいので、そちらを使うほうがやや楽ではある。

OpenPBSのコミュニティ掲示板もあるようなので、クラスターの構成で困った場合は参照するとよいだろう。

参考文献

Altair Community - Documentationより

  1. "Altair PBS Professional 2022.1 - Administrator's Guide"

  2. "Altair PBS Professional 2024.1 - User's Guide"

  3. "Altair PBS Professional 2021.1.3 - Plugins (Hooks) Guide"

その他のウェブサイト・ページ

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

5. ジョブスケジューラPBSProでGPU計算クラスタを組みAIを効率的に学習させる方法 (前編)

6. ジョブスケジューラPBSProでGPU計算クラスタを組みAIを効率的に学習させる方法 (後編)

  • この記事はGPUを計算リソースとしてジョブスケジューリングする方法について詳しい。
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5