mcpField
S
slurm-job-script-generator

slurm-job-script-generator

github.com/heshamfsクラウド・DevOps83201 回インストール1 週間前に更新
リポジトリ

slurm-job-script-generator について

HPC利用者向けに、SLURMのジョブスクリプトを生成し、リソース設定のよくある誤りを検査するスキルです。入力を検証し、CPU・GPUの割り当てを算出して、投入前に警告を示します。

主な機能

  1. 01.sbatchジョブスクリプトの生成
  2. 02実行時間とメモリ指定の検査
  3. 03タスクとGPU配置の算出
  4. 04過剰割り当てとランチャー競合の警告
  5. 05コマンドライン入力の検証

活用シーン

  1. 01MPIまたはMPI+OpenMPシミュレーション用スクリプトの作成
  2. 02競合するメモリ指定の確認
  3. 03投入前のタスク・GPU配置の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/heshamfs/materials-simulation-skills --skill slurm-job-script-generator

インストール後、Claude Code で/slurm-job-script-generatorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CHANGELOG.md
evals/
evals.json
references/
slurm_directives.md
scripts/
slurm_script_generator.py

詳細

SLURM ジョブスクリプトジェネレーター

目標

シミュレーションを実行するための、正しくそのままコピーして使える SLURM ジョブスクリプト(.sbatch)を生成し、よくある設定ミス(不正なウォールタイムの形式、競合するメモリ指定、過剰割り当てのヒント)を提示します。

要件

  • Python 3.10+
  • 外部依存関係なし(Python 標準ライブラリのみ)
  • Linux、macOS、Windows で動作します(スクリプトの生成のみ)

収集する入力

入力説明例
ジョブ名ジョブの短い識別子phasefield-strong-scaling
ウォールタイムSLURM の時間制限00:30:00
パーティションクラスタのパーティション/キュー(必要な場合)compute
アカウントプロジェクト/アカウント(必要な場合)matsim
ノード数割り当てるノード数2
MPI タスク数合計タスク数、またはノードあたりのタスク数128 またはノードあたり 64
スレッド数タスクあたりの CPU 数(OpenMP スレッド数)2
メモリ--mem または --mem-per-cpu(クラスタのポリシーによります)32G
GPU 数ノードあたりの GPU 数(任意)4
作業ディレクトリ実行するディレクトリ$SLURM_SUBMIT_DIR
モジュール読み込む環境モジュール(任意)gcc/12、openmpi/4.1
実行コマンドSLURM で実行するコマンド./simulate --config cfg.json

判断の指針

MPI と MPI+OpenMP のレイアウト
Does the code use OpenMP / threading?
├── NO  → Use MPI-only: cpus-per-task=1
└── YES → Use hybrid: set cpus-per-task = threads per MPI rank
          and export OMP_NUM_THREADS = cpus-per-task

経験則: MPI ランク数が多い場合に強スケーリング効率の低下が見られるなら、ランク数を減らしてランクあたりのスレッド数を増やし、計測してみてください。

メモリフラグの選択
  • --mem(ノードあたり)または --mem-per-cpu(CPU あたり)のどちらか一方を使い、両方は使わないでください。
  • クラスタのドキュメントに従ってください。サイトによっては、どちらか一方の形式しか許可されません。
  • SLURM の --mem の単位は、既定では整数の MB です。または、接尾辞 K/M/G/T を付けた整数を指定します(--mem=0 は一般に「ノード上のすべてのメモリ」を意味します)。
ランチャーの選択(二重ラップを回避)
  • 既定では(--launcher srun)、ジェネレーターは実行コマンドの前に srun --ntasks=N --cpus-per-task=T を付加し、SLURM のタスク配置を継承します。
  • 実行コマンドがすでに srun、mpirun、または mpiexec で始まっている場合は、--launcher none を渡してください。 ジェネレーターによる二重ラップを防げます。srun で mpirun をラップすると、独立した mpirun が N 個起動し、それぞれが独自の MPI ワールドを生成します。srun を srun でラップするのは不正な形式です。
  • 安全策として、ジェネレーターは先頭のランチャー(srun、mpirun、mpiexec、mpiexec.hydra、orterun、aprun、jsrun)を自動検出してラップなしに切り替え、--launcher none を推奨する警告を出します。
GPU レイアウト
  • GPU あたりのランク数 = total_ranks / (nodes * gpus_per_node)。--gpus-per-node が設定されている場合、ジェネレーターは results.derived.total_gpus と results.derived.ranks_per_gpu を報告します。
  • ランクをデバイスに均等に割り当てることを目指してください。ntasks が GPU の合計数で割り切れない場合、ジェネレーターは「タスクと GPU の比率が整数ではありません」という警告を出します。ntasks/GPU 数を調整するか、意図的な共有(NVIDIA MPS など)について説明を記載してください。
  • --gpu-bind=closest や --ntasks-per-gpu などのバインドオプションを検討してください(実行コマンドまたは --srun-extra で渡します)。GPU と QoS のポリシーはサイトごとに異なるため、クラスタのドキュメントで確認してください。

スクリプトの出力(JSON フィールド)

スクリプト主な出力
scripts/slurm_script_generator.pyresults.script、results.directives、results.derived、results.warnings、results.run_line

results.derived は ntasks、ntasks_per_node、cpus_total_requested と、該当する場合は cores_per_node、cpus_per_node_requested、total_gpus、ranks_per_gpu を報告します。results.warnings には、CPU の過剰割り当て、タスクと GPU の比率、二重ランチャーに関する警告が含まれる場合があります。

ワークフロー

  1. クラスターの制約(パーティション/アカウント、GPU のポリシー、メモリのポリシー)を確認します。
  2. プロセスの構成(MPI のみ、または MPI+OpenMP のハイブリッド)を選択します。
  3. slurm_script_generator.py を使用してスクリプトを生成します。
  4. 警告(競合や疑わしい構成)を確認します。
  5. 生成されたスクリプトを job.sbatch として保存します。
  6. sbatch job.sbatch で送信し、squeue で監視します。

CLI の例

# Preview a job script (prints to stdout)
python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \
  --job-name phasefield \
  --time 00:10:00 \
  --partition compute \
  --nodes 1 \
  --ntasks-per-node 8 \
  --cpus-per-task 2 \
  --mem 16G \
  --module gcc/12 \
  --module openmpi/4.1 \
  -- \
  ./simulate --config config.json

# Write to a file and also emit structured JSON
python3 skills/hpc-deployment/slurm-job-script-generator/scripts/slurm_script_generator.py \
  --job-name phasefield \
  --time 00:10:00 \
  --nodes 1 \
  --ntasks 16 \
  --cpus-per-task 1 \
  --out job.sbatch \
  --json \
  -- \
  /bin/echo hello

会話形式のワークフロー例

ユーザー:MPI シミュレーション用の sbatch スクリプトが必要です。2 ノード、ノードあたり 64 ランク、ランクあたり 2 個の OpenMP スレッド、実行時間は 2 時間にしたいです。

エージェントのワークフロー:

  1. パーティション/アカウントと、GPU が必要かどうかを確認します。
  2. ハイブリッドジョブのスクリプトを生成します。
    python3 scripts/slurm_script_generator.py --job-name run --time 02:00:00 --nodes 2 --ntasks-per-node 64 --cpus-per-task 2 -- ./simulate
    
  3. マッピングについて説明します。
    • ランクの合計 = 128
    • ランクあたりのスレッド数 = 2(OMP_NUM_THREADS=2)
  4. ユーザーからノードのコア数が提示された場合は、--cores-per-node を使用してオーバーサブスクリプションがないか確認します。

エラー処理

エラー原因解決方法
time must be HH:MM:SS or D-HH:MM:SSウォールタイムの形式が正しくありません00:30:00 または 1-00:00:00 を使用します
nodes must be positiveノード数が正の値ではありません--nodes >= 1 を指定します
Provide either --mem or --mem-per-cpu, not bothメモリ指定が競合していますメモリ指定方式を 1 つ選択します
Provide a run command after --起動コマンドがありません-- ./simulate ... を追加します
--partition must match /^[A-Za-z0-9]...パーティション/アカウント/qos/constraint/reservation に空白またはシェルのメタ文字が含まれています通常の識別子を使用します
module must match /^[A-Za-z0-9]...モジュール名にシェルのメタ文字が含まれています例:gcc/12、openmpi/4.1 を使用します
nodes must be <= 100000 (got ...)整数の要求値が妥当性確認の上限を超えています要求値を再確認します

検証チェックリスト

  • 生成された results.script で、すべての #SBATCH ディレクティブがシバンの直後、かつ set -euo pipefail より前に配置されていることを確認しました(スクリプトを開き、最初の実コマンド行を確認してください)。最初のコマンドの後にあるディレクティブは SLURM によって黙って無視されます。
  • results.warnings を確認し、空であることを確認するか、各警告(CPU のオーバーサブスクリプション、タスクと GPU の比率が整数でないこと、ランチャーの二重起動)について、無視する正当な理由を記録しました。
  • results.derived.cpus_total_requested(= ntasks * cpus-per-task)を記録し、--cores-per-node を指定した場合は、ノードがオーバーサブスクリプションにならないよう cpus_per_node_requested <= cores_per_node を確認しました。
  • ハイブリッド実行では、スクリプトの export OMP_NUM_THREADS の値が results.derived の cpus_per_task と一致することを確認しました(ジェネレーターは両者を同じ値に設定します。ランクあたりの意図したスレッド数と一致することを確認してください)。
  • GPU ジョブでは、results.derived.total_gpus と ranks_per_gpu を記録し、ranks_per_gpu が意図した整数であること(または MPS など、共有が意図的であることを記録していること)を確認しました。
  • results.run_line が二重にラップされていないことを確認しました。実行コマンドがすでに srun/mpirun/mpiexec/orterun/aprun/jsrun で始まる場合は、SLURM が独立したコピーを N 個起動しないよう、--launcher none が使用されたこと(または自動検出の警告が出たこと)を確認しました。
  • パーティション、アカウント、QoS、メモリ指定方式(--mem と --mem-per-cpu のどちらか)、GPU ディレクティブを、実際のクラスターの文書化されたポリシーと照合しました。ジェネレーターが検証するのは内部整合性のみで、サイトのポリシーは検証しません。

よくある落とし穴と誤った自己正当化

誘惑されがちな近道それが誤りである理由/すべきこと
「エラーなしでスクリプトが生成されたので、リソースは正しいはずです。」ジェネレーターがチェックするのは内部整合性だけで、クラスターへの問い合わせは行いません。ジョブを送信する前に、パーティション/アカウント/QoS/メモリの指定形式と GPU ディレクティブを、サイトの実際のドキュメントで確認してください。
「実行コマンドにすでに srun/mpirun があるので、そのままにしてジェネレーターでラップします。」mpirun を srun でラップすると、独立した N 個の mpirun プロセス(それぞれが独自の MPI ワールド)を起動します。srun を srun でラップするのは不正な形式です。--launcher none を渡し、自動検出の警告が results.warnings に出力されたことを確認してください。
「使いたいノードをリクエストしたので、ジョブはすべてのノードを使うはずです。」#SBATCH ディレクティブが最初のコマンドより下にあると、何も通知されずに無視され、ジョブはクラスターのデフォルト設定にフォールバックします。生成されたスクリプトを読み直し、すべてのディレクティブが set -euo pipefail より前にあることを確認してください。
「ntasks は GPU 数で割り切れませんでしたが、実行できたので問題ありません。」ranks_per_gpu が整数でない場合、ランクはデバイスに不均等に割り当てられます(GPU がアイドル状態または過剰割り当てになります)。ジェネレーターはタスクと GPU の割り当てに関する警告を出力します。ntasks/GPU 数を修正するか、MPS 共有について明示的に記載してください。
「ランク数が多いほど速くなるので、ntasks-per-node を大きく設定します。」--cores-per-node を指定しないと、ジェネレーターは過剰割り当てを検出できません。また、ntasks-per-node*cpus-per-task が物理コア数を超えると、パフォーマンスが低下します。--cores-per-node を渡し、cpus_per_node_requested を確認してください。
「念のため --mem と --mem-per-cpu の両方を設定します。」これらは相互排他的です。ジェネレーターは両方を指定すると拒否します。クラスターのポリシーで適用される方を選んでください。
「MPI 専用のコードでは OMP_NUM_THREADS は関係ありません。」ジェネレーターは常に OMP_NUM_THREADS=cpus-per-task をエクスポートします。MPI 専用の実行では、スレッド化されたライブラリがコアを気付かないうちに過剰使用しないよう、--cpus-per-task=1 にしてください。

セキュリティ

入力の検証
  • --time は正規表現を使って厳密な HH:MM:SS または D-HH:MM:SS 形式で検証されます(分/秒は [00,59])。
  • --nodes、--ntasks、--ntasks-per-node、--cpus-per-task、--gpus-per-node、--cores-per-node は、十分に大きな上限(例:nodes ≤ 100000、ntasks ≤ 10000000、cpus-per-task ≤ 4096、gpus-per-node ≤ 64)を設けたうえで、正の整数として検証されます。導出される合計 ntasks = nodes * ntasks-per-node も上限チェックされます。
  • --mem と --mem-per-cpu は SLURM が受け付ける形式(^[0-9]+([KMGT])?$)に照らして検証されます。同時に両方を指定すると拒否されます。
  • --job-name は ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ に照らして検証されます(スペースやシェルのメタ文字は使用できません)。
  • --partition、--account、--qos、--constraint、--reservation、--gpu-type は、#SBATCH ディレクティブに出力される前に、安全な文字の許可リスト ^[A-Za-z0-9][A-Za-z0-9._:,+-]{0,127}$ に照らして検証されます。
  • --module の値は、シェルインジェクションを防ぐため ^[A-Za-z0-9][A-Za-z0-9._/+-]{0,127}$ に照らして検証されます(;、|、&、バッククォート、$、空白は使用できません)。
  • --env のキーは、有効なシェル識別子(^[A-Za-z_][A-Za-z0-9_]*$)でなければなりません。値は生成される export 行でシェル用にクォートされます。
  • --srun-extra は shlex.split でトークン化され、各トークンは shlex.quote で再クォートされるため、実行行にシェル構文(;、|、&、$ など)を注入できません。
  • 入力が無効な場合、CLI はメッセージを stderr に出力してコード 2 で終了します。
ファイルアクセス
  • スクリプトは外部ファイルを読み込みません。すべての入力は CLI 引数で指定します。
  • --out は生成された sbatch スクリプトを、指定された単一のファイルパスに書き込みます。
  • 生成されるスクリプトは #SBATCH ディレクティブを含むプレーンテキストのシェルスクリプトで、動的に生成されたコードは含まれません。
ツールの制限事項
  • Read:スクリプトのソース、参照資料、既存のジョブスクリプトの確認に使用します
  • Bash:明示的な引数リストを指定して slurm_script_generator.py を実行するために使用します。生成されたスクリプト自体はエージェントによって実行されません
  • Write:生成された .sbatch ファイルの保存に使用します。書き込み先はユーザーの作業ディレクトリ内に限定されます
  • Grep/Glob:既存のスクリプト、設定ファイル、クラスターのドキュメントの検索に使用します
安全対策
  • eval()、exec()、動的なコード生成は使用しません
  • すべてのサブプロセス呼び出しでは明示的な引数リストを使用します(shell=True は使用しません)
  • run コマンド(-- の後)はトークンごとにシェルクォートされて生成スクリプトに記述されますが、スキル自体が実行することはありません
  • モジュール名、--srun-extra トークン、識別子形式のフィールドは、module load、srun の呼び出し、#SBATCH ディレクティブへのインジェクションを防ぐためにサニタイズまたはクォートされます
  • 生成スクリプトでは、すべての #SBATCH ディレクティブをシバンの直後(実行可能なコマンドより前)に配置し、SLURM の解析が停止しないようにします。また、クラスター上で安全にシェルを実行するために set -euo pipefail を使用します

制限事項

  • クラスターのハードウェアやサイトのポリシーは照会しません。内部整合性の検証のみ可能です。
  • SLURM のインストール環境によって、GPU ディレクティブ、QoS ルール、パーティションは異なります。サイトに合わせてディレクティブを調整してください。

参考資料

  • references/slurm_directives.md - 一般的な #SBATCH ディレクティブとマッピングのヒント

バージョン履歴

  • v1.2.2 (2026-06-24):ディレクティブの順序、オーバーサブスクリプション、タスクと GPU のマッピング、ランチャーの二重ラップ、およびジェネレーターが内部整合性の確認のみを行う点を取り上げた「検証チェックリスト」と「よくある落とし穴とその合理化」のセクションを追加しました。
  • v1.2.0 (2026-06-23):重大なディレクティブ順序のバグを修正しました(すべての #SBATCH 行が set -euo pipefail より前に配置されるようになりました)。run コマンドがすでに srun/mpirun で始まる場合にランチャーを二重にラップしないようにし、GPU タスクと GPU の比率に関する警告とレイアウトのガイダンスを追加しました。入力検証を強化し(整数の上限、パーティション/アカウント/qos/制約/予約/GPU タイプの許可リスト、モジュールのサニタイズ、--srun-extra のクォート)、--help 内の %j をエスケープし、セキュリティと出力に関するドキュメントを修正しました。
  • v1.1.0 (2026-03-26):発見されやすくなるよう説明を最適化し、評価スイート、セキュリティレビュー、標準化されたメタデータ、CHANGELOG を追加しました。
  • v1.0.0 (2026-02-25):SLURM ジョブスクリプトジェネレーターの初版

コメント