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を実行します
rpmbuild -ba rpmbuild/SPECS/openpbs.spec完成品は rpmbuild/RPMS/x86_64/ に用意されます.
OpenPBSの構築OpenPBS#e96e9feeを参照
ジョブ管理ノードで qmgr を実行して
計算ノード追加「create node <計算ノード>」と
ジョブ管理ノード以外からのジョブ発行を許可する「set server flatuid = True」を忘れずに
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 ~]$OpenPBS/GPU#lc0e0adfと同じようにジョブ管理ノードにて
qmgr -c "export hook pbs_cgroups application/x-config default" > pbs_cgroups.jsonとして、書き出した「pbs_cgroups.json」を下記のように修正して
|
それを元に戻して、hookを有効にする
qmgr -c "import hook pbs_cgroups application/x-config default pbs_cgroups.json"
qmgr -c "set hook pbs_cgroups enabled = true"これでジョブ管理システム全体でhookが有効になります.
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で行けるみたい.