Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

slotd

slotd

slotd は、Rust で実装された単一ノード・単一ユーザー向けの Slurm 風スケジューラです。

他言語のドキュメント:

対象はクラスタではなく 1 台のワークステーションです。一般的な Slurm のコマンド名と主要オプションを残しつつ、実行モデルは意図的に単純化しています。

  • 1 つのローカル daemon
  • 1 つの SQLite データベース
  • 1 台の実行ホスト
  • 1 人のローカルユーザー向けワークフロー

利用するコマンドは次のとおりです。

  • sbatch
  • srun
  • salloc
  • squeue
  • sacct
  • scontrol
  • scancel
  • sinfo

向いている用途

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 をサポート

このドキュメントに含まれる内容

インストール

必要条件

  • 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 にインストールする
  • sbatchsqueue などのコマンド alias を作成する
  • ~/.local/share/slotd に runtime root を作成する
  • ~/.config/slotd/slotd.env を生成する
  • systemd --user service をインストールして起動する

インストーラのオプション

オプション説明デフォルト
--repo-root PATH別のリポジトリルートからビルドする現在の repo
--profile NAME使用する Cargo profilerelease
--install-bin-dir PATHバイナリと alias のインストール先~/.local/bin
--runtime-root PATHSLOTD_ROOT として使う runtime root~/.local/share/slotd
--config-dir PATH設定ディレクトリ~/.config/slotd
--systemd-user-dir PATHuser unit ディレクトリ~/.config/systemd/user
--cpu-partitions VALUESLOTD_CPU_PARTITIONS に書く値cpu
--gpu-partitions VALUESLOTD_GPU_PARTITIONS に書く値gpu
--features VALUESLOTD_FEATURES に書く値未設定
--notify-cmd VALUESLOTD_NOTIFY_CMD に書く値未設定
--cgroup-base PATHSLOTD_CGROUP_BASE に書く値未設定
--skip-build既存のビルド成果物を再利用するoff
--skip-systemduser service をインストール・起動しないoff
--uninstallインストール済みの構成を削除するoff
--purge-runtimeuninstall 時に永続データも削除する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.sock
  • lib/state.db
  • lib/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/meminfoMemTotal から検出し、失敗時は 16384 MB にフォールバックする
  • メモリは MB 単位で保存
  • GPU は整数スロット
  • admission は実使用量ではなく予約量ベース
  • SLOTD_CGROUP_BASE が未設定なら、CPU とメモリは予約量だけを扱う
  • SLOTD_CGROUP_BASE を writable な cgroup v2 subtree に設定すると、slotdmemory.maxcpu.max を書き込む
  • 明示設定後に cgroup 設定に失敗した場合は、enforcement を黙って省略せず launch を失敗させる

パーティション

環境変数で設定します。

  • SLOTD_CPU_PARTITIONS
  • SLOTD_GPU_PARTITIONS

ルール:

  • 設定済みのパーティション名だけを受け付ける
  • GPU がない場合、GPU パーティションは公開されない
  • GPU パーティションを選び、かつ --gpus を省略した場合の既定値は 1
  • それ以外の既定値は 0
  • CPU/GPU パーティションは 1 台のローカルホストを利便性のために分けて見せる仮想的な区分
  • CPU 容量とメモリ容量はパーティション間で共有され、違いは主に GPU の可視性と既定値

GPU 検出

SLOTD_GPU_COUNT が未設定の場合、slotdnvidia-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

ジョブ状態

実装されている状態:

  • PENDING
  • RUNNING
  • COMPLETING
  • COMPLETED
  • FAILED
  • CANCELLED
  • TIMEOUT
  • OUT_OF_MEMORY

終端状態:

  • COMPLETED
  • FAILED
  • CANCELLED
  • TIMEOUT
  • OUT_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 socket
  • lib/state.db: SQLite state
  • lib/jobs/<job_id>/script.sh: batch script
  • lib/jobs/<job_id>/runner.sh: daemon wrapper
  • lib/jobs/<job_id>/exit_status: wrapper exit status

通知

SLOTD_NOTIFY_CMD が設定されている場合、slotd は終端状態になった top-level job に対してそのコマンドを実行します。

export される変数:

  • SLOTD_JOB_ID
  • SLOTD_JOB_NAME
  • SLOTD_JOB_STATE
  • SLOTD_JOB_PARTITION
  • SLOTD_JOB_REASON

sbatch によるバッチジョブ

形式

sbatch [options] <script>
sbatch [options] --wrap '<command>'

sbatch の動作

sbatch は永続化された batch job record を作成し、ローカル daemon に投入します。

script mode の場合:

  • ディスク上の script を読む
  • job directory に本文を保存する
  • 先頭の #SBATCH directive を解釈する

--wrap mode の場合:

  • コマンドを包む内部 shell script を生成する
  • --ntasks2 以上なら 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>要求メモリ。512M8G など
-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 回だけ再投入する
--parsablejob ID だけを出力する
-W, --waitjob 完了まで待つ

既定値

指定しない場合:

  • cpus-per-task = 1
  • ntasks = 1
  • mem = 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

優先順位:

  1. command-line option
  2. SBATCH_* 環境変数
  3. #SBATCH directive
  4. 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 を読み、先頭の #SBATCH directive を適用する
  • 指定した 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 のような range
  • 0-15:2 のような step 付き range
  • 0-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-DD
  • YYYY-MM-DDTHH:MM:SS
  • now+<duration>

例:

sbatch --begin now+00:10:00 --wrap 'echo delayed'

Requeue Once

--requeue による失敗時の扱い:

  • FAILED は 1 回だけ requeue
  • TIMEOUT は 1 回だけ requeue
  • OUT_OF_MEMORY は 1 回だけ requeue
  • COMPLETED は 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 が受け付ける形式:

  • ALL
  • NONE
  • KEY=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 の場合だけです。

--ntasks2 以上の場合、foreground の srun は同じホスト上で task rank ごとに 1 つのローカルプロセスを起動し、SLURM_PROCIDSLURM_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すぐにリソースが確保できない場合は失敗する
--ptyPTY 対応のために予約されており、現在は明示エラーで拒否される
--constraint <feature>一致する local feature を要求する
--cpu-bind <mode>CPU affinity を設定する
--label出力の先頭に <task_id>: を付ける
--unbuffered転送出力を eager に flush する
--no-waitdaemon-managed run job として投入する

出力挙動

例:

srun --label --unbuffered -- echo hello

典型的な出力:

0: hello

CPU Binding

サポートする値:

  • none
  • cores
  • map_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 を起動します。

--ntasks2 以上の場合、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 を要求する
--immediateallocation をすぐに開始できない場合は失敗する

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, --jobsjob ID で絞り込む
-u, --useruser で絞り込む
-p, --partitionpartition で絞り込む
-o, --format出力 field を選ぶ
-S, --sort行の並び順を指定する
-l, --longlong default view を使う
--start推定開始時刻を表示する
--arrayarray 形式の job ID を表示する
--noheaderheader を省略する

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 名:

  • JobID
  • Partition
  • Name, JobName
  • User
  • ST, State
  • Time, Elapsed
  • TimeLimit, Time_Limit
  • NTasks
  • CPUS, ReqCPUS
  • ReqMem
  • ReqGPU, ReqGPUS
  • Start, StartTime
  • NodeList(Reason), NodeListReason, Reason, NodeList

サポートする % code:

  • %i
  • %P
  • %j
  • %u
  • %t, %T
  • %M
  • %S
  • %R, %N

sacct

sacct は完了済み job や step を含む永続化済み accounting data を表示します。

よく使うオプション

オプション意味
-j, --jobsjob ID で絞り込む
-s, --state状態で絞り込む
-S, --starttime開始時刻で絞り込む
-E, --endtime終了時刻で絞り込む
-u, --useruser で絞り込む
-p, --partitionpartition で絞り込む
-o, --format出力 field を選ぶ
-P, --parsable2`
-n, --noheaderheader を省略する

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 名:

  • JobID
  • ArrayJobID
  • ArrayTaskID
  • JobName
  • Partition
  • User
  • State
  • Reason
  • ExitCode
  • Elapsed
  • AllocCPUS
  • ReqMem
  • ReqTRES
  • AllocTRES
  • NodeList
  • Submit
  • Start
  • End
  • WorkDir
  • BatchFlag
  • MaxRSS

サポートする % 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
  • ReqTRES
  • AllocTRES
  • MaxRSS
  • step summary

hold job

pending job を held state に移します。

結果:

  • job state は PENDING のまま
  • reason は JobHeldUser になる

release job

held 状態の pending job を通常スケジューリングに戻します。

update job

サポートする更新キー:

キールール
JobName / Namejob が PENDING の間だけ変更できる
Partitionjob が PENDING の間だけ変更できる
TimeLimit / Timejob が終端状態になるまでは変更できる
Priorityjob が 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, --partitionpartition で絞り込む
-N, --Node単一ノード要約ビューに切り替える
-l, --longlong default view を使う
-o, --format出力 field を選ぶ
--noheaderheader を省略する

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 の FEATUREScpu のみを表示する
  • GPU partition の FEATUREScpu と検出した 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 名:

  • Partition
  • Hostnames, Hostname, NodeList
  • State
  • Features
  • CPUS
  • CPU_ALLOC, CPUSLOAD, CPUALLOC
  • Memory, Mem
  • MEM_ALLOC, MemoryAllocated, MemAlloc
  • GPUS
  • GPU_ALLOC, GpusAllocated, GpuAlloc
  • Running, RunningJobs
  • Pending, PendingJobs
  • GRES_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

何を検証しているか

現在のテストスイートは、利用者に影響する次の挙動を中心にカバーしています。

  • sbatchsrunsallocsinfosqueuesacctscontrol の基本フロー
  • 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.rs
  • scheduling.rs, compound_scheduling.rs, dependency_variants.rs, array.rs, begin.rs, constraint.rs, resource_flags.rs, requeue.rs, timeout.rs
  • srun_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>.outhello が書かれる

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 が出ない

sinfocpu しか出ない場合の確認項目:

  • 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>