並列環境

Ippei Kishida

Last-modified:2018/03/29 22:54:19.

並列環境の設定をする。 この作業は簡略手順構築の前にやっても良いが、 まとめて qsub を投げて別々の計算機に投げられるかのテストも含むため、 ある程度増産した後にやった方が良かろう。

並列環境

Parallel Environment, PE などと呼ばれる。

並列環境はつまるところ、 「このシリーズを使うときは1台あたりに何プロセス走らせるか」という条件を 設定するもの。 なので、並列環境の設定に先立って並列効率などについての評価を行っておくべき。

1 PE の作成

qconf -ap Ga.mpich2

エディタが起動するので、以下のように記述。

pe_name            Ga.mpich2
slots              10
user_lists         NONE
xuser_lists        NONE
start_proc_args    /bin/true
stop_proc_args     /bin/true
allocation_rule    1
control_slaves     TRUE
job_is_first_task  TRUE
urgency_slots      min
accounting_summary FALSE

主な修正点は以下。

key value note
slots 10 稼働する台数と1台あたりの効率プロセス数の積。Kr なら 7*4 で 28。
allocation_rule 1 1台あたりの効率プロセス数。Kr なら 4

エディタを抜けたら登録されている。確認するには、

qconf -spl
#=> Ga.mpich2

設定の意味については以下を参考。

1.1 slots

The number of parallel processes being allowed to run in total under the parallel environment concurrently. Type is number, valid values are 0 to 9999999. 「Slots」ボックスでは、並行して実行中のすべての並列環境ジョブにより占有可能なジョブスロットの合計数を入力します。

「並列環境下で同時に許可される並列プロセスの総数」ということなので、 以下の方針が考えられる。 (故障したりハングアップする度に手動で減らさんとあかんのかなあ。)

マルチコアプロセッサのホストで、 コア数分だけスロットを確保した方が良いとは限らない。 Intel Compiler でコンパイルしたバイナリは内部最適化が結構すごいので 1プロセスで投げてしまった方が速いことがある。 しかし、mpiしなかった場合に変な結果になったことがある、ということを聞いたことがある。

今のところ、 下表に示すように Ga series では1プロセスで投げた方が速いので、 slots を台数分と等しい 10 にすることにする。 なお 1process/host * 4 host の値は 最初に 65, 2回目に 29。 NFS の影響か、かなりバラつきがあるようだ。

(Elapsed time[s]) 1host 2host 3host 4host
1process/host 73 49 75 29
4process/host 121 109 89 197

1.2 allocation_rule

スケジューラスレッドによって解釈され、 スケジューラが計算機の中で並列プロセスを決定するのを助けるもの。 たとえば並列環境が共有メモリアプリケーションのみに対して作られていたら、 計算機が複数台利用可能であっても全ての並列プロセスが1台の計算機に割り当てられる。 並列環境が分散メモリパラダイムも使えるならば、 プロセスが複数の計算機間で均等に分配されると嬉しかろう。 現状では以下が使える。(直訳)

整数
    整数は1ホストあたりのプロセス数を固定する。
    1 を指定すると、全てのプロセスはそれぞれ別個のホストに割り当てられる。
    $pe_slots を指定すると、
    qsub コマンドの -pe switch で指定したプロセス数の全てが、
    1台のホストに割り当てられる。
    (たとえどんな値が最終的に、ジョブが割り当てられるのに選ばれようとも(?))
    1ホストあたりの割り当てプロセス数が均等であることが保証されるっぽい。

$fill_up
    1台ごとに使えるプロセスを埋めていく。
    1ホストあたりの割り当てプロセス数が均等でないこともありうる。

$round_robin
    1台1プロセスずつ埋めていく。
    1ホストあたりの割り当てプロセス数が均等でないこともありうる。

たとえば、4 プロセス持っているホストが 3台あったとする。 ここに 5 プロセスのジョブが投げられた。 以下のような感じになる筈。

プロセス割り当て数 hostA hostB hostC
$fill_up 4 1 0
$round_robin 2 2 1

allocation_rule に整数を指定したときは、 -pe スイッチで指定した数がその整数倍でなければ実行されないようだ。

当研究室の用途だと、 整数値として計算機のコア数を指定するのが良さそうだ。 Ga での vasp は 1 プロセスで走らせた方が速いので、1 にする。

1.3 control_slaves

This parameter can be set to TRUE or FALSE (the default). It indicates  whether
Sun Grid Engine is the creator of the slave tasks of a parallel application via
sge_execd(8) and sge_shepherd(8) and thus has full control over  all  processes
in  a parallel application, which enables capabilities such as resource limita-
tion and correct accounting. However, to gain control over the slave tasks of a
parallel  application,  a  sophisticated  PE interface is required, which works
closely together with Sun Grid Engine facilities. Such PE interfaces are avail-
able through your local Sun Grid Engine support office.

Please set the control_slaves parameter to false for all other PE interfaces.

TRUE/FALSE のいずれかにセットするが、FALSE がデフォルトである。 これは SGE が、並列アプリケーションから sge_execd や sge_shepherd を経由した従属タスクの作り手であるかどうか、 また並列アプリケーション内の全てのプロセスに対する完全な制御を持つか、を示す。

TRUE にしてみたが、FALSE でも動いている。 関係なさげ。

1.4 job_is_first_task

The  job_is_first_task  parameter  can be set to TRUE or FALSE. A value of TRUE
indicates that the Sun Grid Engine job script already contains one of the tasks
of  the  parallel  application (the number of slots reserved for the job is the
number of slots requested with the -pe switch), while a value  of  FALSE  indi-
cates that the job script (and its child processes) is not part of the parallel
program (the number of slots reserved for  the  job  is  the  number  of  slots
requested with the -pe switch + 1).

If wallclock accounting is used (execd_params ACCT_RESERVED_USAGE and/or SHARE-
TREE_RESERVED_USAGE set to TRUE)  and  control_slaves  is  set  to  FALSE,  the
job_is_first_task  parameter  influences the accounting for the job: A value of
TRUE means that accounting for cpu and requested memory gets multiplied by  the
number  of  slots requested with the -pe switch, if job_is_first_task is set to
FALSE, the accounting information gets multiplied by number of slots + 1.

TRUE/FALSE のいずれかにセットできる。 TRUE は SGE ジョブスクリプトが並列アプリケーションの タスク群の1つを既に含む事を示す ( そのジョブのために予約された slots の数が、 -pe スイッチによって要求された slots の数である) 。 対して FALSE は、 示す、 ジョブスクリプト(とその子プロセス) が並列プログラムの部分でないことを示す ( そのジョブのために予約された slots の数が、「-pe スイッチによって要求された slots の数 + 1」である) 。

もし wallclock accounting が 使われている (execd_params ACCT_RESERVED_USAGE and/or SHARE-TREE_RESERVED_USAGE が TRUE にセット) かつ control_slaves が FALSE であるならば、 job_is_first_taskは そのジョブの accounting に影響を与える: TRUE だと、 そのアカウンティング for CPU、そして要求メモリ、 は、-pe スイッチで要求された slots の数の積となる。 FALSE だと、アカウンティングは slots + 1 との積となる。

TRUE にしてみたり、FALSE にしてみたりしたけど、あまり関係なさげ。 qsub スクリプト自体がヘヴィな処理をする場合に FALSE にするのだろうか。 たぶん優先度に関することで、ウチの使い方だと TRUE にすべきなんだろう。

2 queue の設定

see;

(キューが存在しない場合は、qconf -aq で作り、 hostlist を追加しておく。)

qconf -mq Ga.q で、 pe_list が make になっているところに Ga.mpich2 を追加する。

pe_list               make Ga.openmpi
slots                 4 # 1台あたりの効率プロセス数。Kr なら 4
slots

The maximum number of concurrently executing jobs allowed in the queue. Type is number, valid values are 0 to 9999999.

「キュー内で許可される同時実行ジョブの最大数」とある。 これをそのまま信じれば、 「PE の slots はプロセス数だが、キューの slots はジョブの数である」ということになる。 後述のように幾つか実験をした結果、このマニュアルの表記は正しくないように思う。 今のところ、正確には 「queue の slots は1つのホストで許容される同時実行プロセスの数を決めている」 と思われる。 なので、Ga のように 1プロセスで実行する計算機では 1 にしておくのが良さそうだ。

2.1 qsub の -pe スイッチの効果

という条件を基準とし、 このとき、ジョブは 0 台 run 状態になり、いつまで待ってもrun にならない。

2.1.1 qsub の pe = 4

このとき、以下のように、1ホストで1ジョブずつ run になる。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   1640 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga00.calc.atom                4
   1641 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga01.calc.atom                4
   1642 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga02.calc.atom                4
   1643 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga03.calc.atom                4
   1644 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga04.calc.atom                4
   1645 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga05.calc.atom                4
   1646 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga06.calc.atom                4
   1647 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga07.calc.atom                4
   1648 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga08.calc.atom                4
   1649 0.75000 sleep100-p ippei        qw    01/19/2014 22:40:09                                    4

2.1.2 qsub の pe = 8

このとき、以下のように、2ホストで1ジョブずつ run になる。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   1740 0.50000 sleep100-p ippei        r     01/19/2014 22:44:08 Ga.q@Ga02.calc.atom                8
   1741 0.50000 sleep100-p ippei        r     01/19/2014 22:44:08 Ga.q@Ga03.calc.atom                8
   1742 0.50000 sleep100-p ippei        r     01/19/2014 22:44:08 Ga.q@Ga00.calc.atom                8
   1743 0.50000 sleep100-p ippei        r     01/19/2014 22:44:08 Ga.q@Ga05.calc.atom                8
   1744 0.50000 sleep100-p ippei        qw    01/19/2014 22:44:07                                    8

2.1.3 まとめ

qsub の pe の値は、そのジョブで占有するプロセスの総数となることが確認できた。

2.2 queue の slots の効果

次に、1台ずつ走る以下の条件を基準にしよう。

2.2.1 queue の slots = 1

にしてみると、1台も running にならない。

2.2.2 queue の slots = 4

はすでにやったように、1ホストで1ジョブずつ run になる。 再掲する。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   1640 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga00.calc.atom                4
   1641 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga01.calc.atom                4
   1642 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga02.calc.atom                4
   1643 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga03.calc.atom                4
   1644 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga04.calc.atom                4
   1645 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga05.calc.atom                4
   1646 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga06.calc.atom                4
   1647 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga07.calc.atom                4
   1648 0.75000 sleep100-p ippei        r     01/19/2014 22:40:23 Ga.q@Ga08.calc.atom                4
   1649 0.75000 sleep100-p ippei        qw    01/19/2014 22:40:09                                    4

2.2.3 queue の slots = 8

にしてみると、以下のように1台のホストに2ジョブずつ、9個のジョブが running になる。

job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   2040 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga00.calc.atom                4
   2041 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga00.calc.atom                4
   2042 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga01.calc.atom                4
   2043 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga01.calc.atom                4
   2044 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga02.calc.atom                4
   2045 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga02.calc.atom                4
   2046 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga03.calc.atom                4
   2047 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga03.calc.atom                4
   2048 0.75000 sleep100-p ippei        r     01/19/2014 22:53:08 Ga.q@Ga04.calc.atom                4
   2049 0.75000 sleep100-p ippei        qw    01/19/2014 22:53:00                                    4

2.2.4 まとめ

queue の slots について、 1 と 4 での比較より、 qsub の pe の整数倍でない数では running にならないことが推測される。

queue の slots について、 4 と 8 での比較より、 running になるジョブ数は 9 のまま変化せず。 すなわち、queue の slots は running になるジョブ数に影響を与えない。 running になるジョブ数は、 「(PE の slots) / (PE の allocation_rule)」で決まる。 これらの条件では、 36 /4 = 9 となっている。

また、同じく queue の slots について、 4 と 8 での比較より、 queue の slots は 1 台のホストで許容される同時実行プロセスの数を決めていることが分かる。 queue の slots が 1 のときに running にならないことから、総数ではなく、その数丁度でなければ実行されない模様。 queue の slots が 8 であるところに、PE の allocation_rule で実行されるプロセスが 4 個なので、 2つのジョブでも実行できると判断されて投げられるのだと思われる。

2.3 processors

processors の値は UNDEFINED のままにする。 Solaris などのマルチプロセッサに対する設定らしい。マルチコアプロセッサでは関係ない、のだと思う。

3 ジョブ投入テスト

vi vasp.qsub でスクリプトを作る。

#! /bin/sh
#$ -S /bin/sh
#$ -cwd
#$ -o stdout
#$ -e stderr
#$ -q Ga.q
#$ -pe Ga.mpich2 2

MACHINE_FILE="machines"
MPICH2_BIN="/opt/mpich2/bin"

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:/usr/local/lib:/opt/intel/Compiler/11.1/072/lib/intel64:/opt/intel/Compiler/11.1/072/mkl/lib/em64t:/opt/intel/Compiler/11.1/072/lib/intel64
export LD_LIBRARY_PATH

cd $SGE_O_WORKDIR
printenv | sort > printenv.log
cut -d " " -f 1,2 $PE_HOSTFILE | sed 's/ /:/' > $MACHINE_FILE

$MPICH2_BIN/mpdboot -f $MACHINE_FILE -n $NHOSTS
$MPICH2_BIN/mpiexec -n $NSLOTS /opt/bin/vasp5212-mpich2
$MPICH2_BIN/mpdallexit

投げるホストや台数に応じた修正箇所を以下の2行にまとめてある。

#$ -q Ga.q
#$ -pe Ga.mpich2 8

qstat, qstat -f などで以下のような項目を確認。

3.1 Trouble:

qsub を短時間で複数回やると、 同じホストで全部実行しようとする。 あるいは、少数のホストで重複して実行する。

3.2 Trouble:

mpd が起動しない。

手動で mpd が起動するか? machinefile の書式は正しいか?