OpenPBSの機能として1つの計算機を仮想的に2つ以上にする機能がある
Torqueで言うところのNUMA対応TORQUE#e6cf152cっぽいこと.
だがTorqueではCPUリソースにつてはNUMAを活用して仮想的に1つのマシンを複数の計算ノードに仕立てることができるもののGPUリソースの分割はダメでした.

ここではOpenPBSを用いてGPUリソースを分配できるかを調べてみた.

具体例としては 8GPU マシンを 4GPUと4GPUの2台として扱えるようにしたい とか

OpenPBSのバージョンは「20.0.1」とします.
*当初 18.1.4を対象にしてましたが、どうもうまくいかない. GPUの取り扱いに問題があるみたい

下拵え

良くないけどrootで作業してます.

mkdir -p ~/rpmbuild/{SOURCES,SPECS}
git clone https://github.com/openpbs/openpbs
cd openpbs/
git checkout -b v20.0.1 refs/tags/v20.0.1
cd ..
tar cvfz ~/rpmbuild/SOURCES/openpbs-20.0.1.tar.gz openpbs --transform 's/openpbs/openpbs-20.0.1/' --exclude "openpbs/.git*"
cp openpbs/openpbs.spec rpmbuild/SPECS/

openpbs.specを調整します.

--- rpmbuild/SPECS/openpbs.spec.orig    2021-01-03 12:36:41.439212969 +0900
+++ rpmbuild/SPECS/openpbs.spec 2021-01-03 14:43:11.884731139 +0900
@@ -56,7 +56,7 @@
 %endif
 
 %if !%{defined pbs_home}
-%define pbs_home /var/spool/pbs
+%define pbs_home /var/lib/pbs
 %endif
 
 %if !%{defined pbs_dbuser}

そしてrpmbuildを実行します

rpmbuild -ba rpmbuild/SPECS/openpbs.spec

完成品は rpmbuild/RPMS/x86_64/ に用意されます.

インストール

OpenPBSの構築OpenPBS#e96e9feeを参照
ジョブ管理ノードで qmgr を実行して
計算ノード追加「create node <計算ノード>」と
ジョブ管理ノード以外からのジョブ発行を許可する「set server flatuid = True」を忘れずに

GPU resource の定義

OpenPBS/GPUとほぼ同じ内容です
「pbsnode」コマンドを実行すると

[illya@client ~]$ pbsnodes -aS
vnode           state           OS       hardware host            queue        mem     ncpus   nmics   ngpus  comment
--------------- --------------- -------- -------- --------------- ---------- -------- ------- ------- ------- ---------
s               free            --       --       s               --             31gb       8       0       0 --
[illya@client ~]$

と「ngpus」項目があるのですが、これを使うにはジョブ管理ノードで追加設定が必要です

[root@openpbs ~]# qmgr -c "create resource ngpus type=long, flag=nh"              <-- gpuの数をリソースとして加えてます
[root@openpbs ~]# vi /var/lib/pbs/sched_priv/sched_config
- resources: "ncpus, mem, arch, host, vnode, aoe"
+ resources: "ncpus, mem, arch, host, vnode, aoe, ngpus"                          <-- 280行目に「ngpus」を加える
[root@openpbs ~]# systemctl restart pbs                                           <-- サービス再起動

計算ノードにはGPUが2枚あるので、同じくジョブ管理ノードでその計算ノードの「ngpus」を定義します

[root@openpbs ~]# qmgr -c "set node s resources_available.ngpus=2"

確認してみます

[illya@client ~]$ pbsnodes -aS
vnode           state           OS       hardware host            queue        mem     ncpus   nmics   ngpus  comment
--------------- --------------- -------- -------- --------------- ---------- -------- ------- ------- ------- ---------
s               free            --       --       s               --             31gb       8       0       2 --
[illya@client ~]$

hookの定義

OpenPBS/GPU#lc0e0adfと同じようにジョブ管理ノードにて

qmgr -c "export hook pbs_cgroups application/x-config default" > pbs_cgroups.json

として、書き出した「pbs_cgroups.json」を下記のように修正して

--- pbs_cgroups.json.orig       2021-01-03 15:07:58.958825413 +0900
+++ pbs_cgroups.json    2021-01-03 15:08:34.464036568 +0900
@@ -24,12 +24,28 @@
             "memory_spread_page" : false
         },
         "devices" : {
-            "enabled"            : false,
+            "enabled"            : true,
             "exclude_hosts"      : [],
             "exclude_vntypes"    : [],
             "allow"              : [
-                "b *:* rwm",
-                "c *:* rwm"
+                "c 195:* m",
+                "c 136:* rwm",
+                ["infiniband/rdma_cm","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"]
             ]
         },
         "hugetlb" : {

それを元に戻して、hookを有効にする

qmgr -c "import hook pbs_cgroups application/x-config default pbs_cgroups.json"
qmgr -c "set hook pbs_cgroups enabled = true"

これでジョブ管理システム全体でhookが有効になります.

vnode設定

NUMAでGPUが組み合わせ出来るなら「vnode_per_numa_node」を定義すれが使えそうで
「lscpu」コマンドで

NUMA node0 CPU(s):     0-7
NUMA node1 CPU(s):     8-15

と表記され、「nvidia-smi topo -m」から

        GPU0    GPU1    GPU2    GPU3    CPU Affinity
GPU0     X      PHB     SYS     SYS     0-7
GPU1    PHB      X      SYS     SYS     0-7
GPU2    SYS     SYS      X      PHB     8-15
GPU3    SYS     SYS     PHB      X      8-15

と表記されたならNUMA単位でGPUが分割されるかと思われる.
っが、実機が手元にないので未検証

上記はNUMAでGPUが奇麗に分割されているのでいいのですが、NUMAが1つしかない場合とかもあり
その場合は次の方法が使えるみたい.

GPUを持つジョブ実行ノードに設定ファイルを読ませて対応させる方法

初めにジョブ管理ノードで ngpus に加えて gpu_id カスタムリソースを加えます

[root@openpbs ~]# qmgr -c "create resource gpu_id type=string, flag=h"
[root@openpbs ~]# vi /var/lib/pbs/sched_priv/sched_config
- resources: "ncpus, mem, arch, host, vnode, aoe, eoe, ngpus"
+ resources: "ncpus, mem, arch, host, vnode, aoe, eoe, ngpus, gpu_id"
 
[root@openpbs ~]# systemctl restart pbs

設定ファイルはこんな感じ
*ジョブ実行ノード毎に行います

[root@s ~]# vi s_vnodes
$configversion 2
s: resources_available.ncpus = 0
s: resources_available.mem = 0
s: resources_available.ngpus = 0
s[0]: resources_available.ncpus = 3
s[0]: resources_available.mem = 16gb
s[0]: resources_available.ngpus = 1
s[0]: resources_available.gpu_id = gpu0
s[0]: sharing = default_excl
s[1]: resources_available.ncpus = 1
s[1]: resources_available.mem = 16gb
s[1]: resources_available.ngpus = 1
s[1]: resources_available.gpu_id = gpu1
s[1]: sharing = default_excl
 
[root@s ~]#

そして

[root@s ~]# pbs_mom -s insert vnodes_20201228 s_vnodes
 
[root@s ~]# systemctl restart pbs

と実行する. すると「s_vnodes」の内容が「/var/lib/pbs/mom_priv/config.d/vnodes_20201228」として保存されます。
反映にはジョブ実行ノードのデーモンの再起動が必要です

暫くすると

[illya@client ~]$ pbsnodes -aSv
vnode           state           OS       hardware host            queue        mem     ncpus   nmics   ngpus  comment
--------------- --------------- -------- -------- --------------- ---------- -------- ------- ------- ------- ---------
s               free            --       --       s               --             31gb       4       0       2 --
s[0]            free            --       --       s               --             16gb       3       0       1 --
s[1]            free            --       --       s               --             16gb       1       0       1 --
 
[illya@client ~]$

となる.

元に戻すにはジョブ実行ノードで設定ファイルを取り消してデーモンを再起動して

[root@s ~]# pbs_mom -s remove vnodes_20201228
 
[root@s ~]# systemctl restart pbs

次にジョブ管理ノードで

[root@openpbs ~]# qmgr -c "delete node s[0]"
[root@openpbs ~]# qmgr -c "delete node s[1]"

でvnode自体を削除する必要があります. これで元に戻ります


一応GPUノードを仮想的に複数に分割してGPUデバイスを排他的に分配できた.
特定の仮想ノードへのジョブ投入は

qsub -q workq -l select=vnode=s[1]:ncpus=1:ngpus=1 -I

で行けるみたい.


トップ   編集 添付 複製 名前変更     ヘルプ   最終更新のRSS
Last-modified: 2021-01-03 (日) 17:30:17 (54d)