LoginSignup
2
1

More than 3 years have passed since last update.

Univa Grid EngineからPBS Torqueに移行するときに工夫が必要なこと

Last updated at Posted at 2020-03-03

まずはこちらを参照してください→ SGE用スクリプトファイルをPBS用に書き換える方法。本記事ではこちらで扱われていない内容を記します。

アレイジョブをqdelする

PBSではアレイジョブは1234[]といったjob IDがつきます。これを削除するには、bashなどがパス名展開して余計なことをしないようqdel "1234[]"とダブル(orシングル)クォーテーションで囲む必要があります。qholdなどのコマンドを実行する際にも同様です。

qsubを実行したディレクトリをカレントディレクトリにする(が、直接実行もいけるようにする)

UGEでは$# -cwdで済んでいましたが、PBSではこれが使えないので、スクリプトの頭のほうでcd ${PBS_O_WORKDIR}します。しかしそれだとPBSを使わずに直接実行した際にはcd (空文字列)が評価されてしまいます。単純に以下で回避しましょう。

cd "${PBS_O_WORKDIR:-$(pwd)}"

蛇足ですが、PBSのアレイジョブで実行するスクリプトを直接実行もできるようにする際にも同様のテクニックが便利です。すなわち、input/file1 ... input/file100まで処理したいファイルがあるとき、以下のようにするとアレイジョブではすべてのファイルを処理し、直接実行すると1番目のファイルだけを単一プロセスで処理するようにできます。

find input/ -type f | sort | awk "NR==${PBS_ARRAY_INDEX:-1}"

JOBIDやARRAYIDを付加してログを出力する

UGEでは以下のようqsubへの引数を書くことで、ログファイル名を一意に定めることができました。また、少々ややこしいことにスクリプト内では$SGE_TASK_IDでアレイジョブの何番目かを取ってくる仕様でした。

#$ -o log/stdout_$HOSTNAME_$JOB_ID_$TASK_ID
#$ -e log/stderr_$HOSTNAME_$JOB_ID_$TASK_ID

PBSを使用する際、スクリプト内では$SGE_TASK_IDの代わりに$PBS_ARRAY_INDEXを使うことができます。しかし$JOB_ID$TASK_IDに相当するものがありません。

そこで代替策としては、実行するスクリプトの内容をすべて{}でグループコマンド化し、まるごと標準出力と標準エラー出力をリダイレクトしてやる手があります(もっといい方法があったら教えてください!)。

#!/bin/bash
#PBS -S /bin/bash
#PBS -N demojob
#PBS -V
#PBS -o /dev/null
#PBS -e /dev/null
#PBS -J 1-4

cd "${PBS_O_WORKDIR:-$(pwd)}"
{
    echo hoge
    echo fuga
    python nonexistent.py
}&>log/$(date +"%Y%m%d%H%M%S")_"${PBS_JOBNAME}_${PBS_JOBID:--$$}"

このようにすると以下のログ出力が得られます。cdはグループに入る前に実行する必要があることに注意してください。ファイル名にはついでに日時も付加してあります。なお、PBSを経由しないで実行するときのために$PBS_JOBIDがなければプロセスIDが入るようにしてあります。

log/20200101123456_demojob_1234[4].hostname
hoge
fuga
python: can't open file 'nonexistent.py': [Errno 2] No such file or directory

スクリプトに引数を与える際の留意点

UGEではqsub myscript.sh myargとするだけでした。PBSではqsub -- $HOME/mydir/myscript.sh myargとすれば与えることができます。このときは絶対パスでスクリプトを指定する必要があることに注意してください。しかし、これをするとスクリプト本体内で#PBS ...と指定しているものが無効になってしまいます。たとえば#PBS -Vも無効になりますから、PATHの設定が消えてしまいますし、#PBS -J ...も消えてアレイジョブになりません(このトレードオフを解消する方法をご存じの方はぜひ教えてください!)。

いまのところの対応策は
1. スクリプト内にqsubへの引数を書くのをやめて、qsub -V -J 1-4 -- $HOME/mydir/myscript.sh myargなど直接qsubの引数にする
2. スクリプトに引数を渡すことをあきらめて、qsub実行前にexport MYVAR=foobarなど環境変数を設定したうえで単にqsub myscript.shして、スクリプト内で環境変数を読み取る。コマンドがすっきりするので個人的にはこちらが好みです。

ジョブ一つあたりのCPU数を指定する

上記記事で扱われている内容なので冗長ですが、よく使うので書いておきます。一つのジョブが10CPUを使うときにUGEでは#$ -pe make 10など指定したところ、PBSでは#PBS -l select=10としてください。#PBS -l select=10:mem=10GBなら10CPUとメモリ10GBを確保します。

スクリプトひな形

ここまでの内容を合わせて、スクリプトのひな型はこんな感じになります。環境変数による切り替えの例としてDRYRUNが空でなければ実際の処理をスキップするようにしてあります。Queueの設定などはそれぞれの環境に合わせて行ってください。

#!/bin/bash
#PBS -S /bin/bash
#PBS -N demojob
#PBS -o /dev/null
#PBS -e /dev/null
#PBS -V
#PBS -J 1-4

cd "${PBS_O_WORKDIR:-$(pwd)}"
{
    INPUTFILE=$(find input/ -type f | sort | awk "NR==${PBS_ARRAY_INDEX:-1}")
    echo "Executing something for ${INPUTFILE}"

    if [ -n "${DRYRUN}" ]; then
        echo "----Dry run flag is set... skipping execution"
    else
        some_command_you_want_to_run "${INPUTFILE}"
    fi

    echo "----Done"
}&>log/$(date +"%Y%m%d%H%M%S")_"${PBS_JOBNAME}_${PBS_JOBID:--$$}"
2
1
1

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
2
1