PBS pro (openpbs) のインストールと設定

OpenPBS

$ sudo apt-get install git

$ mkdir /root/src
$ cd /root/src
$ git clone https://github.com/openpbs/openpbs

$ cd openpbs

GitHub の OpenPBS のページにある INSTALL を読んで設定を行う.

$ sudo apt-get install gcc make libtool libhwloc-dev libx11-dev \
   libxt-dev libedit-dev libical-dev ncurses-dev perl \
   postgresql-server-dev-all postgresql-contrib python3-dev tcl-dev tk-dev swig \
   libexpat-dev libssl-dev libxext-dev libxft-dev autoconf \
   automake g++ libcjson-dev

$ sudo apt-get install expat libedit2 postgresql python3 \
   postgresql-contrib sendmail-bin sudo tcl tk libical3 libcjson1

configure スクリプトと Makefile の作成

$ ./autogen.sh

configure

$ ./configure --prefix=/opt/pbs

make & make install

$ make
$ sudo make install

$ sudo /opt/pbs/libexec/pbs_postinstall

$ sudo chmod 4755 /opt/pbs/sbin/pbs_iff /opt/pbs/sbin/pbs_rcp

PATH と MANPATH の追加. /etc/skel/.bashrc にも登録しておく.

$ . /etc/profile.d/pbs.sh

# cat /etc/profile.d/pbs.sh >> /etc/skel/.bashrc

ホスト名の登録.100G NIC の IP を /etc/hosts に登録しておく

# vi /etc/hosts

  127.0.0.1       localhost
  10.0.100.31     ncfs1.matsue-ct.ac.jp   ncfs1
  10.0.100.21     ncsv1.matsue-ct.ac.jp   ncsv1
  10.0.100.22     ncsv2.matsue-ct.ac.jp   ncsv2
  10.0.100.23     ncsv3.matsue-ct.ac.jp   ncsv3
  10.0.100.24     ncsv4.matsue-ct.ac.jp   ncsv4

確認:ping が通ることを確認

# ping ncsv2

PBS_SERVER に管理ノードのホスト名を登録する. 管理のために pbs_server, pbs_sched, pbs_comm を起動する必要がある. 管理ノードでは PBS での計算はさせないので, pbs_mom は起動しない.

ログインノードの場合は以下のようにする.

# vi /etc/pbs.conf

  PBS_SERVER=ncfs1
  PBS_START_SERVER=1
  PBS_START_SCHED=1
  PBS_START_COMM=1
  PBS_START_MOM=0
  PBS_EXEC=/opt/pbs
  PBS_HOME=/var/spool/pbs
  PBS_CORE_LIMIT=unlimited
  PBS_SCP=/usr/bin/scp

計算ノードの場合は以下のようにする.

# vi /etc/pbs.conf

  PBS_SERVER=ncfs1
  PBS_START_SERVER=0
  PBS_START_SCHED=0
  PBS_START_COMM=0
  PBS_START_MOM=1
  PBS_EXEC=/opt/pbs
  PBS_HOME=/var/spool/pbs
  PBS_CORE_LIMIT=unlimited
  PBS_SCP=/usr/bin/scp

計算実行場所として使う /work は NFS で共有するために, scp ではなく cp コマンドで ジョブ実行結果をコピーするようにする. $usecp の行を追加する.

# vi /var/spool/pbs/mom_priv/config

 $clienthost ncfs1
 $restrict_user_maxsysid 999
 $usecp *:/work/ /work/

PBS の再起動

# systemctl restart pbs

起動の確認

# systemctl status pbs

  status が inactive の場合は何度か再起動 ( systemctl restart pbs) を実行してみて,active になるのを確認する.

PBS へ計算ノードを登録.

# /opt/pbs/bin/qmgr -c "create node ncsv1"
# /opt/pbs/bin/qmgr -c "create node ncsv2"
# pbsnodes -a (確認)

CPU 用の queue の設定

CPU メイン (GPU なし) のキューの作成

# /opt/pbs/bin/qmgr -c "create queue cpu queue_type=execution"
# /opt/pbs/bin/qmgr -c "set queue cpu enabled=True"
# /opt/pbs/bin/qmgr -c "set queue cpu priority=30"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_default.nodes=1"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_default.ncpus=1"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_default.ngpus=0"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_default.walltime=120:00:00"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_max.nodes=1"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_max.ncpus=32"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_max.ngpus=0"
# /opt/pbs/bin/qmgr -c "set queue cpu started=True"
# /opt/pbs/bin/qmgr -c "set queue cpu resources_default.mem=50gb"

確認

$ /opt/pbs/bin/qmgr -c "p s"
#  /opt/pbs/bin/pbsnodes -aS

GPU を計算リソースとして管理するための設定

GPU 数の登録

管理ノードで実行する. リソースとして GPU の数 (ngpus) を登録.

$ sudo /opt/pbs/bin/qmgr -c "create resource ngpus type=long, flag=nh"

管理ノードの設定ファイルの resources: の行に ngpus を追加

$ sudo vi /var/spool/pbs/sched_priv/sched_config

  resources: "ncpus, mem, arch, host, vnode, aoe, eoe, ngpus"

GPU の数の設定

# /opt/pbs/bin/qmgr -c "set node ncsv1 resources_available.ngpus=2"
# /opt/pbs/bin/qmgr -c "set node ncsv2 resources_available.ngpus=3"

登録内容の確認. ngpus の項目が増えていることがわかる.

$ pbsnodes -a

cgroups用hookの設定 (cgroupsによるGPUリソースの分離)

以下,https://web.chaperone.jp/w/index.php?OpenPBS/GPU を参考にしながら設定した.

PBSProにおいてcgroupsの設定は,ジョブ実行時のhookでpythonスクリプトを実行して実現している. そのPythonスクリプトの設定ファイルを編集するために,まずは現在の設定をpbs_cgroups.json というファイルにエクスポートする.

$ sudo  /opt/pbs/bin/qmgr -c "export hook pbs_cgroups application/x-config default" > pbs_cgroups.json

設定の変更が, 以下のように修正する.

  • devices の enabled をtrueに変更 (cgroupによるデバイスのアクセス制限を有効化)
  • devices の allow にnvidia-uvm等のデバイスを追加 (nvidia-docker関連のデバイスは常にアクセスを許可する)
  • メモリ確保は面倒なので memory の enabled を false に.

device の書き方は以下のようになっている. 実際に ls -l してみると nvidia 関連は 195 になっている. <URL:https://www.altairjp.co.jp/pdfs/pbsworks/PBSAdminGuide2020.1.pdf> 参照.

p.578-579
  The allow parameter specifies how access to devices will be controlled. The list consists of entries in one of the follow- ing formats:
  • A single string entry, used verbatim. For example:
  • “b *:* rwm” allows full access (read, write, and mknod) to all block devices
  • “c *:* rwm” allows full access to all character devices

  with that major number.
  • If ls /dev/nvidiactl reported
  “crw-rw-rw- 1 root root 284, 1 Mar 30 14:50 nvidiactl”
  then the line added to the allow file looks like
  “c 284:* rwm”

p.589-590

  15.5.5.1.ii Isolating NVIDIA GPUs
  For NVIDIA GPU isolation to work, you need to restrict access to only those devices assigned to the job. 
  In the “allow” subsection of the devices stion of the configuration file, do not use the broad “c *:* rwm”.

  Make sure that the “allow” section excludes read and write access for the 195 major number (“c 195:* m”), 
  which is what all NVIDIA devices use. Preserve mknod (“m”) access, since other software such as the container hook may need “m” access.

エクスポートしたファイルを以下のように修正する. <URL:https://www.altairjp.co.jp/pdfs/pbsworks/PBSAdminGuide2020.1.pdf> p.590 の記述に従うが, “b *:* m”, “c *:* m”, が入っているとうまくいかなかったので, そこは削除する. また, キャラクタデバイスの 136 は本システムにないので削除しても良さそうな気がするが, とりあえず残しておいた.

$ sudo vi pbs_cgroups.json

     ...(略)...

     "devices" : {
         "enabled"            : true,
         "exclude_hosts"      : [],
         "exclude_vntypes"    : [],
         "allow"              : [
             "c 195:* m",
             "c 136:* rwm",                
             ["fuse","rwm"],
             ["net/tun","rwm"],
             ["tty","rwm"],
             ["ptmx","rwm"],
             ["console","rwm"],
             ["null","rwm"],
             ["zero","rwm"],
             ["full","rwm"],
             ["random","rwm"],
             ["urandom","rwm"],
             ["cpu/0/cpuid","rwm","*"],
             ["nvidia-modeset", "rwm"],
             ["nvidia-uvm", "rwm"],
             ["nvidia-uvm-tools", "rwm"],
             ["nvidiactl", "rwm"]
         ]
     },
     ...(略)...

作成した設定ファイル pbs_cgroups.json をPBSProにインポートする.

$ sudo /opt/pbs/bin/qmgr -c "import hook pbs_cgroups application/x-config default pbs_cgroups.json"

cgroups のためのhookを有効化

$  sudo /opt/pbs/bin/qmgr -c "set hook pbs_cgroups enabled = true"

PBSを再起動し,設定を反映させる.

$ sudo systemctl restart pbs

cgroups がv2 だと制限がかからないので,以下のようにして v1 に変更する.

※この作業はログインノードと計算ノードの両方で行う必要がある.

$ sudo vi /etc/default/grub

   以下のようにする
   GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"

$ sudo update-grub
$ sudo reboot

再起動後の確認

$ sudo /opt/pbs/bin/qmgr -c "list hook"

  Hook pbs_cgroups
     type = site
     enabled = true   <-- ここを確認
     ...(略)...

$ stat -fc %T /sys/fs/cgroup/

  tmpfs が出力されれば OK (cgroup2fs が出力された場合は cgroups v2 のまま変更されていない)

GPU 用の queue の追加設定

GPU 利用のキューの作成

# /opt/pbs/bin/qmgr -c "create queue gpu queue_type=execution"
# /opt/pbs/bin/qmgr -c "set queue gpu enabled=True"
# /opt/pbs/bin/qmgr -c "set queue gpu priority=30"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_default.nodes=1"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_default.ncpus=1"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_default.ngpus=1"   
# /opt/pbs/bin/qmgr -c "set queue gpu resources_max.nodes=1"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_max.ncpus=8"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_max.ngpus=1"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_default.walltime=120:00:00"
# /opt/pbs/bin/qmgr -c "set queue gpu started=True"
# /opt/pbs/bin/qmgr -c "set queue gpu resources_default.mem=50gb"

全体設定

# /opt/pbs/bin/qmgr -c "set server default_queue = gpu"

確認

$ /opt/pbs/bin/qmgr -c "p s"


#  /opt/pbs/bin/pbsnodes -aS

  vnode           state           OS       hardware host            queue        mem     ncpus   nmics   ngpus  comment
  --------------- --------------- -------- -------- --------------- ---------- -------- ------- ------- ------- ---------
  ncsv1           free            --       --       ncsv1           --            756gb     256       0       2 --
  ncsv2           free            --       --       ncsv2           --            251gb      32       0       3 --

# /opt/pbs/bin/qstat -Qf

  Queue: cpu
      queue_type = Execution
      Priority = 30
      total_jobs = 0
      state_count = Transit:0 Queued:0 Held:0 Waiting:0 Running:0 Exiting:0 Begun
          :0 
      resources_max.ncpus = 64
      resources_max.ngpus = 0
      resources_max.nodes = 1
      resources_default.mem = 50gb
      resources_default.ncpus = 1
      resources_default.ngpus = 0
      resources_default.nodect = 1
      resources_default.nodes = 1
      resources_default.walltime = 120:00:00
      enabled = True
      started = True

   Queue: gpu
      queue_type = Execution
      Priority = 30
      total_jobs = 0
      state_count = Transit:0 Queued:0 Held:0 Waiting:0 Running:0 Exiting:0 Begun
          :0 
      resources_max.ncpus = 8
      resources_max.ngpus = 1
      resources_max.nodes = 1
      resources_default.ncpus = 1
      resources_default.ngpus = 1
      resources_default.nodect = 1
      resources_default.nodes = 1
      resources_default.walltime = 120:00:00
      enabled = True
      started = True

cgroups による制限のテスト

複数実行してみて,各ノードにて実行されていること,GPU が 1 基しか見えないことを確認するを用いて実行

$ echo 'sleep 20; hostname; echo CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES; nvidia-smi ' | qsub -q gpu -l select=1:ncpus=1:ngpus=1
$ echo 'sleep 20; hostname; echo CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES; nvidia-smi ' | qsub -q gpu -l select=1:ncpus=1:ngpus=1

$ cat STDOUT.o*

PBS でジョブ投入テスト

"--gpus all" を付けてしまうと,全 GPU が見えてしまう.

$ echo 'docker run --gpus 'device=0' --rm nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi -L' |  qsub -q gpu -l select=1:ncpus=1:ngpus=1
$ echo 'docker run --gpus all --rm nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi -L' |  qsub -q gpu -l select=1:ncpus=1:ngpus=1

$ cat STDIN.o2016
  GPU 0: Tesla V100S-PCIE-32GB (UUID: GPU-8a30728d-e5e5-a945-aeeb-410b8dd12855)

$ cat STDIN.o2017
  GPU 0: Tesla V100S-PCIE-32GB (UUID: GPU-8a30728d-e5e5-a945-aeeb-410b8dd12855)
  GPU 1: Tesla V100S-PCIE-32GB (UUID: GPU-c6d14151-65dd-a54b-accb-7419b3a7a457)

docker での GPU 制限

<URL:https://github.com/puyogo-suzuki/gpudocker-inside-batchsys> を利用する (Thanks to Suzuki-kun).

元々のパスを確認

$ which docker
  /usr/bin/docker

各ノードで以下を実行する.

$ wget https://raw.githubusercontent.com/puyogo-suzuki/gpudocker-inside-batchsys/main/docker.sh
$ sudo mv docker.sh /usr/local/bin/docker
$ sudo chmod 755 /usr/local/bin/docker

パスが正しく設定されているか確認する.

$ which docker
 /usr/local/bin/docker

但し, /usr/local/bin/docker の 54 行目はフルパス (/usr/bin/docker) に書き換えた.

実際に試してみる. GPU 数に制限がかかっていることがわかる.

$ echo 'docker run --gpus all --rm nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi -L' |  qsub -q gpu -l select=1:ncpus=1:ngpus=1:host=ncsv1
$ echo 'docker run --gpus all --rm nvidia/cuda:12.1.1-runtime-ubuntu22.04 nvidia-smi -L' |  qsub -q gpu -l select=1:ncpus=1:ngpus=1:host=ncsv2

$ cat STDIN.o2019

  ncsv2
  GPU 0: Tesla V100S-PCIE-32GB (UUID: GPU-c0cf94f2-e63f-2c04-f286-43b7d3cd746f)

現在は使っていないが使うと良さそうな設定

各キューを実行できるホストを登録する. 設定すると, 当該キューは設定されたホストでしか実行できなくなる.

# /opt/pbs/bin/qmgr -c "set node ncsv2 queue = gpu"
# /opt/pbs/bin/qmgr -c "set node ncsv3 queue = gpu"
# /opt/pbs/bin/qmgr -c "set node ncsv4 queue = gpu"

キューの実行数の制限

# qmgr -c "set queue QNAME max_running = 10"

各キューについてユーザの実行可能数を制限

# qmgr -c "set queue QNAME max_user_run = 3"

各キューについてユーザの実行可能数な制限を解除

# qmgr -c "unset queue QNAME max_user_run