Diskless並列計算機の製作

目次



はじめに

2020年10月、これまで使っていた2014年作製の自作並列計算機を増設して、計 算資源を増強しました。その時のメモです。2014年に構築した時のメモは、旧 並列計算機メモに残しています。旧並列計算機(silicon)は1台故障(BIOSが起 動しない)しましたが元気に計算を続けています。今回は、この並列計算機に 最近のPC構成で16ノード追加します。旧並列計算機と新並列計算機は、計算能 力が違うのでキューを分けて運用することにします。またsiliconの親ノード も子ノードに入れ、研究室に転がっていたi5コアのPCを2つ加えてsiliconは17 ノードとします。

image.png

更新履歴

2020/10/27

  • siliconとgermaniumでクラスタ構築

2023/03/24

  • Linuxカーネルを5.10.0-21-amd64 (Debian11; bullseye)にした。
  • di-netboot-assistantでboot用ファイルを取得し、UEFIとPXEで起動するようにした。
  • DebianがNISをうまく設定してくれないので手動で設定(systemctl)するようにした。
  • disklessとpost-disklessを修正した。
  • inte oneAPIにコンパイラを変更した。
  • germaniumを23ノードに増設していたので説明をupdateした。
  • silicon06が死んだので外した。

ハードウェア

旧並列計算機同様にツクモから後払いで購入した。1ノードの構成は以下の通 り。この構成で16ノード分購入した。

品名 型番 価格
CPU intel Core i9-10900BOX 47,000円
マザーボード PRIMEH410ME (intel H410) 8,080円
メモリ Crucial DDR4-2666 64 Gbyte (32x2) 29,980円
電源 玄人志向 80PLUS GOLD 550W 7,320円
合計   102,388円

CPUのスペックは次のような具合です。16ノードで160コアになります。

ソケット形状 LGA1200
コア数 10 コア
スレッド数 20
クロック周波数 2.8GHz
最大クロック周波数(全コアブースト) 4.6 GHz
最大クロック周波数(シングルブースト) 5.2 GHz
TDP 65 W

子ノードを配置するラックはアルミフレームも考えたが再利用を考えて今回も アングルで作成した。子ノードをぶら下げるネットは100円ショップで購入し た。旧並列計算機も同じラックとするため、かなり広幅のラックを作製した。 ラックと子ノードの組み立てはシミュレーションをテーマとする学生に作って もらった。このマーザーボードはCSMがenableにならずUEFIだけの BIOSしか使えない曲者だった。

大まかな手順

  1. Debinaを最小構成で親ノードにインストール
  2. 親ノードと子ノードに共通のpackageをaptでインストール
  3. 子ノードのシステムとして/nfsrootに親ノードのファイルをコピー。
  4. 親ノードにnfsとnis、必要なpackageとintel compiler, openpbsをインストール
  5. 子ノードにopenpbsのインストール。不要なプロセスの停止。

親ノード

Debianのnetinstall用imgをUSBスティックに書きこんで起動する。イ ンストールメニューから(Advanced options -> Expert install)と進んでイン ストールする。ベースシステムのインストールまで順番に行う。ソフトウェア はssh-serverだけにチェックしてインストールを進める。 注意事項は、以下のとおり。

  • Graphicalインストールを選択しない。
  • ホスト名を入力する時にFQDNを入力しない。

初期設定

suでrootでログインして作業用にパスの設定。

echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /root/.bashrc

親ノードと子ノードで必要となるpackageをインストールする。

  • net-tools
  • gcc g++
  • nfs-common
apt install net-tools gcc g++ nfs-common -y

この状態を/nfsrootにコピーして、子ノードにnfsでmountさせる。

cd /
mkdir -p /nfsroot/proc
ls | grep -v -E 'proc|nfsroot|srv|sys|run' | xargs cp -ax --target-directory=/nfsroot

/etc/network/interfacesでNIC2枚分の設定をする。

vi /etc/network/interfaces
----------------------------------------------------------------------------
auto lo
iface lo inet loopback

allow-hotplug eno0
iface eno0 inet dhcp

auto eno1
iface eno1 inet static
  address   192.168.1.1
  network   192.168.1.0
  netmask   255.255.255.0
  broadcast 192.168.1.255
#  gateway   192.168.1.1
#  dns-nameservers 192.168.1.1
----------------------------------------------------------------------------

/etc/hostsからipv6を削除てhostnameの設定。子ノードのhostnameは後で追加。

vi /etc/hosts
----------------------------------------------------------------------------
127.0.0.1       localhost
192.168.1.1     germanium

vi /etc/hostname
----------------------------------------------------------------------------
germanium

ipv6の無効化するため、/etc/sysctl.confに追加。

vi /etc/sysctl.conf 
----------------------------------------------------------------------------
net.ipv6.conf.all.disable_ipv6 = 1
----------------------------------------------------------------------------

tftpd-hpa

pxeboot用にtftpd-hpaをインストール。配布ファイルは/tftprootに配置。

apt install tftpd-hpa -y
vi /etc/default/tftpd-hpa
----------------------------------------------------------------------------
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftproot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"

mkdir /tftproot
chmod 777 /tftproot

netbootインストール用のファイルをdi-netboot-assistant使ってダウンロー ドする。そのままではインストールがスタートするのでbootするように書き換 える。PXEとUEFIどちらでも対応するようにする。pxelinux.cfg/default(PXE 用)とgrub/grub.cfg(UEFI用)は全部消して、内容入れ替える。

apt install di-netboot-assistant -y
di-netboot-assistant --tftproot=/tftproot install bullseye
vi /tftproot/d-i/n-a/pxelinux.cfg/default
----------------------------------------------------------------------------
LABEL linux
DEFAULT vmlinuz root=/dev/nfs initrd=initrd.img nfsroot=192.168.1.1:/nfsroot ip=dhcp rw

vi /tftproot/d-i/n-a/grub/grub.cfg
----------------------------------------------------------------------------
if loadfont $prefix/font.pf2 ; then
  set gfxmode=800x600
  insmod efi_gop
  insmod efi_uga
  insmod video_bochs
  insmod video_cirrus
  insmod gfxterm
  terminal_output gfxterm
fi

insmod play
play 960 440 1 0 4 440 1

set default='Boot from local disk..'
set timeout=1

menuentry 'Debian boot' {
    linux /d-i/n-a/vmlinuz root=/dev/nfs nfsroot=192.168.1.1:/nfsroot ip=dhcp rw
    initrd /d-i/n-a/initrd.img
}

boot用のファイルをinstallして/tftprootに配置。

apt install pxelinux syslinux -y
cp /boot/vmlinuz-5.10.0-21-amd64 /tftproot/d-i/n-a/vmlinuz
cp /usr/lib/PXELINUX/pxelinux.0 /tftproot/d-i/n-a/pxelinux.0
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /tftproot/d-i/n-a/ldlinux.c32

vi /etc/initramfs-tools/initramfs.conf
----------------------------------------------------------------------------
#MODULES=most
MODULES=netboot
----------------------------------------------------------------------------
mkinitramfs -o /tftproot/d-i/n-a/initrd.img
/etc/init.d/tftpd-hpa restart

nfs-server

/nftrootで公開。

apt install nfs-server -y
vi /etc/exports
----------------------------------------------------------------------------
/nfsroot    192.168.1.0/24(rw,async,no_root_squash,no_subtree_check)
/opt        192.168.1.0/24(rw,async,no_root_squash,no_subtree_check)
/home       192.168.1.0/24(rw,async,no_root_squash,no_subtree_check)
/usr/local  192.168.1.0/24(rw,async,no_root_squash,no_subtree_check)
----------------------------------------------------------------------------
/etc/init.d/nfs-kernel-server restart

NFSはv4ではなくv3を使う。

vi /etc/default/nfs-kernel-server
----------------------------------------------------------------------------
RPCNFSDCOUNT=32
RPCMOUNTDOPTS="--manage-gids --no-nfs-version 4"
RPCNFSDOPTS="-N 2 --no-nfs-version 4 -N 4"
/etc/init.d/nfs-kernel-server restart

nis-server

設定に必要なファイル。

  • /etc/default/nis
  • /etc/ypserv.securenets
  • /etc/defaultdomain

nisのインストール

apt install nis -y

Domainの指定

vi /etc/defaultdomain
----------------------------------------------------------------------------
lab10.tf.chiba-u.jp
vi /etc/yp.conf
----------------------------------------------------------------------------
domain lab10.tf.chiba-u.jp server 192.168.1.1

nisでuserを共有する。

vi /etc/default/nis
----------------------------------------------------------------------------
NISSERVER=master
YPBINDARGS=-no-dbus
----------------------------------------------------------------------------

nisに応答するnetworkを制限しておく。

vi /etc/ypserv.securenets 
----------------------------------------------------------------------------
# 0.0.0.0 0.0.0.0
255.255.255.0   192.168.1.0
----------------------------------------------------------------------------

shadowに変更があってもmakeするようしておく。domainnameでdomain引けるか 確認しとく。

vi /var/yp/Makefile
----------------------------------------------------------------------------
-ALL = passwd group hosts rpc services netid protocols netgrp
+ALL = passwd shadow group hosts rpc services netid protocols netgrp 
----------------------------------------------------------------------------
/etc/init.d/ypserv restart
/usr/lib/yp/ypinit -m

自動起動のサービスとしてypservが登録されているか確認。されていないならenableにする。

systemctl list-unit-files --type=service | grep ypserv
systemctl enable ypserv

isc-dhcpd

dhcpdのインストール。2つのnicにip addressが正しく割り当てていないと dhcpdが起動しないので注意。

apt install isc-dhcp-server -y
vi /etc/dhcp/dhcpd.conf
----------------------------------------------------------------------------
option domain-name "lab10.tf.chiba-u.jp";
option domain-name-servers 10.245.1.95, 10.97.1.95, 10.129.1.95;
default-lease-time -1;
max-lease-time -1;
authoritative;
log-facility local7;
option space PXE;
option PXE.mtftp-ip               code 1 = ip-address;  
option PXE.mtftp-cport            code 2 = unsigned integer 16;
option PXE.mtftp-sport            code 3 = unsigned integer 16;
option PXE.mtftp-tmout            code 4 = unsigned integer 8;
option PXE.mtftp-delay            code 5 = unsigned integer 8;
option arch code 93 = unsigned integer 16; # RFC4578

subnet 192.168.1.0 netmask 255.255.255.0 {
  class "pxeclients" {
    match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
    next-server 192.168.1.1;
    if option arch = 00:07 {
        filename "d-i/n-a/bootnetx64.efi";
    } else {
        filename "d-i/n-a/pxelinux.0";
    }
  }
  pool {
    max-lease-time -1;
    default-lease-time -1;
    range 192.168.1.2 192.168.1.254;
    deny unknown clients;
  }
}
# all slave nodes.
host node1 {
  hardware ethernet 08:62:66:49:64:9C;
  fixed-address 192.168.1.101;
}
host node2 {
  hardware ethernet 3C:7C:3F:10:A9:DB;
  fixed-address 192.168.1.102;
}
----------------------------------------------------------------------------

起動に失敗する場合はreconfigureしてdhcpdが待ち受けるnicを指定する。ま たdhcpを待ち受けるnicにipアドレスが振られていなくても起動に失敗するよ うだ。

dpkg-reconfigure isc-dhcp-server
/etc/init.d/isc-dhcp-server restart

GWの設定

一時的にGWになってslave-nodeを外部と接続する。eno1は外側のNIC。

apt install iptables -y
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE

GWの必要がなくなったら後片付け。

echo 0 > /proc/sys/net/ipv4/ip_forward

/nfsroot下の設定

/nfsroot以下ののslave-nodeの/etcを設定。nicの設定しない場合は勝手に dhcpで接続してくれるようだ。nfsでmountさせるためにfstabを設定しておく。 後で設定するopenpbsのHOMEディレクトリは子ノードで共有できたなためtmpfs とする。

vi /nfsroot/etc/network/interfaces
----------------------------------------------------------------------------
auto lo
iface lo inet loopback
----------------------------------------------------------------------------

vi /nfsroot/etc/fstab
----------------------------------------------------------------------------
/dev/nfs         / nfs tcp,nolock 0 0
proc /proc       proc  defaults 0 0
none /tmp        tmpfs defaults 0 0
none /var/tmp    tmpfs defaults 0 0
none /var/spool  tmpfs defaults 0 0
none /media      tmpfs defaults 0 0
none /var/log    tmpfs defaults 0 0
192.168.1.1:/opt /opt             nfs rw,noatime,nolock,nfsvers=3 0 0
192.168.1.1:/usr/local /usr/local nfs rw,noatime,nolock,nfsvers=3 0 0
192.168.1.1:/home /home           nfs rw,noatime,nolock,nfsvers=3 0 0
----------------------------------------------------------------------------

ここまでできたら、子nodeをpxe起動してみて正しくbootできるか確認する。 うまく子ノードが起動したら、念のためtarで固めて初期状態の/nfsrootを保 存しておく。

tar czf /root/nfsroot_original.tgz /nfsroot

子ノード

親ノードでうまく設定できたら子ノードの電源を入れてpxe bootする。起動が 確認できたら、子ノードにログインして作業を進める。tmpfs以外のファイル を修正すると実際は親ノードの/nftroot下が書き換わっていることに注意する。

networkの設定

aptで外部からファイルをダウンロードする必要が生じて、外ネットに接続す る時はroutingテーブルを設定する。基本、外部との接続は不要なので必要な くなったらrouteは削除しておく。

route add default gw 192.168.1.1 enp2s0

使い終わったら後片付けする。

route del default gw 192.168.1.1

/etc/hostsと/etcdefaultdomainを編集しておく。

vi /etc/hosts
----------------------------------------------------------------------------
127.0.0.1	localhost

vi /etc/defaultdomain
----------------------------------------------------------------------------
lab10.tf.chiba-u.jp

nis-client

ユーザは親ノードで管理するため、nisでユーザ情報を共有する。

apt install nis

/etc/yp.confに以下のラインを追加

vi /etc/yp.conf  # 最終ラインに追加
----------------------------------------------------------------------------
domain lab10.tf.chiba-u.jp server 192.168.1.1

/etc/nsswitch.confにnisを追加

vi /etc/nsswitch.conf
----------------------------------------------------------------------------
passwd:         files nis
group:          files nis
shadow:         files nis
gshadow:        files nis

hosts:          files nis dns

以下のコマンドで、nisサーバの情報が引けるか確認する。

ypwhich
ypcat passwd
ypcat hosts

自動起動のサービスとしてypbindが登録されているか確認。されていないならenableにする。

systemctl list-unit-files --type=service | grep ypbind
systemctl enable ypbind

初期化サービスの登録

hostnameをdhcpで割り振られたipアドレスに従ってセットするようスクリプト (diskless)を作成して設置する。

旧並列計算機(silicon)の4コア子ノードのipアドレスの範囲は 192.168.1.21-50とし、hostnameはsiliconXXとする。新設する子ノードは 192.168.1.51以降でgermaniumXXとする。

vi /nfsroot/etc/init.d/diskless
----------------------------------------------------------------------------
#!/bin/sh
### BEGIN INIT INFO
# Provides:          diskless
# Should-Start:      $sshd
# Default-Start:     3 5
# Default-Stop:      0 1 2 4 6
# Short-Description: Set hostname
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO
# Author: Takahiro Ohkubo 

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service for diskless server"
NAME=hostname_and_mount

case "$1" in
    start)
        export LC_ALL=C
        IP=`ip address |grep inet|grep -v inet6 |grep -v 127.0.0.1 | \
            awk '{print $2}'| cut -d'.' -f4| cut -d'/' -f1`
        if [ 20 -lt $IP ] && [ $IP -lt 50 ]; then
            IP_=`expr $IP - 20`
	    HOSTNAME=`printf "silicon%01d" $IP_`
        elif [ 50 -lt $IP ] && [ $IP -lt 100 ]; then
            IP_=`expr $IP - 40`
	    HOSTNAME=`printf "germanium%02d" $IP_`
        else
            BASE="UNKNOWN"
	    HOSTNAME=`printf "UNKNOWN%02d" $IP_`
        fi
        if [ `hostname` = $HOSTNAME ]; then
            echo "script has been run"
            exit 1
        else
            hostname $HOSTNAME
        fi
      ;;
  stop)
      umount /usr/local
      umount /home
      umount /var/spool/torque
      ;;
  *)
      echo "usage: diskless.sh start|stop"
      ;;
esac
----------------------------------------------------------------------------
chmod 755 /etc/init.d/diskless
update-rc.d diskless defaults

pbs

openpbsはの起動スクリプトは/etc/init.d/pbsにインストールされる。このス クリプトは、pbsのホームディレクトリ(/var/spool/pbs)が存在しない場合、 次のスクリプトを実行して、/var/spool/pbsを作成する。

/usr/local/libexec/pbs_postinstall server 20.0.0 /usr/local /var/spool/pbs '' sameconf

子ノードの/var/spoolはtmpfsとしているので、起動のたびにクリアされる。 そのため、起動スクリプトpost-disklessを作成して以下のファイルを起動の 度に編集することにする。

  • /var/spool/pbs/mom_priv/config
  • /var/spool/pbs/pbs_environment

また/var/logはtmpfsでmountしており、logファイルのサイズが大きくなって メモリを圧縮しても困るので/dev/nullにシンボリックリンクを貼るようにし ておく。Should-Start: $sshd pbsで/etc/init.d/pbsを実行してから post-disklessを実行するよう設定している。

vi /etc/init.d/post-diskless
----------------------------------------------------------------------------
#!/bin/sh
### BEGIN INIT INFO
# Provides:       post-diskless
# Required-Start: $network $local_fs $remote_fs $named
# Should-Start: $sshd pbs
# Required-Stop:  $network $local_fs $remote_fs $named
# Default-Start:  3 5
# Default-Stop:   0 1 2 4 6
# Description:    post diskless
### END INIT INFO
# Author: Takahiro Ohkubo

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service for post script"
NAME=hostname_and_mount

case "$1" in
    start)
        echo '$logevent 0x0' >> /var/spool/pbs/mom_priv/config
        echo '$usecp *:/home/ /home/' >> /var/spool/pbs/mom_priv/config
        echo 'TZ="Asia/Tokyo"' >> /var/spool/pbs/pbs_environment
        /etc/init.d/pbs restart
        rm /var/log/btmp
        rm /var/log/lastlog
        rm /var/log/wtmp
        ln -s /dev/null /var/log/btmp
        ln -s /dev/null /var/log/lastlog
        ln -s /dev/null /var/log/wtmp
        ;;
  stop)
        ;;
  *)
        echo "usage: post_diskless start|stop"
        ;;
esac
----------------------------------------------------------------------------
chmod 755 /etc/init.d/post-diskless
update-rc.d post-diskless defaults

不要サービス停止

自動起動になっているサービスを調べる。

systemctl list-unit-files --type=service

sshとnfs関係を除いてenableになっているものはすべてdisableにする。

systemctl disable apparmor.service
systemctl disable autovt@.service
systemctl disable console-setup.service
systemctl disable cron.service
systemctl disable getty@.service
systemctl disable keyboard-setup.service
systemctl disable rsyslog.service

さらにstaticになっているものはmaskして起動させない。

systemctl mask systemd-timesyncd.service
systemctl mask systemd-journal-flush.service
systemctl mask systemd-journald.service
systemctl mask udevd.service
systemctl mask systemd-udevd
systemctl mask dbus-org.freedesktop.hostname1.service
systemctl mask dbus-org.freedesktop.locale1.service
systemctl mask dbus-org.freedesktop.login1.service
systemctl mask dbus-org.freedesktop.timedate1.service
systemctl mask dbus.service

子ノードはコンソールからログインできなくなるが、どうせsshでしかログイ ンしないので気にしない。残りのプロセスはこれだけ。

$ ps ax|grep -v '\[' | grep -v ps |grep -v grep
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:01 /sbin/init
  265 ?        Ss     0:00 /sbin/rpcbind -f -w
  332 ?        Sl     0:00 /usr/sbin/ypbind
  370 ?        Ssl    0:00 /usr/local/sbin/pbs_mom
 2095 ?        Ss     0:00 /usr/sbin/sshd -D
 2675 ?        S      0:00 sshd: takahiro@pts/0
 2676 pts/0    Ss     0:00 -bash
  308 ?        S      0:00 sshd: takahiro@pts/0

openpbs

親ノード

  • この記事がよくまとまっていて参考にさせてもらいました。

https://qiita.com/MasafumiTsuyuki/items/acf4b19b54937496e32b

  • レファレンスマニュアル

https://www.altair.com/pbs-works-documentation/

親ノードにコンパイルしてインストールしたら、子ノード用のパッケージを作 成する。defaultで/usr/local以下にインストールされ/var/spool/pbsが PBS_HOMEとなる。

openpbs配布ファイルのINSTALLにしたがってBullseyeで必要になるpackageを インストールする。fileの取得に必要なgitとクライアント用のパッケージを 生成するdh-makeもインストールしておく。1Gbyteくらい消費します。

apt 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 -y
apt install expat libedit2 postgresql python3 \
            postgresql-contrib sendmail-bin  sudo tcl tk libical3 -y
apt install git dh-make -y

/usr/local/srcにgitでcloneを作成しコンパイルする。このサーバーを作成し た時点(2023-03-24)ではopepbsのversion20.0.0でした。PBS_HOMEはdefaultで /var/spool/pbsとなる。

cd /usr/local/src
git clone https://github.com/openpbs/openpbs
cd openpbs
./autogen.sh
./configure
make install -j4
/usr/local/libexec/pbs_postinstall

子ノード用にpackageを生成しておく。なおリンクの記事では、dpkg -iとなっ ているが、gdebiの間違いと思われる。 https://openpbs.atlassian.net/wiki/spaces/PBSPro/pages/22183970/Building+and+Packaging+PBS+on+Debian+Ubuntu

make dist
mkdir -p openpbs-client/build
tar xvzf openpbs-20.0.0.tar.gz -C openpbs-client/build
cd openpbs-client/build/openpbs-20.0.0
dh_make --createorig -s -y
dpkg-buildpackage -rfakeroot -uc -us  # 1つ上のディレクトリにdebが生成する

タイムゾーンの設定を行う。clienthostに親サーバを指定し、/homeはNFSマウ ントとなるのでscp使わないようにする。

chmod 4755 /usr/local/sbin/pbs_iff /usr/local/sbin/pbs_rcp
/usr/local/libexec/pbs_postinstall
echo TZ=\"Asia/Tokyo\" >> /var/spool/pbs/pbs_environment

親ノードでは計算を実行させないので、/etc/pbs.confのPBS_START_MOMは defaultのまま。

vi /etc/pbs.conf
----------------------------------------
PBS_SERVER=germanium
PBS_START_SERVER=1
PBS_START_SCHED=1
PBS_START_COMM=1
PBS_START_MOM=0
PBS_EXEC=/usr/local
PBS_HOME=/var/spool/pbs
PBS_CORE_LIMIT=unlimited
PBS_SCP=/usr/bin/scp
----------------------------------------

/usr/local/libをパスに追加する。

vi /etc/ld.so.conf
----------------------------------------
/usr/local/lib

ldconfig

ここまできたら親サーバーでpbs_server, pbs_sched, pbs_commが起動するか 確認する。 #+BEGIN_EXAMPLE/ /etc/init.d/pbs start /etc/init.d/pbs status #+END_EXAMPLE どれか起動しない場合は/etc/hostsを見直し、/var/spool/pbsを消してpbs_postinstallしなおす。

/usr/local/libexec/pbs_postinstall
echo TZ=\"Asia/Tokyo\" >> /var/spool/pbs/pbs_environment

子ノード

子ノードにログインして作業する。依存解決のためgdebiをインストールして から、親ノードで作成したdeb(NFSマウントしている)をインストールする。 openpbsのホームディレクトリ/var/spool/pbsは tmpfsとしてmountするので、 rebootのたびに/var/spool/pbsは消えてなくなることに注意する。 /etc/init.d/pbsに/var/spool/pbsを作ってもらって、/var/spool/pbs以下の 設定ファイルを/etc/init.d/post-disklessで起動のたびに修正する方針とす る。別解として/var/spool/pbsをどこかに固めておいて起動の度に展開しても 良いかもしれません。

/usr/local/libをパスに追加しておく。

vi /etc/ld.so.conf
----------------------------------------
/usr/local/lib

ldconfig
route add default gw 192.168.1.1 enp3s0
apt install gdebi
cd /usr/local/src/openpbs/openpbs-client/build
gdebi openpbs_20.0.0-1_amd64.deb

pbs_momをインストールする。

chmod 4755 /usr/local/sbin/pbs_iff /usr/local/sbin/pbs_rcp
/usr/local/libexec/pbs_postinstall
echo TZ=\"Asia/Tokyo\" >> /var/spool/pbs/pbs_environment

pbs.confで親ノードを指定する。pbs_momだけ動かす。

vi /etc/pbs.conf
----------------------------------------------------------------------------
PBS_SERVER=germanium
PBS_START_SERVER=0
PBS_START_SCHED=0
PBS_START_COMM=0
PBS_START_MOM=1
PBS_EXEC=/usr/local
PBS_HOME=/var/spool/pbs
PBS_CORE_LIMIT=unlimited
PBS_SCP=/usr/bin/scp
----------------------------------------------------------------------------

clienthostは親サーバを指定する。/homeはnfsマウントしているのでusecpと する。

vi /var/spool/pbs/mom_priv/config
----------------------------------------------------------------------------
$clienthost germanium
$restrict_user_maxsysid 999
$logevent 0x0
$usecp *:/home/ /home/
----------------------------------------------------------------------------

/etc/hostを確認して親ノードが引けるか確認する。

vi /etc/hosts
----------------------------------------------------------------------------
127.0.0.1       localhost

192.168.1.1   germanium
192.168.1.21  silicon01
192.168.1.22  silicon02
.
.
.
192.168.1.51  germanium01
192.168.1.51  germanium02
.
.
.
----------------------------------------------------------------------------

ここまできたら子サーバーでpbs_momが起動するか確認して起動サービスに追加 する。起動しない場合は/etc/hostsを見直す。

/etc/init.d/pbs start
/etc/init.d/pbs status
update-rc.d pbs defaults

計算ノードの登録とキューの作成

親ノードで子ノードを登録する。pbsを再起動しなくとも動的に追加できる。 削除する時はcreateでなくdeleteにする。また、defaultでは各ノードのスレッ ド数も入れたコア数(ncpu)をリソースとして確保される。そのためgermanium は物理コア数だけのリソースとして登録する。

for i in `seq 1 17`; do
  node=`printf "silicon%02d" $i`
  qmgr -c "create node $node" 
  qmgr -c "set node $node resources_available.ncpus=4"
done
for i in `seq 1 23`; do
  node=`printf "germanium%02d" $i`
  qmgr -c "create node $node" 
  qmgr -c "set node $node resources_available.ncpus=10"
done

ハードウェア性能が違う2種類のnodeが混在することになるので、2つのキュー をつくりそれぞれのキューに子ノードを割り当てる。

vi /var/spool/pbs/sched_priv/sched_config
----------------------------------------------------------------------------
#resources: "ncpus, mem, arch, host, vnode, aoe, eoe"
resources: "ncpus, mem, arch, host, vnode, aoe, eoe, queue_name"
----------------------------------------------------------------------------
/etc/init.d/pbs restart

キューの新しいリソースとしてqueue_nameを追加する。

qmgr -c "create resource queue_name type=string_array,flag=h"

キューを作成してnodeを追加する。

# silicon queueの作成
qmgr -c "create queue silicon queue_type=e,enabled=t, started=t"
qmgr -c "set queue silicon default_chunk.queue_name=silicon"
qmgr -c 'set queue silicon resources_max.ncpus=68'
qmgr -c 'set queue silicon resources_max.nodes=17'
# nodeの登録
for i in `seq 1 17`; do
     node=`printf "silicon%02d" $i`
     qmgr -c "set node $node resources_available.queue_name=silicon" # appendなら+=
done

# germanium queueの作成
qmgr -c "create queue germanium queue_type=e,enabled=t, started=t"
qmgr -c 'set queue germanium resources_max.ncpus=230'
qmgr -c 'set queue germanium resources_max.nodes=23'
qmgr -c "set queue germanium default_chunk.queue_name=germanium"
# nodeの登録
for i in `seq 1 23`; do
     node=`printf "germanium%02d" $i`
     qmgr -c "set node $node resources_available.queue_name=germanium" # appendなら+=
done

サーバーの設定をしておく。Fromのドメインがchiba-u.jpじゃないとメールサー バに蹴られるので、Fromを指定しておく。またqstatでユーザー全てのqueueを 表示するようにする。

qmgr -c "set server acl_hosts = `hostname`"
qmgr -c "set server default_queue = silicon"
qmgr -c "set server scheduling = True"
qmgr -c 'set server node_pack = True'
qmgr -c "set server mail_from=xxxxx@faculty.chiba-u.jp"
qmgr -c "set server query_other_jobs = true"

最後に設定を確認する。

qmgr -c "p s"
----------------------------------------------------------------------------
#
# Create resources and set their properties.
#
#
# Create and define resource queue_name
#
create resource queue_name
set resource queue_name type = string_array
set resource queue_name flag = h
#
# Create queues and set their attributes.
#
#
# Create and define queue silicon
#
create queue silicon
set queue silicon queue_type = Execution
set queue silicon resources_max.ncpus = 64
set queue silicon resources_max.nodes = 16
set queue silicon default_chunk.queue_name = silicon
set queue silicon enabled = True
set queue silicon started = True
#
# Create and define queue germanium
#
create queue germanium
set queue germanium queue_type = Execution
set queue germanium resources_max.ncpus = 230
set queue germanium resources_max.nodes = 23
set queue germanium default_chunk.queue_name = germanium
set queue germanium enabled = True
set queue germanium started = True
#
# Set server attributes.
#
set server scheduling = True
set server default_queue = workq
set server log_events = 511
set server mailer = /usr/sbin/sendmail
set server mail_from = xxxxx@faculty.chiba-u.jp
set server query_other_jobs = True
set server resources_default.ncpus = 1
set server default_chunk.ncpus = 1
set server scheduler_iteration = 600
set server resv_enable = True
set server node_fail_requeue = 310
set server max_array_size = 10000
set server pbs_license_min = 0
set server pbs_license_max = 2147483647
set server pbs_license_linger_time = 31536000
set server eligible_time_enable = False
set server max_concurrent_provision = 5
set server max_job_sequence_id = 9999999
----------------------------------------------------------------------------

リソースとしてqueue_nameが存在し子ノードがキューに割り当てられている確認する。

pbsnodes -a | grep queue

intelコンパイラ

inteloneAPIをインストールする。intelのサイトからofflineインストール用 のBase ToolkitとHPC Toolkitをダウンロードする。あとは、shellを実行すれ ば、/optにインストールが開始する。インストールが開始するとeclipseや graphics用のライブラリのインストールが求められるが、無視してインストー ルしててもよい。

apt install libnss3 libgbm1 -y
bash l_BaseKit_p_2023.0.0.25537_offline.sh
bash l_HPCKit_p_2023.0.0.25400_offline.sh

ecliseとlibgdk等は不要なのでインストールしない。 fftw用のCとfortran用のwrapperを作っておく。

コンパイルする時は、環境変数等をセットしてくれる付属スクリプトを実行する。

source /opt/intel/oneapi/setvars.sh

ただし、このスクリプトは無駄に遅いので、.bashrcに登録したくない。 oneAPIで実行したバイナリを実行するだけなら、以下の.bashrcに追加しとく。

#source /opt/intel/oneapi/setvars.sh > /dev/null
ONEAPI=/opt/intel/oneapi
export PATH=ONEAPI/mpi/2021.8.0/bin:$PATH
export LD_LIBRARY_PATH=$ONEAPI/mkl/2023.0.0/lib/intel64/:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$ONEAPI/compiler/2023.0.0/linux/compiler/lib/intel64_lin:$LD_LIBRARY_PATH

FFTW3用のwrapper

cd /opt/intel/oneapi/mkl/2023.0.0/interfaces/fftw3xc
make libintel64
cd /opt/intel/oneapi/mkl/2023.0.0/interfaces/fftw3xf
make libintel64
cd /opt/intel/oneapi/mkl/2023.0.0/interfaces/mklmpi
make libintel64

exim4

openpbsからのお知らせをメールで連絡するよう送信サーバの設定する。外部の smtpサーバを経由してメールを送信する(smart smtp)。

apt install exim4
dpkg-reconfigure exim4-config
/etc/init.d/exim4 restart

送信テスト

fromをhoge@hoge.comでdist@huga.jpにメールを出す。

mail -r from@hoge.hoge -s "mail test" dist@hoge.hoge
test

ssl認証経由で送信する場合

vi /etc/exim4/passwd.client
/etc/init.d/exim4 reload

lammps

MKLのFFTをリンクしてコンパイルする。自作コマンドはsrcディレクトリにコピー してコンパイルし実行ファイルを作る。2020/10にインストールした。

スレッド対応のMKLライブラリをリンクする。-xHOSTをつけてCPUに最適化した 実行ファイルを作る。そのため、親ノードと子ノードでCPUが違う場合は、子 ノードでコンパイルする必要がある。また、-DDFFT_MKLをつけないとKISSがリ ンクされるので注意する。mklがリンクされたら実行したlogで"using double precision MKL FFT"となる。

https://lammps.sandia.gov/doc/Build_settings.html

git clone -b stable https://github.com/lammps/lammps.git
cd lammps/src
make yes-RIGID
make yes-KSPACE
make yes-MOLECULE
make yes-MISC
make yes-USER-MISC
make yes-CLASS2
make yes-USER-REAXC
cp MAKE/Makefile.mpi MAKE/Makefile.germanium
vi MAKE/Makefile.germanium
----------------------------------------------------------------------------
CC = mpiicpc -DLAMMPS_MEMALIGN=64
CCFLAGS = -O3 -qopenmp -xHost -restrict -fno-alias -ansi-alias -qoverride-limits       
LINK = mpiicpc -qopenmp
FFT_INC =   -DFFT_MKL -DFFT_MKL_THREADS -I/opt/intel/compilers_and_libraries_2020.2.254/linux/mkl/include/fftw
FFT_PATH =  -L/opt/intel/mkl/lib/intel64
FFT_LIB =   -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core
----------------------------------------------------------------------------
make -j4 germanium
cp lmp_germanium /usr/local/bin/lammps

icpcのoption一覧

-DLAMMPS_MEMALIGN=64  
-O3 最適化レベル
-qopenmp マルチスレッド
-xHost プロセッサで利用可能な最上位の命令セット向けのコードを生成
-restrict pointerの指す先の厳密化
-fno-alias local変数の厳密化
-ansi-alias ANSI エイリアシング規則に準拠
-qoverride-limits コンパイル時のメモリ制限を上書きする。

quantum espresso

2020/10にインストールした。qe-6.6はgipawがまだ対応していないので、qe-6.5をインストールすることとした。

setup.shを作ってconfigureまで行った。

curl -L  https://github.com/QEF/q-e/archive/qe-6.5.tar.gz| tar xvzf -
mv q-e-qe-6.5 qe-6.5
cd qe-6.5

vi setup.sh
----------------------------------------------------------------------------
#!/bin/sh
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/bin/ifortvars.sh intel64
source /opt/intel/mkl/bin/mklvars.sh  intel64 mod lp64
export F90=ifort
export F77=ifort
export CC=icc
export FFLAGS="-O3 -xHOST -assume byterecl  -qopenmp"
export MPIF90=mpiifort
export LDFLAGS=-qopenmp
export DFLAGS="-D__DFTI -D__MPI -D__SCALAPACK"
export BLAS_LIBS="-lmkl_intel_lp64  -lmkl_intel_thread -lmkl_core"
export LAPACK_LIBS=""
export SCALAPACK_LIBS="-lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64"
export FFT_LIBS="-L/opt/intel/mkl/lib/intel64"
./configure  --enable-parallel
----------------------------------------------------------------------------
./setup.sh

相変わらずconfigureが失敗するので手動でmake.incを調整した。

vi make.inc
----------------------------------------------------------------------------
DFLAGS         =  -D__FTI -D__MPI
MPIF90         = mpiifort
F90           = ifort
CC             = icc
F77            = ifort
FFLAGS         = -O3 -xHOST -assume byterecl  -qopenmp
LD             = mpiifort
LDFLAGS        = -qopenmp
BLAS_LIBS      =   -lmkl_intel_lp64  -lmkl_intel_thread -lmkl_core
BLAS_LIBS_SWITCH = external
LAPACK_LIBS = 
LAPACK_LIBS_SWITCH = external
SCALAPACK_LIBS = -lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64
FFT_LIBS       = -L/opt/intel/mkl/lib/intel64
----------------------------------------------------------------------------

gipawモジュールを追加でコンパイルした。

git clone https://github.com/dceresoli/qe-gipaw.git
cd qe-gipaw
./configure --with-qe-source=/usr/local/src/qe-6.5
make -j4
ln -s bin/gipaw.x ../bin/

vasp

vaspポータルからダウンロードしたらコンパイルします。

cd /opt/intel/mkl/interfaces/fftw3xf
make libintel64
cp arch/makefile.include.linux_intel makefile.include
vi makefile.include
----------------------------------------------------------------------------
CPP_OPTIONS= -DHOST=\"LinuxIFC\"\
             -DMPI -DMPI_BLOCK=8000 -Duse_collective \
             -DscaLAPACK \
             -DCACHE_SIZE=4000 \
             -Davoidalloc \
             -Dvasp6 \
             -Duse_bse_te \
             -Dtbdyn \
             -Dfock_dblbuf \
             -D_OPENMP
FC         = mpiifort -qopenmp
FCL        = mpiifort -mkl
FFLAGS     = -assume byterecl -w -xHOST
OBJECTS= fftmpiw.o fftmpi_map.o fftw3d.o fft3dlib.o
INCS=-I$(MKLROOT)/include/fftw
----------------------------------------------------------------------------
MKLROOT=/opt/intel/mkl make -j4

メンテナンス

ノードを追加したりユーザーを追加する等のメンテナンスです。

ユーザー追加

親ノードでユーザー作ったらnisをアップデートする。

cd /var/yp
make

子ノードの追加

子ノードのBIOSでpxe bootを有効にして起動する。起動するとmac addressが 表示されるのでメモしておいてdhcpd.confに登録する。ip addressとhostname を/ets/hostsに追加する。/ets/hostsは子ノードのシステムにコピー。子ノー ドはnisで/etc/hostsを参照するが、どうもpbsの起動のタイミングとずれるよ うなので、子ノードのシステムの/etc/hostsも必ず更新する。

親ノードで以下のファイルを編集する。

vi /etc/dhcp/dhcpd.conf
vi /etc/hosts
cp /etc/hosts /nfsroot/etc/hosts

openpbsに新しいノードを登録し物理コア数を登録しておく。またキューのリ ソースにノードを追加する。

qmgr -c "create node germaniumXX" 
qmgr -c "set node germaniumXX resources_available.ncpus=10"
qmgr -c "set node germaniumXX resources_available.queue_name=germanium"

キューの最大コア数も更新しておく。

qmgr -c 'set queue germanium resources_max.ncpus=160'

ハードディスクの追加

diskのデバイスファイルを調べる

fdisk -l

全体で1ファイルシステムになるようパーティションを作成する。

fdisk /dev/sdb

ファイルシステムの作成する。

mkfs -t ext4 /dev/sdb

UUID調べて/etc/fstabに追加して終わり。

blkid /dev/sdb
vi /etc/fstab

タイムゾーンの設定

リンクはるだけ。

ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

ロケール(日本語)環境の設定

日本語表示が欲しい場合は、localeを設定する。

dpkg-reconfigure locales

パフォーマンス

CPU温度とスピード <2020-10-14 水>

CPU付属のファンを取り付けで、1ノードで500,000個のMD計算をスレッド 並列なしの10並列でlammpsで回してCPU温度をSpeedをモニタすると次のような 感じ。topで確認するとフルパワーで計算しているが、4 GHz弱で頭打ちになっ ている。これで一晩動かし続けてみる。

sensors
----------------------------------------------------------------------------
acpitz-acpi-0
Adapter: ACPI interface
temp1:        +27.8°C  (crit = +119.0°C)

coretemp-isa-0000
Adapter: ISA adapter
Package id 0:  +67.0°C  (high = +80.0°C, crit = +100.0°C)
Core 0:        +67.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:        +65.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:        +67.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:        +67.0°C  (high = +80.0°C, crit = +100.0°C)
Core 4:        +67.0°C  (high = +80.0°C, crit = +100.0°C)
Core 5:        +64.0°C  (high = +80.0°C, crit = +100.0°C)
Core 6:        +65.0°C  (high = +80.0°C, crit = +100.0°C)
Core 7:        +65.0°C  (high = +80.0°C, crit = +100.0°C)
Core 8:        +66.0°C  (high = +80.0°C, crit = +100.0°C)
Core 9:        +65.0°C  (high = +80.0°C, crit = +100.0°C)
----------------------------------------------------------------------------

lscpu 
----------------------------------------------------------------------------
アーキテクチャ:                      x86_64
CPU 操作モード:                      32-bit, 64-bit
バイト順序:                          Little Endian
Address sizes:                       39 bits physical, 48 bits virtual
CPU:                                 20
オンラインになっている CPU のリスト: 0-19
コアあたりのスレッド数:              2
ソケットあたりのコア数:              10
ソケット数:                          1
NUMA ノード数:                       1
ベンダー ID:                         GenuineIntel
CPU ファミリー:                      6
モデル:                              165
モデル名:                            Intel(R) Core(TM) i9-10900 CPU @ 2.80GHz
ステッピング:                        5
CPU MHz:                             4100.002
CPU 最大 MHz:                        5200.0000
CPU 最小 MHz:                        800.0000
BogoMIPS:                            5600.00
仮想化:                              VT-x
L1d キャッシュ:                      32K
L1i キャッシュ:                      32K
L2 キャッシュ:                       256K
L3 キャッシュ:                       20480K
NUMA ノード 0 CPU:                   0-19
フラグ:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp pku ospke md_clear flush_l1d arch_capabilities
----------------------------------------------------------------------------

温度が上がりすぎでブーストが最大まで有効になっていない模様。全コアブー スト最大の4.6 GHz近くまでスピードがもう少し欲しいので、とりあえず水冷 ファン(Thermaltake TH120 ARGB Sync)を1個ポチした。CPUクーラを検討して から、ラックに取り付けようと思います。電力メータの計測値は110Wくらいで す。disklessで動かしていて不要なプロセスは殺しているので電力消費は、ほ ぼ計算のためのCPU演算だけでしょう。

研究室の計算機との比較

silicon

16ノード合計64コアからなる自作した並列計算機。1ノードのCPU性能は以下の とおり。2014年に構築した。親ノード入れて80万くらい。

CPU Intel(R) i5-4690
コアの数 4
スレッド数 4
プロセッサー ベース動作周波数 3.50 GHz
ターボ・ブースト利用時の最大周波数 3.90 GHz
キャッシュ 6 MB Intel® Smart Cache
バススピード 5 GT/s
TDP 84 W
メモリ 16 (8x2) Gbyte

okagiri

2CPU合計36コアからなる某所から購入したワークステーション。1つのCPU性能 は以下のとおり。2018年8月に導入した。200万くらい。

CPU Intel(R) Xeon(R) Gold 6154
コアの数 18
スレッド数 36
プロセッサー ベース動作周波数 3.00 GHz
ターボ・ブースト利用時の最大周波数 3.70 GHz
キャッシュ 24.75 MB L3 Cache
UPI リンク数 3
TDP 200 W
メモリ 96 (16x6) Gbyte DDR4 2666 REG ECC

nokogiri

GPUを2基つんだGPUマシン。2019年8月に導入した。200万くらい。

  • GPU: NVIDIAの単精度のGPUが4枚 (NVIDIA GeForce RTX2080Ti)
  • CPU: Intel Xenon Silver4214 2個 (12*2=24cores)
  • メモリ: 32*12 = 384 Gbyte
  • HD: 4*3=12 Tbyte

ベンチマーク

90原子からなるSiO2ガラスの第一原理計算をqe-6.5とvasp-5.4.4で計算し て計算時間を求めた。scfは23ループで収束します。

k点を各ノードにうまく割り当てられない場合、GbitのEthernetがネックになっ てまったく速度がでないことに注意する。

表1: 第一原理計算の計算時間(sec.)
  germanium (4 node) germanium (8 node) okagiri ito
qe 347 222   239
vasp 107 67   56

また64,000原子からなるNaClの古典分子動力学計算をsilicon17 nodes (68 cores)とgermanium 13 nodes (130 cores)使って1,000ステップ行って計算時 間を計測した。GbitのEthernetを使ってもlammpsだと85%以上の効率で計算が できる。

表2: 分子動力学計算の計算時間(sec.)
  silicon germanium okagiri ito
lammps 838 305   227

著者: 大窪 貴洋

Created: 2023-03-27 月 17:04

Validate