LSF(ジョブスケジューラ)

能書き

大学院生になったら、理論研のクラスタを使えるようになります。
クラスタというのは幾つもの計算機が繋がった、いわゆる「スーパーコンピュータ」の一種です。
と言っても情報リテラシーの授業で使った「dahlman」などのサーバと基本的には同じもので、 ファイルを転送し、コンパイルを行う所までは通常通りです。 そのままプログラムを実行することも出来ます。
が、それでは「数」というクラスタの能力を活用できません。 本格的に計算をする場合は「LSF」という管理ツールを使いましょう。
2014年度現在は「LSF」のフリー版である「Lava」を使用している。

用語集

クラスタ:一つの「親」計算機(サーバ)に複数の「子」計算機がつながったカタマリのこと。
ホスト・ノード:クラスターを構成する1つ1つの計算機
ジョブ:「プログラムの実行」という1まとまりの処理
コア数:CPUの数のこと。LSFでは基本的に、1つのジョブに対し1つのコアが必要(占有される)。
走っている・走らせる:実行中・実行させる
ジョブを投げる:LSFを使って、コアにジョブを割り当てること
LSFの使い方

LSFのコマンド

ジョブを投げる
 $ bsub [-m ホスト名] [-J ジョブ名] [-n 並列数] [-o 出力ファイル名] コマンド
ホストの情報を見る
 $ bhosts
ジョブの情報を見る[他のユーザーを含める]
 $ bjobs [-u all]
ジョブを強制終了する
 $ bkill ジョブID

解説

まず、
 $ bhosts
と打ち込んでみましょう。
 HOST_NAME          STATUS       JL/U    MAX  NJOBS    RUN  SSUSP  USUSP    RSV 
riron01             ok              -     16      0      0      0      0      0
riron02             ok              -     16      1      1      0      0      0
riron03             closed          -     16     16     16      0      0      0
riron04             ok              -     16      4      4      0      0      0
このようなものが表示されます。一番上にあるのが今、自分がいるホストの名前です(ここでは'riron01')。 その下に並んでいるのが、「子」のホストです。 'MAX'というのはCPUの数に対応し、その右の'RUN'などは使用中のCPU数です。 この例の場合、4つの計算機が繋がっていて、それぞれCPUが16個ずつ、合計64個のCPUがあり、 そのうち21個が使用中で残りが使用可能、ただし'riron03'は全てのCPUが使用中、 ということが読み取れます。

 $ bjobs -u all
で、誰のジョブがどこでいくつ走っているかが分かります。
細かい説明は省略。

実行(jobを投げる)

いつも打ち込んでいる実行コマンドの前に、bsubをつけて
$ bsub ./test.exe
のようにすると、jobを「投げる」ことが出来ます。
どのホストに投げるかは、LSFが勝手に判断します。 自分で決めたい場合は、
$ bsub -m ホスト名 ./test.exe
のように指定しましょう。
他のユーザーの邪魔にならないように気を付けて下さい。
bjobsやbhostsで、自分のjobが走っていることを確かめましょう。
同時にいくつものjobを投げることが出来ます。logoutしても大丈夫です。

実行(上級編)

・ジョブ名を指定する
$ bsub -J p80_L256 ./test.exe
のようにすると、jobをに名前を指定することが出来ます。
指定した名前は、'bjobs'コマンドで表示されます。実行時パラメータを名前にすると良いでしょう。
具体的には、'bkill'をするときに役立ちます。

・並列プログラムを実行する
並列プログラムを実行する際は特別なオプションを付ける必要があります。
$ bsub -n 4 env OMP_NUM_THREADS=4 MKL_NUM_THREADS=4 ./parallel.exe
'-n'オプションは、LSFが並列ジョブを管理するためのものです。'env OMP...'は実際に使用するCPU数を指定しています。互いに独立なパラメータですが、同時に同じ値で設定する必要があります。
一般に何も設定をせずに並列プログラムを投げてしまうと、LSFでの見かけ上は1CPUしか占有していないように見えて、実際には全てのCPUリソースを食い尽くしている、ということになってしまいます。
自分専用で、わかって使っているのであればおそらく実害はありませんが、一般にクラスターは他人と共有するものなので、ジョブ管理には気をつける必要があります。

・出力先を指定する
LSFを使うと、いつもは画面に表示されるものが表示されなくなりますが
$ bsub -o output.txt ./test.exe
のように指定しておくと、プログラム終了時に『output.txt』というファイルに書き込んで(書き足して)くれます。
常に書き出したい場合は、エイリアスを使うと便利です。具体的には'˜/.bash_profile'に
alias bsub='bsub -o output.txt'
という1行を書き加えておくと、毎回'-o'オプションを指定する必要がなくなります。

管理

 実行時パラメータを間違えた場合や、負荷(メモリ使用量)が大きすぎた場合は停止させましょう。
 通常であれば[Ctrl-C]で停止できますが、LSFで投げたジョブはLSFで止めることになります。
・ジョブIDを調べる
$ bjobs
JOBID   USER    STAT  QUEUE      FROM_HOST   EXEC_HOST   JOB_NAME   SUBMIT_TIME
141421  koba    RUN   normal     riron01     riron02     20P3-5     Nov 11 11:11
173205  koba    RUN   normal     riron01     riron03     20P6-8     Nov 11 12:00
まずは止めたいジョブの『JOBID』を調べます。
『top』コマンドで出てくる「プロセスID」とは別なので注意。
きちんと'JOB_NAME'を付けていれば判別しやすい。

・ジョブを停止する
$ bkill 173205
止めたいジョブのIDが分かったら、『bkill』コマンドで停止させます。
他の人のジョブを止めることは出来ません。

おまけ:リモートtop

UNIX上でCPU、メモリの使用率を見るには
$ top
というコマンドを使いますが、これだと現在のノードしか見ることができません。
そこで、
$ /home/tmp/rtop
名前、場所は例です。実物は私に聞くか、自分で探して下さい。
というコマンドを用意しました。これを実行すると、
<host>      <CPU[core] total:16>             <Memory[.=4GB] total:32,64,or128>
riron01     .......:.......:.......:.......: 0...:...
riron02     =1.....:.......:.......:.......: 0...:...
riron03     =1=2=3=4.......:.......:.......: 44..:....:....:.
riron04     .......:.......:.......:.......: 0...:....:....:....:....:....:..

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
<riron02>
15523 koba      39  19 60272 5452 3544 R 98.3  0.0  23144:18 single.exe
<riron03>
27329 koba      39  19 2404m 2.3g 1140 R 395.0 12.5   2500:44 parallel.exe
のように、全ノードのリソース使用率を可視化してくれます。

他の人の使用率を見て、互いに譲り合うように使いましょう。

おまけ2:dfコマンド

ディスクの使用率を見るには
$ df -h
というコマンドを使います。
経験上、「急に遅くなった」「急に結果のファイルが出なくなった」というトラブルはディスクが一杯になったことが原因の場合が多いです。
ディスクが一杯になると利用者全員に迷惑を掛けるので、たまに確認しながら使いましょう。 自分のデータ(出力ファイル)がどれくらいのサイズかを把握しておくことも重要です。
screenの使い方

能書き

UNIXコマンド「screen」というものがあります。
1つの画面で(仮想的な)ターミナルをたくさん開きっぱなしにするためのコマンドです。
サーバとの接続が切れても画面出力やコマンド履歴がそのまま残るので、とりあえず使うと便利です。
サーバ自体がシャットダウンしたら、当然全て消えます。
ジョブ管理機能はありませんが、自分のPCで実行するのと同じように使えるので便利です。
ジョブ管理してくれないので、使いすぎないよう注意が必要です。

screenコマンド

新しく起動してscreenに入る
 $ screen [-S 名前]
起動済みのscreenを表示
 $ screen -ls
起動済みのscreenに入る
 $ screen -r [名前]
screenから抜ける
 Ctrl-a d
controlキーを押しながらaキーを押し、その後dキーを押す、という意味

新しいウインドウ
 Ctrl-a c
ウインドウ閉じる
 $ exit
普通にターミナルを閉じる操作。Ctrl-dでも。全てのウインドウを閉じると、screenが終了します。

ウインドウ一覧
 Ctrl-a "
次のウインドウ
 Ctrl-a n
前のウインドウ
 Ctrl-a p
指定した番号(たとえば3)のウインドウ
 Ctrl-a 3

バッファスクロール
 Ctrl-a ESC
でコピーモードにし、矢印キー、Ctrl-bなどでバッファをさかのぼる。

設定変更

『˜/.screenrc』というファイルを作り、以下の内容を書き込みます。
# .screenrc for K. Kobayashi 190220
defflow off
startup_message off
altscreen on
defscrollback 1000
deflogin off

term screen-256color
termcapinfo xterm-256color 'Co#256:pa#32767:'
hardstatus alwayslastline '%{= kw}%02c:%s %{= .y}%H %L=%{= .c}%-w%46>%{= .r}%n %t*%{= .c}%+w%-16=%{= .y}[%l]'

# screen escape key bind: ctrl+S
escape ^Ss
# screen list key bind: ctrl+S w
bind w windowlist -b
bind ^w windowlist -b

# enable .bash_profile
shell -$SHELL

この設定を使うと、
 Ctrl-a のところが Ctrl-s になる
Crtl-aは「カーソルを先頭に移動」に使うので、変更しないと不便です。Crtl-sは元々「画面がフリーズする」という地雷機能なので安心。

ウインドウ一覧が
 Ctrl-s w
になる(押しやすい)など、細かい工夫があります。
詳しい知人の話や、ネットに落ちてるものなどを参考にしました。興味があれば自分で工夫しましょう。