slurmはオープンソースのジョブスケジューラーだ。
これは何かというと、例えば、俺は今から1000種類の条件でシミュレーションを投げるぞ! ウオオ という時に、サーバーにログインして、シェルのfor文で1000個のバッチスクリプトを登録し、そのままログアウトして家で寝ていると勝手に順次実行されていくという便利ソフトウェアだ。
普通こういうのはサーバーラックに挿す系の大型クラスターとか、複数台のデスクトップマシンをネットワークで繋いだものとかで色々大変な設定をして使うものだが、今回は全てが面倒に感じたので(あと手元にコントロールノードに使えそうないい感じのマシンがなかったので)、1台をコントロールノードかつ計算ノードとして完結させることにした。共有ストレージとか必要なくなる(自明に共有されている)ので多分色々楽。
それくらいの気持ちなので割と適当にやっていきます。OSはUbuntu 18.04。やりながら書いてるわけではない(history
見て要約して書いてる)ので、何か必須手順忘れてるかも。その時は頑張って下さい。
まず、slurmのコントロールノード用デーモンslurmctld
と計算ノード用デーモンslurmd
をaptで入れる。Ubuntu 18で入るやつは17.11.2でちょっと古い(これを書いている時点で最新版は20.02.0)が見なかったことにする。
$ sudo apt install slurmctld slurmd
最新版を使いたい場合は本家からダウンロードする。
aptを使えば依存関係はもちろんslurm
ユーザーの登録とsystemctl
へのservice
ファイルの配置まで済んでいるので楽。あと必要なのはクラスターの構成を書くためのslurm.conf
だ。
これを簡単に作るためのインターフェースがhtmlファイルとして提供されているので、これを開いて適当に書いていく。CPUとかメモリはあるだけ書く。コントロールノードと計算ノードのIPと名前を同じにしておく。Resource SelectionをCons_resにして、あとは全部デフォルト。
$ firefox /usr/share/doc/slurmctld/slurm-wlm-configurator.easy.html
出てきたファイル(slurm.conf
)を/etc/slurm-llnl
にコピーして、所有者をslurm:slurm
にする。
$ sudo cp slurm.conf /etc/slurm-llnl $ sudo chown slurm:slurm /etc/slurm-llnl/slurm.conf
多分これで大丈夫なので、必要なやつを全部systemctl
に立ち上げてもらうために再起動。手動でsystemctl
からやったほうが良いのかも知れないけど面倒だったので再起動した。
再起動したら、slurmd
とslurmctld
がちゃんと動いているか確認。その後sinfo
で何か出力されるか確認。おかしくなってたらエラーメッセージ見てググって下さい。
$ sudo systemctl status slurmd $ sudo systemctl status slurmctld $ sinfo
ちゃんと動いていたら何かテストスクリプトを投げてみる。
#!/bin/bash echo "sleeping..." sleep 10 echo "done!"
$ sbatch test.sh $ squeue (ジョブが流れているという表示) $ ls slurm-1.out test.sh
ちゃんと動いてるようなら終わりです。
(3/11追記)
スルーしていたslurm.conf
の中身だが、hyperthreadingを使って全スレッドを動かすための設定はハマりがちっぽいので書いておこうと思う。
まず、スケジューリングの際に各ノードで複数のジョブが走ることを許す必要がある。slurm.conf
のスケジューリング関係の設定を以下のようにする。
# ... # SCHEDULING FastSchedule=1 # これはデフォルト SchedulerType=sched/backfill # これもデフォルト SelectType=select/cons_res # これにする SelectTypeParameters=CR_CPU # またはCR_Core # ...
ハイパースレッディングを使わず、単に1ノードでコア数分の複数ジョブを動かす場合はこれだけでよい。
続いて、Partitionでオーバーサブスクライブを許す(複数の異なるジョブがハイパースレッディングでコアを共有することを許す)。デフォルトで生成したslurm.conf
には、最後に以下のような行があるはずだ。ここでOverSubscribe=FORCE
にする。YES
だと一つのジョブ内ではハイパースレッディングができても、異なるジョブ同士はコアを共有しないようだ。
PartitionName=<name> Nodes=<yournode> OverSubscribe=FORCE Default=YES MaxTime=INFINITE State=UP
これで動くはずだ。
作業上の注意点として、slurm.conf
を書き換える際にはsystemctl stop slurmd slurmctld
でslurmを落としておこう。書き換え終わったら、systemctl start slurmd slurmctld
で起動して動くかどうか確かめる。
また、上で書いた環境だとslurm.conf
の中にtypoなどがある状態でslurmctld
をstart
すると、slurmctld
がsystemctl stop slurmctld
で止まってくれなくなることがある。この場合、落ち着いてslurm.conf
を動く状態のものに戻してからsystemctl restart slurmctld
をすると正しく動き始め、かつ正しく止められるようになる。
今適当な値を入れて作りなおしたが、概ねこんな感じになると思う。ノードの名前やIP、リソースの量は入れ替えないといけないが、それをするくらいならslurmのeasy-configuratorを使ったほうが速い。確認用ということで。
# slurm.conf file generated by configurator easy.html. # Put this file on all nodes of your cluster. # See the slurm.conf man page for more information. # ControlMachine=linux0 ControlAddr=10.1.1.100 # #MailProg=/bin/mail MpiDefault=none #MpiParams=ports=#-# ProctrackType=proctrack/pgid ReturnToService=1 SlurmctldPidFile=/var/run/slurm-llnl/slurmctld.pid #SlurmctldPort=6817 SlurmdPidFile=/var/run/slurm-llnl/slurmd.pid #SlurmdPort=6818 SlurmdSpoolDir=/var/lib/slurm-llnl/slurmd SlurmUser=slurm #SlurmdUser=root StateSaveLocation=/var/lib/slurm-llnl/slurmctld SwitchType=switch/none TaskPlugin=task/none # # # TIMERS #KillWait=30 #MinJobAge=300 #SlurmctldTimeout=120 #SlurmdTimeout=300 # # # SCHEDULING FastSchedule=1 SchedulerType=sched/backfill #SchedulerPort=7321 SelectType=select/cons_res SelectTypeParameters=CR_CPU # # # LOGGING AND ACCOUNTING AccountingStorageType=accounting_storage/none ClusterName=cluster #JobAcctGatherFrequency=30 JobAcctGatherType=jobacct_gather/none #SlurmctldDebug=3 SlurmctldLogFile=/var/log/slurm-llnl/slurmctld.log #SlurmdDebug=3 SlurmdLogFile=/var/log/slurm-llnl/slurmd.log # # # COMPUTE NODES NodeName=linux0 NodeAddr=10.1.1.100 RealMemory=32031 Sockets=1 CoresPerSocket=6 ThreadsPerCore=2 State=UNKNOWN PartitionName=debug Nodes=linux0 Default=YES MaxTime=INFINITE State=UP
どうやらRealMemory
にslurmから見えている量以上の値を入れると起動した時のstateがdrain
になって、scontrol
から状態をidle
にしないとジョブが入らないらしい。
計算ノードでslurmd -C
というコマンドを流すとメモリの量を確認できるので、適当な値を書くよりはこの値をコピペするのが無難だろう。
(追記)
systemctl status slurmctld
したときに「pidファイルがない」みたいなエラーで落ちている場合、slurm.conf
とslurmctld.service
で*.pid
ファイルのpathが異なっている可能性がある。それを確認し、適切に揃えてみてほしい。
(追記2) 訂正:SelectTypeParameter -> SelectTypeParameters