Sun N1 Grid Engine 6.1 ユーザーズガイド

C アプリケーション例

ここでは、C 言語バインドを使用したアプリケーション対話例をいくつか紹介します。Grid Engine Community サイトの「Howtos」セクションでも、そのほかの例を紹介しています。


例 6–2 セッションの開始と停止

次のコードセグメントは、もっとも基本的な DRMAA C バインドプログラムの例です。

DRMAA 関数を呼び出すたびにエラーコードが返されます。何も問題がなければ、コードは DRMAA_ERRNO_SUCCESS になります。エラーが発生すると、そのエラーに応じたエラーコードが返されます。各 DRMAA 関数は少なくとも 2 つのパラメータを取ります。2 つのパラメータは、エラーの場合にエラーメッセージに埋め込む文字列およびエラー文字列の最大の長さを表す整数です。

例の行 8 では、drmaa_init() を呼び出しています。この関数は DRMAA セッションを設定するもので、ほかの大部分の DRMAA 関数の前に呼び出します。drmaa_get_contact () のように、drmaa_init() の前に呼び出せる関数もありますが、これらの関数は一般的な情報を提供するだけです。drmaa_run_job() drmaa_wait() のようにアクションを実行する関数は、drmaa_init() の復帰後に呼び出します。drmaa_init() が復帰する前にこのような関数を呼び出すと、「DRMAA_ERRNO_NO_ACTIVE_SESSION」というエラーコードが返されます。

dmraa_init() 関数はセッションを作成し、イベントクライアントリスナースレッドを開始します。このセッションは DRMAA を使用して発行されたジョブを整理するためのもので、スレッドはジョブの状態およびシステム全般に関する最新情報をキューマスターから受け取ります。drmaa_init() が正しく呼び出されたあと、呼び出し元のアプリケーションは、終了する前に drmaa_exit () の呼び出しも行います。終了する前にアプリケーションが drmaa_exit() を呼び出さないと、キューマスターに無効なイベントクライアントハンドルが残り、キューマスターのパフォーマンスが低下することがあります。

プログラムが終了する行 17 では、drmaa_exit() はセッションをクリーンアップして、イベントクライアントリスナースレッドを停止します。ほかの大部分の DRMAA 関数は、drmaa_exit() の前に呼び出します。drmaa_get_contact() のように、drmaa_exit() のあとで呼び出せる関数もありますが、これらの関数は一般的な情報を提供するだけです。drmaa_run_job() あるいは drmaa_wait() のようにアクションを実行する関数は、drmaa_exit() を呼び出す前にに呼び出します。drmaa_exit() を呼び出したあとでこのような関数を呼び出すと、「DRMAA_ERRNO_NO_ACTIVE_SESSION」というエラーコードが返されます。

01: #include 
02: #include "drmaa.h"
03: 
04: int main(int argc, char **argv) {
05:    char error[DRMAA_ERROR_STRING_BUFFER];
06:    int errnum = 0;
07: 
08:    errnum = drmaa_init(NULL, error, DRMAA_ERROR_STRING_BUFFER);
09: 
10:    if (errnum != DRMAA_ERRNO_SUCCESS) {
11:       fprintf(stderr, "Could not initialize the DRMAA library: %s\n", error);
12:       return 1;
13:    }
14: 
15:    printf("DRMAA library was started successfully\n");
16:    
17:    errnum = drmaa_exit(error, DRMAA_ERROR_STRING_BUFFER);
18: 
19:    if (errnum != DRMAA_ERRNO_SUCCESS) {
20:       fprintf(stderr, "Could not shut down the DRMAA library: %s\n", error);
21:       return 1;
22:    }
23: 
24:    return 0;
25: }


例 6–3 ジョブの実行

次は、DRMAA C バインドを使用して N1 Grid Engine にジョブを発行するコードセグメントの例です。このプログラムの最初と最後は、例 6–2 と同じです。違いは行 16 〜 59 にあります。行 16 では、DRMAA がジョブテンプレートを割り当てています。ジョブテンプレートは、発行するジョブの情報を格納するための構造です。drmaa_run_job() または drmaa_run_bulk_job() の複数の呼び出しでは、同じテンプレートを再利用できます。

行 22 では、DRMAA_REMOTE_COMMAND 属性を設定しています。この属性は、実行するプログラムがある場所を DRMAA に伝えます。この属性の値は、実行可能ファイルへのパスです。パスは相対または絶対のどちらでもかまいません。相対の場合は、DRMAA_WD 属性を基準にしたパスで、デフォルトではユーザーのホームディレクトリです。DRMAA の属性については、drmaa_attributes のマニュアルページを参照してください。このプログラムが動作するには、sleeper.sh スクリプトがデフォルトパスになければなりません。

行 32 では、DRMAA_V_ARGV 属性を設定しています。この属性は、実行可能ファイルに渡す引数を DRMAA に伝えます。DRMAA の属性については、drmaa_attributes のマニュアルページを参照してください。

行 43 の drmaa_run_job() はジョブを発行します。DRMAA は、ジョブに割り当てられた ID を文字配列に書き込み、この配列が drmaa_run_job() に渡されます。これで、ジョブは qsub によって発行されたかのように動作します。この時点で drmaa_exit() を呼び出すか、プログラムを終了しても、ジョブは何の影響も受けません。

クリーンアップするために、行 54 でジョブテンプレートが削除されます。これによって、ジョブテンプレート用に DRMAA が確保していたメモリーが解放されますが、発行されたジョブは何の影響も受けません。

最後に、行 61 で drmaa_exit() が呼び出されています。drmaa_exit() の呼び出しは、行 18 から始まっていた if 構造の外側にあります。これは、 drmaa_init() が呼び出されたあと、ほかのコマンドが成功したかどうかに関係なく、終了する前に drmaa_exit() を呼び出さなければならないためです。

01: #include 
02: #include "drmaa.h"
03: 
04: int main(int argc, char **argv) {
05:    char error[DRMAA_ERROR_STRING_BUFFER];
06:    int errnum = 0;
07:    drmaa_job_template_t *jt = NULL;
08: 
09:    errnum = drmaa_init(NULL, error, DRMAA_ERROR_STRING_BUFFER);
10: 
11:    if (errnum != DRMAA_ERRNO_SUCCESS) {
12:       fprintf(stderr, "Could not initialize the DRMAA library: %s\n", error);
13:       return 1;
14:    }
15: 
16:    errnum = drmaa_allocate_job_template(&jt, error, DRMAA_ERROR_STRING_BUFFER);
17: 
18:    if (errnum != DRMAA_ERRNO_SUCCESS) {
19:       fprintf(stderr, "Could not create job template: %s\n", error);
20:    }
21:    else {
22:       errnum = drmaa_set_attribute(jt, DRMAA_REMOTE_COMMAND, "sleeper.sh",
23:                                     error, DRMAA_ERROR_STRING_BUFFER);
24: 
25:       if (errnum != DRMAA_ERRNO_SUCCESS) {
26:          fprintf(stderr, "Could not set attribute \"%s\": %s\n",
27:                   DRMAA_REMOTE_COMMAND, error);
28:       }
29:       else {
30:          const char *args[2] = {"5", NULL};
31:          
32:          errnum = drmaa_set_vector_attribute(jt, DRMAA_V_ARGV, args, error,
33:                                               DRMAA_ERROR_STRING_BUFFER);
34:       }
35:       
36:       if (errnum != DRMAA_ERRNO_SUCCESS) {
37:          fprintf(stderr, "Could not set attribute \"%s\": %s\n",
38:                   DRMAA_REMOTE_COMMAND, error);
39:       }
40:       else {
41:          char jobid[DRMAA_JOBNAME_BUFFER];
42: 
43:          errnum = drmaa_run_job(jobid, DRMAA_JOBNAME_BUFFER, jt, error,
44:                                  DRMAA_ERROR_STRING_BUFFER);
45: 
46:          if (errnum != DRMAA_ERRNO_SUCCESS) {
47:             fprintf(stderr, "Could not submit job: %s\n", error);
48:          }
49:          else {
50:             printf("Your job has been submitted with id %s\n", jobid);
51:          }
52:       } /* else */
53: 
54:       errnum = drmaa_delete_job_template(jt, error, DRMAA_ERROR_STRING_BUFFER);
55: 
56:       if (errnum != DRMAA_ERRNO_SUCCESS) {
57:          fprintf(stderr, "Could not delete job template: %s\n", error);
58:       }
59:    } /* else */
60: 
61:    errnum = drmaa_exit(error, DRMAA_ERROR_STRING_BUFFER);
62: 
63:    if (errnum != DRMAA_ERRNO_SUCCESS) {
64:       fprintf(stderr, "Could not shut down the DRMAA library: %s\n", error);
65:       return 1;
66:    }
67: 
68:    return 0;
69: }