slotd

slotd は、Rust で実装された単一ノード・単一ユーザー向けの Slurm 風スケジューラです。
他言語のドキュメント:
対象はクラスタではなく 1 台のワークステーションです。一般的な Slurm のコマンド名と主要オプションを残しつつ、実行モデルは意図的に単純化しています。
- 1 つのローカル daemon
- 1 つの SQLite データベース
- 1 台の実行ホスト
- 1 人のローカルユーザー向けワークフロー
利用するコマンドは次のとおりです。
sbatchsrunsallocsqueuesacctscontrolscancelsinfo
向いている用途
slotd は次の用途に向いています。
- ローカル実験ジョブの待ち行列管理
- 長時間実行する CPU / GPU ジョブ
- 1 台のマシン上でのバッチ処理
- リソース確保付きの対話実行
- ワークステーション上での軽量な Slurm 風インターフェース
次の用途は対象外です。
- マルチノードスケジューリング
- クラスタ管理
- account、QoS、fairshare
- ホストをまたぐ federation や reservation
主な特徴
- 単一の Rust バイナリとして実装
- daemon と Unix domain socket を使用
- 状態は SQLite に永続化
- CPU、メモリ、GPU の予約を管理
- バッチジョブ、配列ジョブ、対話実行、allocation、step をサポート
- 遅延開始、1 回だけの requeue、dependency、ローカル feature constraint をサポート
このドキュメントに含まれる内容
- インストール
- クイックスタート
- ランタイムモデル
sbatchによるバッチジョブsrunによる対話実行sallocによるアロケーション- キュー状態と集計情報
- ジョブ制御
- ノードとパーティション表示
- テスト
- 実行例
- トラブルシューティング
インストール
必要条件
- Linux または WSL
cargoを含む Rust toolchain- daemon を自動管理したい場合は
systemd --user - GPU の自動検出を使いたい場合は
nvidia-smi
リポジトリを clone する
git clone https://github.com/ymgaq/slotd.git
cd slotd
付属スクリプトによるインストール
リポジトリルートで実行します。
./scripts/install.sh
デフォルトでは次を行います。
slotdを release ビルドするslotdを~/.local/binにインストールするsbatchやsqueueなどのコマンド alias を作成する~/.local/share/slotdに runtime root を作成する~/.config/slotd/slotd.envを生成するsystemd --userservice をインストールして起動する
インストーラのオプション
| オプション | 説明 | デフォルト |
|---|---|---|
--repo-root PATH | 別のリポジトリルートからビルドする | 現在の repo |
--profile NAME | 使用する Cargo profile | release |
--install-bin-dir PATH | バイナリと alias のインストール先 | ~/.local/bin |
--runtime-root PATH | SLOTD_ROOT として使う runtime root | ~/.local/share/slotd |
--config-dir PATH | 設定ディレクトリ | ~/.config/slotd |
--systemd-user-dir PATH | user unit ディレクトリ | ~/.config/systemd/user |
--cpu-partitions VALUE | SLOTD_CPU_PARTITIONS に書く値 | cpu |
--gpu-partitions VALUE | SLOTD_GPU_PARTITIONS に書く値 | gpu |
--features VALUE | SLOTD_FEATURES に書く値 | 未設定 |
--notify-cmd VALUE | SLOTD_NOTIFY_CMD に書く値 | 未設定 |
--cgroup-base PATH | SLOTD_CGROUP_BASE に書く値 | 未設定 |
--skip-build | 既存のビルド成果物を再利用する | off |
--skip-systemd | user service をインストール・起動しない | off |
--uninstall | インストール済みの構成を削除する | off |
--purge-runtime | uninstall 時に永続データも削除する | off |
例:
./scripts/install.sh \
--features cpu,gpu \
--notify-cmd 'notify-send "slotd" "$SLOTD_JOB_ID $SLOTD_JOB_STATE"'
--cgroup-base を使う場合は、writable な cgroup v2 subtree を指定してください。
未設定のままなら CPU とメモリは予約量ベースのままです。
アンインストール
インストール済み構成を削除します。
./scripts/install.sh --uninstall
インストール済み構成と runtime state を両方削除します。
./scripts/install.sh --uninstall --purge-runtime
手動セットアップ
インストーラを使わない場合でも、直接ビルドして実行できます。
cargo build --release
SLOTD_ROOT="$HOME/.local/share/slotd" ./target/release/slotd daemon
別シェルでは同じ SLOTD_ROOT を使います。
SLOTD_ROOT="$HOME/.local/share/slotd" ./target/release/slotd sbatch --wrap 'echo hello'
Runtime Files
デフォルトの runtime root は次です。
~/.local/share/slotd
重要なファイルとディレクトリ:
run/slotd.socklib/state.dblib/jobs/<job_id>/
client と daemon は必ず同じ SLOTD_ROOT を使う必要があります。
クイックスタート
1. daemon の確認
スクリプトでインストールし、--skip-systemd を使っていなければ、daemon はすでに起動しているはずです。
まず基本コマンドを確認します。
sinfo
squeue
sacct
初回起動時の典型例:
sinfoは設定済みパーティションごとに 1 行表示するsqueueは空sacctは空
2. 単純なバッチジョブを投入する
sbatch --wrap 'echo hello from slotd'
典型的な出力:
Submitted batch job 1
3. キューを確認する
squeue
ジョブ実行中の典型的な出力:
JOBID | PARTITION | NAME | USER | ST | TIME | NODELIST(REASON)
1 | cpu | wrap | ... | R | 0:00 | localhost
4. 完了したジョブを確認する
sacct
ジョブ完了後の典型的な出力:
JobID | Partition | JobName | User | State | ExitCode
1 | cpu | wrap | ... | COMPLETED | 0:0
5. ジョブの詳細を表示する
scontrol show job 1
ここで確認できる内容:
- ジョブ ID と所有者
- ジョブ状態と reason
- 要求リソース
- 出力パス
- 作業ディレクトリ
- 各種 timestamp
6. 対話実行を試す
srun --label --unbuffered -- echo hello
典型的な出力:
0: hello
ランタイムモデル
全体像
slotd は単一ホスト向けのスケジューラです。実行モデルは意図的に単純です。
- 1 つのローカル daemon
- 1 つのローカル SQLite データベース
- 1 台のローカル実行ホスト
- 1 人のローカルユーザー向けワークフロー
controller と worker の分離はなく、リモートノード起動プロトコルもありません。
基本リソース
slotd が扱うリソースは 3 種類です。
- CPU
- メモリ
- GPU
現在の挙動:
- CPU 予約量は
ntasks * cpus-per-task ntasksは batch と foreground 実行で task rank ごとに 1 つのローカルプロセスを起動する- 総メモリの既定値は
/proc/meminfoのMemTotalから検出し、失敗時は16384 MBにフォールバックする - メモリは MB 単位で保存
- GPU は整数スロット
- admission は実使用量ではなく予約量ベース
SLOTD_CGROUP_BASEが未設定なら、CPU とメモリは予約量だけを扱うSLOTD_CGROUP_BASEを writable な cgroup v2 subtree に設定すると、slotdはmemory.maxとcpu.maxを書き込む- 明示設定後に cgroup 設定に失敗した場合は、enforcement を黙って省略せず launch を失敗させる
パーティション
環境変数で設定します。
SLOTD_CPU_PARTITIONSSLOTD_GPU_PARTITIONS
ルール:
- 設定済みのパーティション名だけを受け付ける
- GPU がない場合、GPU パーティションは公開されない
- GPU パーティションを選び、かつ
--gpusを省略した場合の既定値は1 - それ以外の既定値は
0 - CPU/GPU パーティションは 1 台のローカルホストを利便性のために分けて見せる仮想的な区分
- CPU 容量とメモリ容量はパーティション間で共有され、違いは主に GPU の可視性と既定値
GPU 検出
SLOTD_GPU_COUNT が未設定の場合、slotd は nvidia-smi から GPU を検出しようとします。
現在の実装で確認するパス:
nvidia-smi/usr/bin/nvidia-smi/usr/lib/wsl/lib/nvidia-smi/bin/nvidia-smi
ジョブ種別
永続化される record は次のいずれかです。
- top-level batch job
- allocation-only job
- array task
- allocation 配下の step
ジョブ状態
実装されている状態:
PENDINGRUNNINGCOMPLETINGCOMPLETEDFAILEDCANCELLEDTIMEOUTOUT_OF_MEMORY
終端状態:
COMPLETEDFAILEDCANCELLEDTIMEOUTOUT_OF_MEMORY
スケジューリングルール
daemon loop は 300ms ごとに回ります。
pending job がブロックされる条件:
- dependency
- array concurrency limit
- delayed start time
- exclusive host use
- 予約リソース不足
- user hold state
順序付け:
- 基本ルールは投入順
- 明示的な job priority で投入順を上書きできる
- array task は array group ごとに交互に実行される
Runtime Files
SLOTD_ROOT 配下:
run/slotd.sock: daemon socketlib/state.db: SQLite statelib/jobs/<job_id>/script.sh: batch scriptlib/jobs/<job_id>/runner.sh: daemon wrapperlib/jobs/<job_id>/exit_status: wrapper exit status
通知
SLOTD_NOTIFY_CMD が設定されている場合、slotd は終端状態になった top-level job に対してそのコマンドを実行します。
export される変数:
SLOTD_JOB_IDSLOTD_JOB_NAMESLOTD_JOB_STATESLOTD_JOB_PARTITIONSLOTD_JOB_REASON
sbatch によるバッチジョブ
形式
sbatch [options] <script>
sbatch [options] --wrap '<command>'
sbatch の動作
sbatch は永続化された batch job record を作成し、ローカル daemon に投入します。
script mode の場合:
- ディスク上の script を読む
- job directory に本文を保存する
- 先頭の
#SBATCHdirective を解釈する
--wrap mode の場合:
- コマンドを包む内部 shell script を生成する
--ntasksが2以上なら task rank ごとに 1 つのローカルプロセスを起動する
典型的な出力:
Submitted batch job 1
--parsable を付けた場合:
1
主なオプション
| オプション | 意味 |
|---|---|
--wrap <command> | インラインの shell command を投入する |
-J, --job-name <name> | job name を設定する |
-p, --partition <partition> | partition を選ぶ |
-c, --cpus-per-task <n> | task ごとの CPU 数 |
-n, --ntasks <n> | 同時に起動するローカル task 数 |
--mem <size> | 要求メモリ。512M や 8G など |
-t, --time <time> | time limit |
-G, --gpus <n> | 要求 GPU slot 数 |
-o, --output <path> | stdout の path pattern |
-e, --error <path> | stderr の path pattern |
-D, --chdir <path> | working directory |
--constraint <feature> | 一致する local feature を要求する |
-d, --dependency <spec> | dependency expression |
-a, --array <spec> | array specification |
--export <spec> | job 内に export する環境変数を指定する |
--export-file <path> | ファイルから環境変数を読み込む |
--open-mode append|truncate | 出力ファイルに追記するか上書きするかを選ぶ |
--signal <spec> | timeout 前に warning signal を送る |
--begin <time> | job の実行可能時刻を遅らせる |
--exclusive | 他の top-level job と host を共有しない |
--requeue | 一部の失敗状態の後に 1 回だけ再投入する |
--parsable | job ID だけを出力する |
-W, --wait | job 完了まで待つ |
既定値
指定しない場合:
cpus-per-task = 1ntasks = 1mem = 512M- partition = 設定済みの default partition
- GPU の既定値は、GPU partition では
1、それ以外では0
#SBATCH 対応
サポートする directive:
-J,--job-name-p,--partition-c,--cpus-per-task-n,--ntasks--mem-t,--time-G,--gpus-o,--output-e,--error-D,--chdir--constraint--begin--exclusive--requeue-d,--dependency-a,--array
優先順位:
- command-line option
SBATCH_*環境変数#SBATCHdirective- built-in default
例となる batch script:
#!/usr/bin/env bash
#SBATCH -J script-demo
#SBATCH -p cpu
#SBATCH -c 2
#SBATCH --mem 1G
#SBATCH -t 00:05:00
#SBATCH -o logs/%j.out
echo "hello from script mode"
echo "job=$SLURM_JOB_ID cpus=$SLURM_CPUS_PER_TASK"
投入方法:
sbatch ./script-demo.sh
期待される結果:
sbatchが script を読み、先頭の#SBATCHdirective を適用する- 指定した job name、partition、CPU 数、メモリ量、出力 path で job が実行される
logs/<jobid>.outに script 本文の出力が書かれる
Dependencies
サポートする dependency expression:
after:<jobid>[,<jobid>...]afterany:<jobid>[,<jobid>...]afterok:<jobid>[,<jobid>...]afternotok:<jobid>[,<jobid>...]singleton
Arrays
サポートする array 指定:
- 単一 ID
0-7のような range0-15:2のような step 付き range0-31%4のような concurrency limit
例:
sbatch -a 0-9%2 --wrap 'echo task=$SLURM_ARRAY_TASK_ID'
期待される結果:
- 複数の task record が永続化される
- 同じ array の同時実行数は最大 2
Delayed Start
--begin が受け付ける形式:
- epoch seconds
YYYY-MM-DDYYYY-MM-DDTHH:MM:SSnow+<duration>
例:
sbatch --begin now+00:10:00 --wrap 'echo delayed'
Requeue Once
--requeue による失敗時の扱い:
FAILEDは 1 回だけ requeueTIMEOUTは 1 回だけ requeueOUT_OF_MEMORYは 1 回だけ requeueCOMPLETEDは requeue しないCANCELLEDは requeue しない
例:
sbatch --requeue --wrap 'exit 1'
Output Paths
pattern token:
%j: job ID%A: array job ID%a: array task ID%x: job name%u: user name%N: hostname%%: リテラルの%
既定値:
- 非 array の stdout:
slurm-%j.out - array の stdout:
slurm-%A_%a.out --error未指定時、stderr は stdout と同じ
Environment Export
--export が受け付ける形式:
ALLNONEKEY=VALUE,...
例:
sbatch --export FOO=bar,HELLO=world --wrap 'echo "$FOO $HELLO"'
期待される結果:
- 出力に
bar worldが含まれる
srun による対話実行
形式
srun [options] -- <command...>
srun の動作
srun はデフォルトでコマンドを foreground で実行します。
挙動は、すでに allocation の中にいるかどうかで変わります。
- allocation の内側:
- step record を作成する
- foreground で直接コマンドを実行する
- allocation の外側:
- allocation に近い top-level record を作成する
- 実行可能になるまで待つ
- step record を作成する
- foreground でコマンドを実行する
daemon-managed な run job を投入するのは --no-wait の場合だけです。
--ntasks が 2 以上の場合、foreground の srun は同じホスト上で task rank
ごとに 1 つのローカルプロセスを起動し、SLURM_PROCID と
SLURM_LOCALID を export します。
主なオプション
| オプション | 意味 |
|---|---|
-J, --job-name <name> | job name を設定する |
-p, --partition <partition> | partition を選ぶ |
-c, --cpus-per-task <n> | task ごとの CPU 数 |
-n, --ntasks <n> | 同時に起動するローカル task 数 |
--mem <size> | 要求メモリ |
-t, --time <time> | time limit |
-G, --gpus <n> | 要求 GPU slot 数 |
-o, --output <path> | foreground stdout の出力先 |
-e, --error <path> | foreground stderr の出力先 |
-D, --chdir <path> | working directory |
--immediate | すぐにリソースが確保できない場合は失敗する |
--pty | PTY 対応のために予約されており、現在は明示エラーで拒否される |
--constraint <feature> | 一致する local feature を要求する |
--cpu-bind <mode> | CPU affinity を設定する |
--label | 出力の先頭に <task_id>: を付ける |
--unbuffered | 転送出力を eager に flush する |
--no-wait | daemon-managed run job として投入する |
出力挙動
例:
srun --label --unbuffered -- echo hello
典型的な出力:
0: hello
CPU Binding
サポートする値:
nonecoresmap_cpu:<id,id,...>
例:
srun --cpu-bind map_cpu:0,2 -- python train.py
Immediate Mode
--immediate を付けると、リソースがすぐに確保できない場合に待たずに失敗します。
例:
srun --immediate -p gpu -G 1 -- nvidia-smi
--no-wait
--no-wait は foreground で待たず、daemon に run job を投入します。
典型的な出力:
Submitted run job 12
制限:
--labelと--unbufferedは--no-waitと同時には使えない--ptyは互換性のために parse されるが、実際の PTY 実装がないため現在は “not implemented yet” エラーで終了する
salloc によるアロケーション
形式
salloc [options] [command...]
salloc の動作
salloc は allocation-only の top-level job を作成し、実行可能になるまで待ってから、その allocation の中で foreground command を起動します。
command を指定しない場合は、自分の shell を起動します。
--ntasks が 2 以上の場合、foreground command は task rank ごとに 1 つの
ローカルプロセスを起動します。
典型的な出力:
Granted job allocation 4
主なオプション
| オプション | 意味 |
|---|---|
-J, --job-name <name> | allocation 名を設定する |
-p, --partition <partition> | partition を選ぶ |
-c, --cpus-per-task <n> | task ごとの CPU 数 |
-n, --ntasks <n> | 同時に起動するローカル task 数 |
--mem <size> | 要求メモリ |
-t, --time <time> | time limit |
-G, --gpus <n> | 要求 GPU slot 数 |
-D, --chdir <path> | working directory |
--constraint <feature> | 一致する local feature を要求する |
--immediate | allocation をすぐに開始できない場合は失敗する |
例
salloc -p gpu -c 4 --mem 8G -G 1 -t 00:30:00
期待される結果:
- allocation record が作成される
- allocation が実行可能になるまで command が待つ
- allocation の中で shell が起動する
- その後の
srunはその allocation 配下の step になる - allocation command は allocation の task 数でローカル multi-task 実行される
キュー状態と集計情報
squeue
squeue は top-level の queued job と running job を表示します。
よく使うオプション
| オプション | 意味 |
|---|---|
--all | すべての状態を表示する |
-t, --states | 状態で絞り込む |
-j, --jobs | job ID で絞り込む |
-u, --user | user で絞り込む |
-p, --partition | partition で絞り込む |
-o, --format | 出力 field を選ぶ |
-S, --sort | 行の並び順を指定する |
-l, --long | long default view を使う |
--start | 推定開始時刻を表示する |
--array | array 形式の job ID を表示する |
--noheader | header を省略する |
Default View
JOBID | PARTITION | NAME | USER | ST | TIME | NODELIST(REASON)
Long View
JOBID | PARTITION | NAME | USER | ST | TIME | TIME_LIMIT | NTASKS | CPUS | REQ_MEM | REQ_GPU | NODELIST(REASON)
Start-Time View
--start を付け、format を明示しない場合:
JOBID | PARTITION | NAME | USER | ST | START_TIME | NODELIST(REASON)
Format Fields
サポートする field 名:
JobIDPartitionName,JobNameUserST,StateTime,ElapsedTimeLimit,Time_LimitNTasksCPUS,ReqCPUSReqMemReqGPU,ReqGPUSStart,StartTimeNodeList(Reason),NodeListReason,Reason,NodeList
サポートする % code:
%i%P%j%u%t,%T%M%S%R,%N
sacct
sacct は完了済み job や step を含む永続化済み accounting data を表示します。
よく使うオプション
| オプション | 意味 |
|---|---|
-j, --jobs | job ID で絞り込む |
-s, --state | 状態で絞り込む |
-S, --starttime | 開始時刻で絞り込む |
-E, --endtime | 終了時刻で絞り込む |
-u, --user | user で絞り込む |
-p, --partition | partition で絞り込む |
-o, --format | 出力 field を選ぶ |
-P, --parsable2 | ` |
-n, --noheader | header を省略する |
Default View
JobID | Partition | JobName | User | State | ExitCode
Record Types
sacct に含まれる record:
- top-level job
- allocation record
- step record
- completed record
ID の表示ルール:
- step ID は
<job_id>.<step_id> - array task は
<array_job_id>_<task_id>
Format Fields
サポートする field 名:
JobIDArrayJobIDArrayTaskIDJobNamePartitionUserStateReasonExitCodeElapsedAllocCPUSReqMemReqTRESAllocTRESNodeListSubmitStartEndWorkDirBatchFlagMaxRSS
サポートする % code:
%i%F%K%j%P%u%t,%T%R%X%M%C%m%b%B%N%V%S%E%Z
ジョブ制御
scontrol
サポートする形式:
scontrol show job <job_id>
scontrol hold job <job_id>
scontrol release job <job_id>
scontrol update job <job_id> KEY=VALUE...
show job
次のような詳細 job 情報を表示します。
- job ID と所有者
- 状態と reason
- 要求リソース
- time limit
- dependency string
- submit、start、end timestamp
- command と working directory
- stdout と stderr の path
- array metadata
ReqTRESAllocTRESMaxRSS- step summary
hold job
pending job を held state に移します。
結果:
- job state は
PENDINGのまま - reason は
JobHeldUserになる
release job
held 状態の pending job を通常スケジューリングに戻します。
update job
サポートする更新キー:
| キー | ルール |
|---|---|
JobName / Name | job が PENDING の間だけ変更できる |
Partition | job が PENDING の間だけ変更できる |
TimeLimit / Time | job が終端状態になるまでは変更できる |
Priority | job が PENDING の間だけ変更できる |
例:
scontrol update job 10 TimeLimit=02:00:00
scancel
サポートする形式:
scancel <job_id>
scancel <job_id.step_id>
scancel --signal <sig> <job_id>
scancel --signal <sig> <job_id.step_id>
Default Cancel Behavior
- pending job はただちに
CANCELLEDになる - running job は
COMPLETINGを経由する - runner は
SIGTERMを送る - 必要なら grace period 後に
SIGKILLを送る
記録される cancel reason:
CancelledByUser
Signal Mode
--signal は通常の cancel を行わず、指定シグナルだけを送ります。
例:
scancel --signal TERM 12
ノードとパーティション表示
sinfo
sinfo はローカルノードに対する partition と host state を表示します。
よく使うオプション
| オプション | 意味 |
|---|---|
-p, --partition | partition で絞り込む |
-N, --Node | 単一ノード要約ビューに切り替える |
-l, --long | long default view を使う |
-o, --format | 出力 field を選ぶ |
--noheader | header を省略する |
Default View
典型的な出力:
PARTITION | HOSTNAMES | STATE | FEATURES | GRES_USED
cpu* | localhost | idle | cpu | N/A
gpu | localhost | idle | cpu,generic_gpu | gpu:0
補足:
- 設定済み partition ごとに 1 行表示される
- default partition には
*が付く - CPU partition の
FEATURESはcpuのみを表示する - GPU partition の
FEATURESはcpuと検出した GPU モデル feature を表示し、汎用のgpuは表示しない - CPU/GPU partition は同じローカルホストを見せ分けるための仮想的な区分
- CPU 容量とメモリ容量は partition 間で共有され、別々の resource pool にはならない
Node View
sinfo -N は partition ごとの行を 1 つのローカルノード要約にまとめます。
典型的な出力:
PARTITION | HOSTNAMES | STATE
cpu,gpu* | localhost | idle
補足:
PARTITION列は partition 名をカンマで連結した値になる- その中でも default partition には
*が付く - long view や format 指定で出す capacity/allocation 系の値は、表示対象 partition 全体で集約される
Long View
sinfo -l では capacity と allocation の詳細が追加されます。
PARTITION | HOSTNAMES | STATE | FEATURES | CPUS | CPU_ALLOC | MEMORY | MEM_ALLOC | GPUS | GPU_ALLOC | RUNNING | PENDING | GRES_USED
Supported Format Fields
field 名:
PartitionHostnames,Hostname,NodeListStateFeaturesCPUSCPU_ALLOC,CPUSLOAD,CPUALLOCMemory,MemMEM_ALLOC,MemoryAllocated,MemAllocGPUSGPU_ALLOC,GpusAllocated,GpuAllocRunning,RunningJobsPending,PendingJobsGRES_USED,GresUsed
サポートする % code:
%P%N%t,%T%f%G
テスト
slotd の検証は、主に tests/ 配下の Rust 統合テストで行っています。
各テストは一時ディレクトリ上に分離されたランタイムを作成し、専用 daemon を起動したうえで、公開されている Slurm 風コマンドをコンパイル済みの slotd バイナリ経由で実行します。
そのため、普段使っている SLOTD_ROOT を汚さずに確認できます。
実行方法
テスト全体を実行:
cargo test
特定の統合テストファイルだけを実行:
cargo test --test scheduling
特定のテストケースだけを実行:
cargo test dependency_job_waits_for_prerequisite_before_running --test scheduling
何を検証しているか
現在のテストスイートは、利用者に影響する次の挙動を中心にカバーしています。
sbatch、srun、salloc、sinfo、squeue、sacct、scontrolの基本フロー- dependency、配列ジョブ、遅延開始、constraint、resource flag、requeue などのスケジューリング規則
srun --pty、--label、--unbuffered、allocation / step などの対話実行・前景実行パス- cancellation、warning signal、update 処理、出力ファイル配置などのライフサイクルと回復処理
SLOTD_NOTIFY_CMDや parsable 出力などの通知・問い合わせ系の挙動
代表的なテストファイル:
cli_basic.rs,sbatch_options.rs,srun.rs,srun_options.rs,srun_modes.rs,salloc.rs,sinfo.rs,control.rs,query_squeue.rs,query_sacct.rsscheduling.rs,compound_scheduling.rs,dependency_variants.rs,array.rs,begin.rs,constraint.rs,resource_flags.rs,requeue.rs,timeout.rssrun_interactive.rs,srun_allocation.rs,cpu_bind.rs,output_files.rs,cancellation.rs,recovery.rs,update.rs,warning_signal.rs,notify.rs
手動スモークテスト
簡単な手動確認を行う場合は、まず daemon を起動します。
cargo run -- daemon
その後、同じ SLOTD_ROOT を使う別シェルから小さなジョブを投げます。
cargo run -- sbatch --wrap 'echo hello'
実行例
CPU バッチジョブ
sbatch \
-J hello \
-p cpu \
-c 1 \
--mem 512M \
-t 00:05:00 \
-o logs/%j.out \
--wrap 'echo hello'
期待される結果:
Submitted batch job <id>logs/<id>.outにhelloが書かれる
GPU バッチジョブ
sbatch \
-J gpu-demo \
-p gpu \
-c 4 \
--mem 8G \
-G 1 \
-t 01:00:00 \
-o logs/%j.out \
--wrap 'nvidia-smi'
期待される結果:
- job は GPU partition 上で動く
- 出力に
nvidia-smiの情報が含まれる
対話 foreground 実行
srun --label --unbuffered -- echo hello
期待される結果:
0: hello
対話 allocation
salloc -p gpu -c 4 --mem 8G -G 1 -t 00:30:00
期待される結果:
Granted job allocation <id>- allocation の中で shell が起動する
Array Job
sbatch \
-J array-demo \
-a 0-9%2 \
-o logs/%A_%a.out \
--wrap 'echo task=$SLURM_ARRAY_TASK_ID'
期待される結果:
- 複数の task record が作られる
logs/<array_id>_0.outのような log file ができる
1 回だけの Requeue
sbatch --requeue --wrap 'exit 1'
期待される結果:
- 最初の失敗で job は
PENDINGに戻る - 2 回目の失敗で最終状態は
FAILEDになる
遅延開始
sbatch --begin now+00:10:00 --wrap 'echo delayed'
期待される結果:
- begin 時刻までは pending のまま
squeue --startに将来の開始時刻が出る
明示的な環境変数 export
sbatch \
--export FOO=bar,HELLO=world \
--wrap 'echo "$FOO $HELLO"'
期待される結果:
- 出力に
bar worldが含まれる
daemon の手動起動
SLOTD_ROOT="$HOME/.local/share/slotd" ./target/release/slotd daemon
別シェルでは次を実行します。
SLOTD_ROOT="$HOME/.local/share/slotd" ./target/release/slotd sbatch --wrap 'echo hello'
トラブルシューティング
Connection refused
症状:
error: io error: Connection refused (os error 111)
意味:
- client は socket path を見つけている
- ただしその場所で接続を受け付ける daemon が動いていない
確認ポイント:
- daemon が実際に起動しているか
- client と daemon が同じ
SLOTD_ROOTを使っているか - 古い実行で残った stale socket file がないか
確認コマンド:
ls -l "$SLOTD_ROOT/run/slotd.sock"
sinfo
Runtime Root が違う
daemon と client が別の runtime root を使うと、コマンドは不安定に失敗したように見えます。
よくある原因:
- daemon は
systemd --userで起動している - client は同じ
SLOTD_ROOTを持たない shell から起動している
最も簡単な対策:
scripts/install.shでインストールする~/.local/binの wrapper command を使う
GPU Partition が出ない
sinfo に cpu しか出ない場合の確認項目:
- daemon 環境で
nvidia-smiが動くか SLOTD_GPU_PARTITIONSが意図通りに設定されているか- GPU 設定変更後に daemon を再起動したか
手動確認:
nvidia-smi
sinfo
再インストール時の Text file busy
インストーラは現在、バイナリを atomic に置き換えます。それでも問題が出る場合:
- daemon を停止または再起動する
- もう一度インストーラを実行する
コマンド:
systemctl --user restart slotd.service
./scripts/install.sh
Job が PENDING のまま
考えられる原因:
- リソース不足
- dependency 未達成
- array concurrency limit
- delayed start time 未到達
- job が held
- すでに exclusive job が動いている
確認方法:
squeue
scontrol show job <job_id>
cgroup 設定に失敗する
SLOTD_CGROUP_BASE を設定しているのに writable な cgroup v2 subtree を指して
いない場合、job launch は明示的な cgroup error で失敗します。
確認項目:
- daemon 環境でその path が存在するか
- 通常の directory や file ではなく cgroup v2 subtree か
- daemon ユーザーが job ごとの subdirectory 作成と control file 書き込みをできるか
Cancel したのに OUT_OF_MEMORY で終わった
終了処理中に cgroup の memory event が OOM を示した場合、最終状態は OUT_OF_MEMORY が優先されることがあります。
出力ファイルが見当たらない
確認ポイント:
- job の working directory
-o/--outputと-e/--errorの path%jや%A_%aなどの pattern expansion
確認コマンド:
scontrol show job <job_id>