--- title: 逐次プログラムの実行 published: true taxonomy: category: - docs external_links: process: true title: false no_follow: true target: _blank mode: active --- 本節では,C言語でプログラムを作成し,スーパーコンピュータでコンパイル・ジョブ実行を行うユースケースについて説明します.<br> スーパーコンピュータへのログインについては,[システムへの接続方法](/login) をご覧ください. [toc] ## サンプルプログラムの作成 本節では,サンプルプログラム (sample.c) を作成ならびにコンパイルする手順について説明します. ### エディタの起動 ここでは,emacsを用いてサンプルプログラムを作成します.emacsの他にシステムに標準インストールされているエディタとしては, vi(vim) などがあります. 下記のコマンドでemacsが起動し,空のファイル「sample.c」を開きます. ```nohighlight emacs sample.c ``` ### プログラムの記述 下記のプログラムを手入力するか,コピー&ペーストしてください.<br> ターミナルへのペーストはマウスの右クリックやホイールクリックに割り当てられていることが多いです. ```nohighlight #include <stdio.h> #include <unistd.h> int main(void){ printf("hello\n\n"); sleep(120); return 0; } ``` 入力が完了したら,「Ctrl+x Ctrl+s」を押し,保存します. 「Ctrl+x」は,「キーボードのCtrlキーを押しながらxキーを押す」という意味です.<br> 保存が完了した場合は,画面の下部に下記のようなメッセージが表示されます. ```nohighlight Wrote /home/b/b59999/sample.c ``` emacsを終了するには,「Ctrl+x Ctrl+c」を押します.<br> 作成したファイルの確認は,ターミナルで`ls -l`と打ち,下記のようにsample.cといったファイル名が表示されていれば問題ありません. ```nohighlight -rw-r----- 1 b59999 b59999 75 Dec 18 10:42 sample.c ``` ### コンパイル 下記のコマンドを入力してコンパイルします. コンパイルのコマンド名はシステムによって異なります. システム | コマンド -------- | -------- A | cc sample.c BまたはC | icc sample.c コンパイルされたプログラムは「a.out」という名前になります.<br> ターミナルで`ls -l`と打ち,下記のようにa.outというファイル名が表示されていれば問題ありません. ```nohighlight -rw-r----- 1 b59999 b59999 9817 Dec 18 10:42 a.out ``` ## ジョブ実行と実行確認 次に,前節で作成したプログラムを実行する手順について説明します.<br> ログインノードは多くのユーザで共有して使用する計算機ですので, *** プログラムは *** 下記の方法を用いて *** 計算ノードで実行する必要 *** があります. プログラムを計算ノードに投入(実行依頼)する単位をジョブと呼びます. ジョブ投入の方法として,会話型処理とバッチ処理の2種類の方法がありますが, ここではバッチ処理を使ったジョブ投入の方法を紹介します. バッチ処理を用いて,ジョブ投入をする場合はジョブスクリプトと呼ばれるスクリプトで 実行処理について記述する必要があります.<br> ここでは,ジョブスクリプトの作成,実行,実行確認までを説明します. ### ジョブスクリプトの作成 ジョブスクリプトは,原則的にシェルスクリプトと同じ形式です.ジョブスクリプトはPBSのジョブ投入オプションを記述したオプション領域と, 実行するプログラムを記述したユーザプログラム領域(シェルスクリプト部)から構成されます.<br> ユーザプログラム領域にはプログラム本体の実行処理に加えて,前後で実行する処理をシェルスクリプトと同じ形式で記載頂くことが可能となっています. 下記のコマンドでemacsを起動し,sample.shファイルを開きます. ```nohighlight emacs sample.sh ``` emacsが起動したら,下記のジョブスクリプトを手入力するか,コピー&ペーストしてください.<br> *** ※ジョブスクリプトは,システムAとシステムB/Cによってユーザプログラム領域の書き方が異なります.ジョブ投入するシステムのものをご利用ください. *** #### システムA 用のジョブスクリプト ```nohighlight #!/bin/bash #============ PBS Options ============ #QSUB -q gr19999b #QSUB -ug gr19999 #QSUB -A p=1:c=1:t=1:m=1355M #QSUB -W 10:00 #============ Shell Script ============ aprun -n $QSUB_PROCS -d $QSUB_THREADS -N $QSUB_PPN ./a.out ``` ※注) システムAでバッチ処理を行う場合は, ***aprunコマンドが必須*** となります.詳細は [こちら](./#aprun) をご覧ください. #### システムB / C 用のジョブスクリプト ```nohighlight #!/bin/bash #============ PBS Options ============ #QSUB -q gr19999b #QSUB -ug gr19999 #QSUB -A p=1:c=1:t=1:m=3413M #QSUB -W 10:00 #============ Shell Script ============ ./a.out ``` 次に,ご自身の利用可能なシステムやキューに応じて,ジョブスクリプトを修正します. #### \#QSUB -q の値について `#QSUB -q `に続けてキューを指定します.キュー名は,サービスコースごとに以下の値となります. サービスコース | キュー名 -------- | -------- エントリ | eb パーソナル | pa (システムA)<br>pb (システムB)<br>pc (システムC) グループ,機関・部局定額,HPCI,JHPCN | 申込者に通知されたキュー名 グループコースキュー(gr19999b)を指定する場合は下記の通り記載します. ```nohighlight #QSUB -q gr19999b ``` #### \#QSUB -ug の値について これはグループコースまたは機関・部局定額,HPCI,JHPCNの利用者に必要です.エントリ,パーソナルの方はこの行ごと削除して頂いて構いません. `#QSUB -ug `に続けてグループ名を指定します.グループコースはグループ名(キュー名から最後の英字を取ったもの)と同じです.機関定額,HPCI,JHPCNの方は,キュー名と異なる場合がありますので,指定されたグループ名に従ってください. システムBのグループコースキューgr19999bに投入する場合は下記の通り記載します. ```nohighlight #QSUB -ug gr19999 ``` #### \#QSUB -A の値について `#QSUB -A`に続けてジョブ割当リソース量を指定することができます. 指定することが可能な引数は以下の4つで,指定しない場合はデフォルト値が自動的にセットされます. -Aの引数 | 説明 | デフォルト値 | -----------|-------------------------------------|----------------- p=procs | ジョブ実行時の割当プロセス数 | 1 t=threads | ジョブ実行時のプロセスあたりの割当スレッド数.環境変数 OMP_NUM_THREADS を自動で設定 | 1 c=cores | ジョブ実行時のプロセスあたりの割当CPUコア数.基本的に t と同じ値を設定 | 1 m=memory | ジョブ実行時のプロセスあたりの割当メモリ量(単位:M,G,T)| 1355M(システムA), 3413M(システムB), 42666M(システムC) 今回は,逐次プログラム(非並列プログラム)を題材として取り扱っていますので,1プロセスに 1コア,1スレッド,メモリ1355Mを 割り当てて実行する場合の例を以下に記載します.並列計算をする場合は [MPIプログラムの実行](/faq/mpi) をご覧ください. ```nohighlight #QSUB -A p=1:c=1:t=1:m=1355M ``` #### \#QSUB -W の値について `#QSUB -W`に続けてジョブ実行時間の上限値を指定することができます. ジョブ実行時間上限値のデフォルト値ならびに,指定できる最大値は以下のとおりです サービスコース | デフォルト値 | 上限値| ------------------|-----------------|--------| エントリ | 1:00 (1時間) | 1:00 (1時間) パーソナル | 1:00 (1時間) | 168:00 (168時間) グループ,機関・部局定額,HPCI,JHPCN | 1:00 (1時間) | 336:00 (336時間) ジョブ実行時間の上限値を 10時間とする場合は下記の通り記載します. ```nohighlight #QSUB -W 10:00 ``` #### aprunコマンドについて【システムAのみ】 {#aprun} システムAでは,ジョブスクリプトが実行されるノード(ゲートウェイノード)とプログラムが実行されるノード(計算ノード)が分かれています. プログラムを計算ノード上で動作させるためには,逐次プログラム,MPIプログラムに関わらず,ジョブスクリプトのプログラムを実行する箇所に **必ず** _**aprun**_ コマンドを使用する必要があります. aprunコマンドの引数のうち,代表的なものを以下に示します.オプションの詳細については,コマンドのマニュアル(man aprun)を参照してください. オプション |機能 | デフォルト値 | 備考 | :--------------------:|------------------------------------|-----------------|------| -n _procs_ | 起動するプロセス数を指定する | 1 | $QSUB_PROCS を指定することで,\#QSUB -A オプションの p に指定した数値が挿入される -d _cores_ | プロセスあたり確保するCPUコア数を指定する | 1 | $QSUB_THREADS を指定することで,\#QSUB -A オプションの t に指定した数値が挿入される -N _procs\_per\_node_ | ノードあたりのプロセス数を指定する | 1 | $QSUB_PPN を指定することで,自動的に最適な1ノードあたりのプロセス数が挿入される ### ジョブの実行 以下のコマンドでジョブを投入します. ```nohighlight qsub sample.sh ``` 上記コマンドが正常に受け付けられた場合は 下記のようにJOBIDが表示されます. ```nohighlight $ qsub sample.sh 1255581.jb ``` ### 実行確認 `qs`コマンドで,ジョブの状態が確認できます. 出力結果の一例: ```nohighlight QUEUE USER JOBID STATUS PROC THRD CORE MEM ELAPSE( limit) gr19999b b59999 1255581 RUN 1 1 1 1355M 00:00( 10:00) ``` STATUSがRUNになっていれば,プログラムが計算ノードで実行されています.<br> ジョブが終了すると,プログラムの標準出力は,「B121811.o1255581」といった,拡張子が「o+数字」のファイルに出力されます.数字の部分は JOBID になっています. `ls`コマンドで,標準出力ファイルを探し,開いてみましょう.ジョブが正常に実行されていれば,下記のように「hello」という出力と共に,ジョブサマリが出ているはずです. ```nohighlight [b59999@laurel3 b]$ ls B121811.o1255581 B121811.e1255581 [b59999@laurel3 b]$ cat B121811.o1255581 hello ================================================================================ Resource Usage on 2017-12-18 11:50:04.791317: JobId: 1255581.jb Job_Name = B1255581 queue = gr19999b Resource_List.Aoption = gr19999:p=1:t=1:c=1:m=1355:c_dash=1 Resource_List.select = 1:ncpus=2:mpiprocs=1:mem=1355mb:jobfilter=long qtime = 2017-12-18 11:49:58 stime = 2017-12-18 11:50:04 resource_used.cpupercent = 0 resource_used.cput = 00:00:00 resources_used.mem = 0b resources_used.ncpus = 2 resources_used.vmem = 0b resources_used.walltime = 00:00:02 ================================================================================ ``` なお,拡張子が「e+数字」のファイルは,標準エラー出力となります. ## 本格的な計算のために 以上のチュートリアルでは,ホームディレクトリで単一プロセスでのサンプルプログラムの実行を行いました. 本格的な計算には, MPIやOpenMPによる複数プロセス・複数スレッドの並列実行が必要です.そのためには,ジョブスクリプトで今回取り上げなかった`#QSUB -A`オプションが必要です.また,ジョブの標準実行時間は1時間ですので,長時間の計算を行うには`#QSUB -W`オプションが必要です.<br> 詳細は下記ページから,システムに応じた項目をご覧ください. * [プログラムの実行](/run) また,エントリコース以外の方は,ディスク領域としてホーム(容量100GB)以外に大容量ディスクがご利用いただけます. 詳細は下記ページをご覧ください. * [ファイルシステムの利用](/filesystem) コンパイラや計算ライブラリについても,複数種類の商用ツールを用意しております. 利用方法は下記ページをご覧ください. * [コンパイラ・ライブラリ](/compilers) ジョブスクリプトは実行種別に合わせたサンプルスクリプトを用意しています. 詳細は下記ページをご覧ください. * [サンプルスクリプト(システムA)](/run/systema#samplescript) * [サンプルスクリプト(システムB/C)](/run/systembc#samplescript) 以上で,自作アプリケーションのコンパイル,実行 の説明は終了となります.