ATLAS日本基礎ネットワーク LCGミドルウエアトレーニングコース
ここでの目標
グリッドは全体で一つの仮想的な計算機と考えることが出来ます。しかしそれぞれのサイトは固有の資源、ハードウエア、OS、ソフトウエア等で構成されています。それ故、共通の言語(Job Description Language, JDL)で書かれたジョブリクエストをそれぞれのサイトの固有の制御情報に変換してジョブを実行させることになります。
JDLに使われる言語はClassAd (Classified Advertizement)言語というCondorプロジェクト(計算機クラスター制御のプロジェクト)で開発されたものを元にしています。ユーザはジョブをこのClassAdで記述することになります。
ClassAdで書かれたジョブ要求は、リソースブローカ(RB)に問い合わせることにより、そこで実行が可能かどうかを確かめます。このときにランクをつけ、最もランクの高いところが最も実行に適しているということで、そのリソースブローカが管理するComputing Element(CE)にジョブ要求が渡されます。
ジョブ要求にはいろいろな条件を付けることが出来ます。CPUの速さが何GHz以上だとか、もちろんCPUの種類が何だとか、物理メモリーサイズが何MB以上だとか、あるいはOSがLinuxでディストリビューションはRHじゃないとだめとか。もちろんAtlasソフトウエアがインストールされていることなども条件になります。
RBが適切であると判定したCEにジョブが渡されますが、CEはさらに自分の傘下のワーカーノード(WN)にジョブを送ります。実際のジョブはWN上で実行されます。
ジョブが投入される場所が決まったら、次に実行するプログラムを指定し、ジョブが実行できるだけの入力データの用意をする必要があります。
実行可能プログラムは元々OSやディストリビューションについてきているものでもインストール済みのソフトウエアでも、ユーザが自分で作ったものであってもその環境で動作するものであれば何でも構いません。この場合、ユーザのプログラムはそれが起動されるまでに適切な場所にインストールされなければなりません。これもジョブの一部として実行可能です。また、単一のイメージファイルであれば他の入力データファイルと同様にジョブ要求の中に記述することも可能です。
入力データの用意の仕方には主に二つの方法があります。ジョブ投入を行うローカルな場所にあるファイルをジョブ実行の前にグリッドジョブ投入の仕組みを使って転送する方法です。これはそのサイズがそれほど大きくないときに使用します。この方法で送られるファイルのセットをInputSandboxと呼びます。サイズの大きなファイルを入力として使う場合はカタログからローカルコピーを作ってからジョブを起動します。カタログから取ってくるデータファイルをInputDataとして記述することにより、そのデータが存在するSEの近くのCEが選ばれることになります。実際のローカルコピーの作成はジョブのステップの一部として別途記述する必要があります。
実行結果は標準出力、標準エラー出力も含めてファイルとして作られます。それ故、それらを回収する必要があります。入力データの場合と同様に、ファイルのセット(OutputSandboxと呼ばれる)としてジョブを投入したUIに戻す方法と、カタログに登録し実体をコピーしてどこからでも見えるようにする方法です。前者はファイルサイズが小さいとき、後者はファイルサイズが大きいときに使われるのが一般的ですが、小さいファイルをカタログすることも出来ます。あまり大きなファイルをOutputSandboxに載せることは出来ません。
JDLの言語であるClassAdは単純な文法を持っています。
名前=値;
という表現の並びで構成されます。最後のセミコロンを忘れずに。
コメントは#で始まるか
# この部分はコメント
C++のコメントの書式を用います。
// この部分はコメント /* この部分もコメント。 複数行にまたがることが出来る。*/
JDLファイルには必ず含まれていなければならない文があります。
Executable = 走らせるコマンド; StdOutput = 出力ファイル名; StdError = エラー出力ファイル名;
です。走らせるべきコマンドと、それが使用するであろう標準出力、標準エラー出力をリダイレクトするファイルです。これらの出力ファイルは当然回収されることを想定しています。例文としてはhostname.jdlとして次を編集しましょう。
Executable = "/bin/hostname"; StdOutput = "std.out"; StdError = "std.err";
このままでは出力が回収できません。ジョブはUIノードからRBノードを経由してWNノードに渡されます。WN上にstd.outやstd.errというファイルが出来ます。これらをUIノードまで戻してもらうためにOutputSandboxという文を記述します。
上のファイルhostname.jdlに次の行を追加します。
OutputSandbox = { "std.out","std.err" };
Executableで指定したコマンドの実行が完了したときにWNにあるこれらのファイルをUIまで転送してくれます。
これで、簡単ですがジョブを一つ記述しました。
次に、このJDLファイルを使ってジョブが走ることの出来るサイトを調べることにします。JDLの役割は、ジョブそのものの記述でもありますが、そのジョブをグリッド上のどこに投げるのが最適かを判定する情報としての役割もあります。マッチメーキング(お見合い?)と呼びますが、各地のRBに問い合わせて、そのジョブが走る条件を満たしているかどうか、どのくらい適切かを判断します。
$ glite-wms-job-list-match -a hostname.jdl
Selected Virtual Organisation name (from --vo option): atlas_j Connecting to host dg03.cc.kek.jp, port 7772
*************************************************************************** COMPUTING ELEMENT IDs LIST The following CE(s) matching your job requirements have been found:
*CEId* dg01.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j gridtb02.icepp.jp:2119/jobmanager-lcgpbs-atlas_j lcg009.cc.kek.jp:2119/jobmanager-lcglsf-atlas_j ***************************************************************************
edg-job-list-matchコマンドは文字通り、マッチするCEをリストします。--vo atlas_j オプションでVOを指定しています。
VOのオプションによる設定は面倒ですが、VOMSへ登録されていない場合は必要です。
このジョブが実行可能なCEがいくつかあることがわかりました。
次に、実際にジョブを投入しましょう。
$ glite-wms-job-submit -a -o jobid hostname.jdl
Selected Virtual Organisation name (from --vo option): atlas_j Connecting to host dg03.cc.kek.jp, port 7772 Logging to host dg03.cc.kek.jp, port 9002
================================ edg-job-submit Success ===================================== The job has been successfully submitted to the Network Server. Use edg-job-status command to check job current status. Your job identifier (edg_jobId) is:
- https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
The edg_jobId has been saved in the following file: /home/sakamoto/tutorial/jobid =============================================================================================
ジョブは無事に投入できました。実際にジョブを受け取ったRBはdg03.cc.kek.jpです。そこでhttps://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULgという名前が付けられました。これ以後、このジョブはこの名前で参照されます。とてもじゃないが覚えきれるものではないので-oオプションを使ってファイルにこの名前を書き出しました。jobidという名前のファイルがローカルに出来ています。
$ cat jobid ###Submitted Job Ids### https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg
これでグリッドジョブは投げられました。ジョブは次のような経過を経て完了に至ります。
これ以外にも
という状態を取り得ます。
実際に先ほど投げたジョブがどうなっているか見てみましょう。
$ glite-wms-job-status -i jobid
************************************************************* BOOKKEEPING INFORMATION:
Status info for the Job : https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg Current Status: Done (Success) Exit code: 0 Status Reason: Job terminated successfully Destination: dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j reached on: Wed Dec 14 03:21:33 2005 *************************************************************
説明をしている間に十分時間が経ったので完了しております。
ジョブがDone状態になったら出力ファイルを取り寄せることが出来ます。
$ glite-wms-job-output -i jobid
Retrieving files from host: dg03.cc.kek.jp ( for https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg )
********************************************************************************* JOB GET OUTPUT OUTCOME
Output sandbox files for the job: - https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg have been successfully retrieved and stored in the directory: /tmp/jobOutput/sakamoto_3Cr_DwtAbSYSdLVEUPnULg
*********************************************************************************
ここにあるように、/tmp/jobOutputの下にディレクトリsakamoto_*が出来て、その中にOutputSandboxに書かれたファイルが置かれています。
内容を確認してみましょう。
$ ls -l /tmp/jobOutput/sakamoto* total 4 -rw-r--r-- 1 sakamoto jst 0 Dec 14 06:53 std.err -rw-r--r-- 1 sakamoto jst 16 Dec 14 06:53 std.out
ちゃんとstd.outとstd.errが出来ています。std.errのサイズが0なので、stderrへは何も書かれなかったことがわかります。
std.outの内容を確認しましょう。
$ cat /tmp/jobOutput/sakamoto_3Cr_DwtAbSYSdLVEUPnULg/std.out wn35.kekgrid.jp
wn35.kekgrid.jpと表示されました。/bin/hostnameの出力ですが、wn35.kekgrid.jpで実行されたことがわかります。(このホストアドレスはKEKのプライベートネットワークのものです)
ジョブ出力を取り出した後なので
$ glite-wms-job-status -i jobid
************************************************************* BOOKKEEPING INFORMATION:
Status info for the Job : https://dg03.cc.kek.jp:9000/3Cr_DwtAbSYSdLVEUPnULg Current Status: Cleared Status Reason: user retrieved output sandbox Destination: dg06.cc.kek.jp:2119/jobmanager-lcgpbs-atlas_j reached on: Wed Dec 14 06:53:44 2005 *************************************************************
という結果になります。
必要がなければUI上のファイルも消去します。
$ rm -rf /tmp/jobOutput/sakamoto*
作業場所に作ってしまったjobidというファイルも消しておきましょう。
$ rm jobid
実際のジョブでは、いろいろな環境変数を設定したり、ジョブステップを分けて段階毎に処理を行うようにします。そのため、実行イメージとしてはジョブスクリプトを走らせることにするのが一般的です。
シェルスクリプトを走らせるJDLを書いておきましょう。testenv.shというスクリプトファイルを走らせることにします。testenv.jdlというファイルを作ります。
[ Executable = "/bin/sh"; Arguments = "testenv.sh"; StdOutput = "std.out"; StdError = "std.err"; InputSandbox = {"testenv.sh"}; OutputSandbox = {"std.out","std.err"}; ]
JDLの文法に従い、ここではジョブ範囲を[]で囲ってあります。
実行可能イメージとして/bin/shを選びました。それに対し、引数を与えます。これがtestenv.shというシェルスクリプトと言うことになります。出力は同じままにしておきます。このtestenv.shはユーザがUI上に用意するものなので、WNに送る必要があります。それ故、InputSandbox文を追加しました。
次にこのtestenv.shを用意しなければなりません。実際には任意のスクリプトを書けばよいのですが、ここでは実際にWNの環境がどんなものかを調べるために次のようなものを書いてみます。
#!/bin/sh echo "Current working directory --" pwd echo "Contents of this directory --" ls -al echo "Contents of /--" ls -l / echo "Contents of /opt--" ls -l /opt echo "Contents of /opt/exp_soft--" ls -l /opt/exp_soft echo "Contents of /opt/exp_soft/atlas_j--" ls -l /opt/exp_soft/atlas_j echo "df--" /bin/df echo "gcc--" /usr/bin/which gcc echo "gcc vresion--" gcc --version echo "environments--" /usr/bin/printenv
それぞれの行の意味は自明でしょう。/opt/exp_softを見ているのは、実験固有のソフトウエアのインストール場所がVO毎に設定されるからです。/opt/exp_soft/atlas_jの下に、athena関係などのソフトウエアがインストールされているはずです。それを確認しています。
これ自身実行できるようにモードを変えておきましょう。
$ chmod 755 testenv.sh
試しにローカルに走らせてみてください。問題ないでしょうか。
$ ./testenv.sh
もし、綴り間違いなどがあれば訂正しておきます。
これでジョブの用意が出来ました。先ほどと同様にジョブを投入します。
$ glite-wms-job-submit --vo atlas_j -o jobid testenv.jdl
実行結果を得るため
$ glite-wms-job-status -i jobid $ glite-wms-job-output -i jobid
得られた標準出力の内容を確認しましょう。
JDLへの条件の記述
joblistmatchでの確認
CEを指定してジョブを投げる
RBを経由せずにジョブを投げる
テストのために使用