ジョブ投入
miyabiのシステム構成
miyabiはCPUベースのMiyabi-CとGPUベースのMiyabi-Gのハイブリッドシステムです.ノード数(計算機を構成する演算器の台数)総計算能力はMiyabi-Cが190ノードで1.3 PFLOPS1に対してMiyabi-Gは1120ノードで78.8PFLOPSと,GPUノードのほうが圧倒的に大きいです.
ここでは,GPUノードの利用を前提としたジョブ実行の方法を説明します.Miyabi-Gには1ノードあたり1個のNVIDIA GH200 Superchipが搭載されています. GH200には,ARMベースのNVIDIA Grace CPU(72コア)とNVIDIA H100 GPUが搭載されています.CPUとGPUそれぞれのメモリは120GBと96GB,演算器とメモリの間の通信速度であるメモリバンド幅はCPUが512 GB/s,GPUが4.022 TB/sです. CPU-GPU間は片方向450 GB/sの高速ネットワークで接続されており,またノード間は400 GB/sのInfinibandで接続されています.
GPUはCPUに比べて多数のコアと高速なメモリアクセスが特徴です.ただし,メモリサイズはCPUよりも小さいため,大規模な計算では複数のGPUを使うMPI並列計算が必須となります.
最初のジョブ
以下の簡単なFortranプログラム hello.f90 をジョブ管理システムを用いて実行してみます.
program hello
implicit none
write(*,*) "Hello miyabi!"
call sleep(60)
end program helloこれは,標準出力に Hello miyabi!と出力し,60秒間待つだけのプログラムです. NVIDIAのnvfortranを用いてコンパイルしましょう.
$ nvfortran hello.f90 -o hello.xhello.xは単一のCPUを用いた小さなプログラムですから,直接実行することもできますが,あえてこれをジョブにしてみます.
ジョブスクリプトの作成
ジョブは,必要となる計算資源やプログラムの実行文をまとめたジョブスクリプトを書き,それを投入することで実行します.投入されたジョブはすぐに実行されるとは限りません.コンピュータの混雑時にはジョブ管理システムによって計画的に実行されます.
先ほどのhello.xを実行するジョブスクリプトは以下のようなものです.
#!/bin/bash
#PBS -q regular-g
#PBS -l select=1
#PBS -l walltime=00:05:00
#PBS -W group_list=MYGROUP
#PBS -j oe
#PBS -N myjob
#PBS -m abe
#PBS -l mail_power_info=true
cd ${PBS_O_WORKDIR}
./hello.xスクリプト各行の意味は後ほど説明することとして,とりあえず実行してみましょう.
ジョブの投入と監視
ジョブを投入して実行させるには,qsubコマンドを使います.
$ qsub job.sh
2540540.opbs投入に成功すると,上記の例のように7桁の数字+.opbsという文字列が表示されます.この数字が投入されたジョブに固有のジョブID番号です.
投入されたジョブの状態は qstat コマンドで確認できます.
$ qstat
JOB_ID JOB_NAME STATUS PROJECT QUEUE START_DATE ELAPSE TOKEN NODE MIG
2540540 job.sh RUNNING gv49 small-g 08/12 21:13:49 00:00:10 0.0 1 -上記の例はSTATUSがRUNNINGになっており,実行中の状態です.投入直後はQUEUED(投入された),大きいジョブや混雑時にはその後 SCHEDULED (実行日時の予定が決まった)という状態を経て実行されます.SCHEDULEDのときは,START_DATEに開始予定日時が書かれています.
その後終了するとSTATUSがEXITINGになり2,完全に終了すると
$ qstat
No unfinished job found. という表示になります.このプログラムでは call sleep(60) していますので,終了まで1分強かかります.ジョブの開始と終了のタイミングで,登録メールアドレスにメールが届いているはずです.
カレントディレクトリでlsしてみると,出力ファイル myjob.oXXXXXXXが作られているはずです.ただしXXXXXXXはジョブID番号です.このなかにプログラムの出力が含まれています.
$ cat myjob.oXXXXXXX
Hello miyabi!出力ファイルは,ジョブの実行が始まってすぐに作成され,プログラムの進行とともに継ぎ足されていきます.もちろん,プログラムが何も画面に出力しないのであれば,ファイルは空のままです.
以上をまとめると,ジョブ管理システムにおけるプログラム実行は,以下のような手続きからなります.
- プログラムの作成とコンパイル
- ジョブスクリプトの作成
- ジョブの投入
- 実行待機と(必要があれば)監視
- ジョブの終了確認
- 出力結果ファイルの解析
ジョブスクリプトにおける指定
それでは,あらためてジョブスクリプトの書き方を説明していきます.ジョブスクリプトの先頭にある#PBS から始まる文が,ジョブ実行の設定です.以下に説明するジョブ投入コマンドのコマンドラインオプションとしても指定できるのですが,煩雑になるのでスクリプトで記述するほうがお勧めです.沢山ありますが,実はすべてが必須というわけではなく,使う可能性があるものをすべて列挙しています.意味は以下の表の通りです.
| オプション | 必須 | 意味 |
|---|---|---|
-q regular-g |
YES | ジョブ投入のキュー |
-l select=1 |
YES | 使用ノード数 |
-l walltime=00:05:00 |
YES | ジョブの実行予定時間 |
-W group_list=MYGROUP |
YES | 計算資源を使うグループ |
-j oe |
no | 標準出力と標準エラー出力を統合 |
-N myjob |
no | ジョブの名前を指定 |
-m abe |
no | ジョブの開始終了時にメール送信 |
-l mail_power_info=true |
no | メールに使用電力情報を含める |
以下,順番に詳しく説明していきます.
キュー
キュー(Queue)とは,ジョブの種類別のグループのようなものです.Miyabi-Gは全部で1120個のGPUを搭載していますが,それをデバッグ用,小規模計算用,通常使用用などと分けています.また,キューごとにひとつの計算ジョブで利用できるノード数や計算時間などが異なります.どのようなキューがあり,どれだけ使われているかは
$ qstat --nodeuseというコマンドで確認できます.通常の使用には regular-g を指定しておけばよいです.regular-gは使用ノード数に応じてsmall-g, medium-g, large-g, x-large-gというキューに分かれているのですが,regular-g を指定するとシステムが適宜振り分けてくれます.
使用ノード数
MPI並列計算を使用しない単独コアの(OpenMPの並列化をしていない)場合は1,MPIやOpenMPの並列化をした場合は専用の記述をします.詳しくは応用例で紹介します.
計算時間
スパコンは大人数が同時に使うものですので,投入されたジョブは,ジョブスケジューラがその使用ノード数と計算時間長に応じて最適な実行ノードと実行時間を設定します.
計算ジョブの実行が予定計算時間を超えてしまうと,そのジョブは強制終了されてしまいます.このように書くと,できるだけ長く設定しておけば良いと考えるかもしれませんが,それは良い方法ではありません.時間が短ければ,短時間だけ予定が空いているノードですぐに実行される可能性が高まります.自分のプログラムの計算量を把握し,確実に計算が終わりつつも長過ぎない時間を設定するのがコツです.
計算資源を使うグループ
スパコンには「計算資源」という概念があり,あらかじめアカウントの所属するグループ毎に1年間に利用できる計算量がトークンという単位で割り当てられています.ユーザーは複数のグループに所属していることがあるため,ジョブの実行時には自分が所属するグループIDを記載する必要があります.計算実行後,そのグループから計算に使った資源量が差し引かれます.
現在自分が使える計算資源量は,利用支援ポータルWebのほか,
$ show_tokenコマンドによっても知ることができます.なお,出力ファイル数やファイル容量にも制限があり,そちらは
$ show_quotaで確認できます.
ジョブの出力ファイル
コマンドライン端末から対話的に実行する場合とことなり,ジョブで実行されるプログラムには画面へのテキスト出力ができません.そのかわりに,標準出力と標準エラー出力(Fortranでは装置番号6番と0番,あるいはuse iso_fortran_envした状態で装置番号変数 output_unit と error_unit)を,それぞれファイルに出力します.つまり,1回のジョブ実行で2つのファイルが作成されます.そのファイル名は,標準出力が${jobname}.o${jobid},標準エラー出力が${jobname}.e${jobid}です.ただし${jobname}には -N オプションで名前を指定していればその名前が,そうでなければジョブスクリプトのファイル名が使われます.${jobid}はジョブID番号です.
たとえ標準出力や標準エラー出力がなくてもファイルが生成されるので,デバッグや試行錯誤をしていると出力ファイルが溜まっていきがちです.-j oeオプションを指定すると,標準エラー出力の内容も標準出力ファイルにまとめてくれます.この場合,作成されるファイルは${jobname}.o${jobid}だけです.
メール通知
オプション -m abe を指定しておくと,ジョブの異常終了時(a),開始時(b),終了時(e)にそれぞれ電子メールで通知してくれます.メールの宛先はアカウント登録時に設置したメールアドレスで,利用支援ポータルから変更することができます.
ジョブ実行時のディレクトリ移動
上記のジョブスクリプト例には,
cd ${PBS_O_WORKDIR}という記載があります.この${PBS_O_WORKDIR}には,qsubコマンドによってジョブを投入したディレクトリ名が格納されています.通常はこのままで構いませんが,自分で絶対パスのディレクトリを直接記載してもよいでしょう.
インタラクティブジョブ
ログインノードは多数のユーザーで共有するものですので,そこで重い計算をすると他のユーザーに迷惑がかかります. 以下のコマンドでインタラクティブジョブを起動すると,1つのノードを1時間占有できます.インタラクティブジョブの実行ノードとログインノードではファイルシステムは共通ですので,端末だけインタラクティブジョブを起動してデータ処理などをし,ファイル編集はログインノードから,という使い方ができます.
$ qsub -I -l select=1 -W group_list=MYGROUP -q interact-g -l walltime=01:00:00
なお,大規模計算のプリ・ポスト処理用により利用時間の長いプリポストノードも用意されていますが,Miyabi-Cにしかありませんので説明は省略します.