チュートリアル02:並列実行
本章ではFreeFlexにより同時に複数のMD計算を行う方法について説明する。なお、MPI計算はサーバーごとに使用方法が微妙に異なることが多く、大まかな流れ以外は各自で実行方法を確認する必要が出てくることがある。
本研究室では現在PBSを用いて並列計算の投入を行っており、PBSの利用が推奨される。詳細についてはPBS Pro マニュアル参照
MPI環境の準備
(私の環境では完全にはじめから始めたわけではないので、他にも初期設定がいる可能性が高いです。)
MPIを用いたプログラムの実行ではサーバーマシン起動後の初回に
> mpdboot –f /etc/mpd.hosts –n 15 &
のようなコマンドを用いる必要がある。 ここでmpd.hosts は
=== mpd.hosts ================================================================================== naruko00 naruko01 naruko02 . . . ================================================================================================
のようにクラスタ化されているマシン名を一覧にしたファイルであり、”-n” で指定している数字はマシンの総数である。
OpenMP並列化による計算の高速化
基本の実行
FreeFlex でOpenMP による並列実行を行うには、&FreeFlex ネームリストにおいて、
=== input_omp.nml ============================================================================== &FreeFlex ms_init_file = "system3.ms", xyz_traj_file = "traj_omp.xyz", log_file = "log_omp", ms_last_file = "system4_omp.ms", nml_output_file = "output_omp.nml" ms_restart_file = "restart_omp.ms" nstep = 100 dt = 1.0d-15 omp_number = 16 / ================================================================================================
> ./FreeFlex.exe input_omp.nml &
のように omp_number を指定して実行すればよい(系はTutorial01のものと同様。/sample/tutorial/02 内の ms_init_file が古い version のものである場合があるため,Tutorial01 で作成したものを使用すること.)。 ただし一度に多くの計算を回す場合は、
> export OMP_NUM_THREADS=4; ./FreeFlex.exe input_omp.nml &
のように環境変数側でも並列数を指定する方が無難なようである。以前この指定を行わなかったところ使用プロセッサ数が多すぎるとのエラーメッセージが出たことがある。これは、 OMP_NUM_THREADS の初期値が最大並列可能数に設定されており、実行時に一度このプロセッサ数を確保したうえでプログラム中の命令で使用プロセッサ数を制限するためと考えられる。
PBSを利用した実行
PBSを利用したOMPジョブの投入例を以下に示す。この投入例はmpi1、omp16の投入ファイルである。
なお、PBSを用いる際は他計算機にFreeFlexをコピーし、rsh接続ができることを確認すること。詳細はPBS Pro マニュアルを参照。
細かい内容、例えば3行目の値の設定(ncpusなど)は、チュートリアル02:並列計算などのPBSのチュートリアルを参考にすること。
=== sub_omp.sh ==============================================================================
#!/bin/bash
#PBS -N tutorial02
#PBS -l select=1:ncpus=16:mpiprocs=1:ompthreads=16
#PBS -j oe
###### ユーザー指定の変数の default 以外を設定する。###########################
RNODE=node00
RDIR=/home/user/FreeFlex/sample/tutorial/02
RFILE=
WDIR=
SAVE=
echo -n 'START: '; date
###### initialization #####################################################
###### [1] mpd ######
touch /tmp/node_$$
trap 'rm /tmp/node_$$' 1 2 3 15
uniq $PBS_NODEFILE > /tmp/node_$$
NPROCS=`cat $PBS_NODEFILE | wc -l`
NHOSTS=`cat /tmp/node_$$ | wc -l`
for i in `cat /tmp/node_$$`
do
rsh $i mpdcleanup >/dev/null
done
mpdboot -f /tmp/node_$$ -n $NHOSTS -r rsh
EXIST=`rsh $RNODE "test -e $RDIR; echo \\$?"` # $RNODE:$RDIR の存在を確認する。
if [ $EXIST != 0 ]; then
echo ' Error! No such a dirctory. Confirm RNODE and RDIR. '$RNODE":"$RDIR
exit
fi
###### [2] files ######
echo 'RNODE: '${RNODE:='fep'} # default は、'fep'になる。
echo 'RDIR: '${RDIR:=$PBS_O_WORKDIR} # defalut は、サブミットした場所。
echo 'RFILE: '${RFILE:="*"} # default は、すべて。
echo 'WDIR: '${WDIR:=$HOME/$$} # default は、$HOME/$$
echo 'SAVE: '${SAVE:=0} # default は、0
echo 'PBS_NODE: '`cat /tmp/node_$$`
test -e $WDIR || mkdir -p $WDIR # WDIR をつくる。
cd $WDIR
touch touch_$$
if [ "`rsh $RNODE ls $RDIR/touch_$$ 2>/dev/null`" == "$RDIR/touch_$$" ]; then
IDENTICAL=0 # RDIR と WDIR が同一のとき、何もしない。
else
IDENTICAL=1 # RDIR と WDIR が別ディレクトリのとき、RNODE の入力ファイルを WDIR にコピー。
rsh $RNODE "cd $RDIR; tar czf - $RFILE" | tar xzf -
fi
rm touch_$$
####### execution ###########################################################
export FreeFlex='/home/user/FreeFlex'
mpiexec -machinefile $PBS_NODEFILE -n $NPROCS $FreeFlex/FreeFlex.exe input_omp.nml
###############################################################################
####### termination #######################################################
###### [2] files ######
cd
if [ $IDENTICAL -ne 0 ]; then
# RDIR と WDIR が別ディレクトリのとき、WDIR の出力ファイルを RDIR にコピー。
# rsync -azu -e rsh $WDIR"/" $RNODE:$RDIR
ionice -c 3 nice -n 10 rsync -azu -e rsh --rsync-path="ionice -c 3 nice -n 10 rsync" $WDIR"/" $RNODE:$RDIR
if [ $? -eq 0 ]; then
[ $SAVE -eq 0 ] && rm -rf $WDIR # SAVE=0 のとき、WDIR を削除。
else
echo "rsync failed in terminating the job."
fi
fi
###### [1] mpd ######
mpdcleanup -r rsh -f /tmp/node_$$
rm /tmp/node_$$
###########################################################################
echo -n 'END: '; date
================================================================================================
上記のファイルのRNODEを現在のノードに、user部分をFreeFlexが置いてあるディレクトリへと変更すること。ジョブの投入には以下のコマンドを実行すればよい。
> qsub sub_omp.sh
MPI並列化による複数計算(とりあえず回してみる)
FreeFlex で複数の計算を同時に行うには下記のようにMPIによる実行を行えばよい。
=== input_mpi.nml ============================================================================== &FreeFlex ms_init_file = "system3.ms", xyz_traj_file = "traj_mpi.xyz", log_file = "log_mpi", ms_last_file = "system4_mpi.ms", nml_output_file = "output_mpi.nml" ms_restart_file = "restart_mpi.ms" nstep = 100 dt = 1.0d-15 omp_number = 4 / ================================================================================================
> mpiexec –machinefile machinefile –n 4 ./FreeFlex.exe input_mpi.nml &
ここで machinefile はMPIを実行するマシンの名前を一覧にしたもので、
=== machinefile ================================================================================ naruko00 naruko00 naruko00 naruko00 ================================================================================================
のような形式で –nで指定した数以上のマシン名を列記する必要がある。 なお、今回の計算ではinput_mpi.nml 中で omp_number も 4 に設定されており、計 (omp)×(mpi)=4×4=16 個のプロセッサを使用することになる。
上記コマンドを実行するとディレクトリ内に 0000/, 0001/, 0002/, 0003/ の4つのディレクトリが作られる計算結果はこの中に格納されている。
MPI並列化(条件を変える)
先のMPI計算では4つの計算はすべて全く同じ条件で実行されている。 この条件を変えるには 0000/ 等のディレクトリ内にもネームリストを作成する必要がある。 例えば、並列数を1, 2, 4, 8 と変えて実行したい場合、
=== input_mpi2.nml ============================================================================= &FreeFlex ms_init_file = "system4_mpi.ms", xyz_traj_file = "traj_mpi2.xyz", log_file = "log_mpi2", ms_last_file = "system5_mpi.ms", nml_output_file = "output_mpi2.nml" ms_restart_file = "restart_mpi2.ms" nstep = 100 dt = 1.0d-15 omp_number = 4 / ================================================================================================
のような全体の基準となるファイルの他に、
=== 0000/input_mpi2.nml ======================================================================== &FreeFlex omp_number = 1 / ================================================================================================
=== 0001/input_mpi2.nml ======================================================================== &FreeFlex omp_number = 2 / ================================================================================================
=== 0002/input_mpi2.nml ======================================================================== &FreeFlex omp_number = 4 / ================================================================================================
=== 0003/input_mpi2.nml ======================================================================== &FreeFlex omp_number = 8 / ================================================================================================
のようなファイルを各ディレクトリ内に作成する必要がある(各自作成すること。)。なおinput_mpi2.nml 内ではインプットとなるmsファイル名に2-2 で各ディレクトリ内に作成された "system4_mpi.ms" を指定している(ワークディレクトリ内にはこのファイルは存在しない。存在していても各ディレクトリ内が優先される)。 このような指定により、MPI実行で得られた最終構造からMD計算を再開できる。 また、msファイルの中身をそれぞれ別のデータと差し替えることで、複数の構造(初期条件)からの計算が可能になる。
本計算を下記コマンドにより実行すると(OMP_NUM_THREADSを指定している場合は解除すること)、
> mpiexec –machinefile machinefile –n 4 ./FreeFlex.exe input_mpi2.nml & FreeFlex.F(246): WARNNING: ファイル system4_mpi.ms が存在しません。 MPI用ディレクトリからの読み込みを試みます。
のような警告メッセージが出力されるがこれは各ディレクトリ内のmsファイルを読みに行っていることを示す正常な動作である。 実行結果として計算時間を見てみると、
0000/log_mpi2: total: 215.238 s 0001/log_mpi2: total: 136.926 s 0002/log_mpi2: total: 85.610 s 0003/log_mpi2: total: 60.399 s
のようにOpenMPによる実行で計算速度がある程度速くなっていることが分かる。
実際に系を作成する
実際に初期構造を作る際、チュートリアル01のような作業を数十回やるのは骨が折れるので、そういった作業を自動で行うスクリプトのサンプルを以下に示す。
=== makesystem.sh =================================================================
#!/bin/bash
# 系の作成個数を決める。
ndir=80
$HOME/FreeFlex/add2.exe add.nml system1.ms
#水、DCMのmsファイルが存在する場合、xyzファイルを作成する。
if test -e DCM.ms
then
$HOME/FreeFlex/ms2xyz.exe DCM.ms DCM.xyz
fi
if test -e water.ms
then
$HOME/FreeFlex/ms2xyz.exe water.ms water.xyz
fi
#系の作成
#packmolを用いる際、system.inpに"seed -1"を追加すること。
for ((i=0 ; i<$ndir ; i++))
do
dir=$(printf "%04d" "${i}" )
echo $dir
packmol < system.inp
$HOME/FreeFlex/xyz2ms.exe system.xyz system1.ms system2.ms
mkdir -p ../$dir
mv ./system2.ms ../$dir/system1.ms
done
=========================================================================================
上記のスクリプトはあくまでも個人用なので、用いる際は個々人でカスタマイズすること。