Author: | 藤堂眞治, 松尾春彦 |
---|---|
Address: | Department of Applied Physics, University of Tokyo, 113-8656 Tokyo, Japan |
Contact: | wistaria@ap.t.u-tokyo.ac.jp |
Version: | 1.1 (2008/08/09) |
この文書では, looper/parallel.h (Rev: 2869 (2008-06-27))の内容について解説を行なう.
個々のクラスターの状態を表わすクラス. 一段階更新が終った後のクラスターは以下の二つのどちらかの状態を取る.
まだ開いており虚時間境界を横切る.
クラスターはより大きな開いたクラスター(結合クラスター)の一部分となっている. メンバー関数 id() は結合クラスターの id を返す.
考えている虚時間領域で完全に閉じる.
メンバー関数 operator() はフリップされるかどうかを返す.
メンバー関数の返り値 (表中の「--」は返り値が意味を持たないことを示す)
タイプ | is_open() | operator() | id() |
開クラスター | true | -- | 結合されたクラスターの id |
閉クラスター | false | flip する場合 true, しない場合 false | -- |
type
個々のクラスターの物理量(長さなど)を保持するクラス.
演算子 +=(estimate_t const&): 新たに結合されたクラスターの物理量を追加する.
全体の物理量を保持するクラス.
演算子 +=(collector_t const&): 閉じたクラスターの物理量(estiamte_t)を全体の物理量に追加
演算子 +=(collector_t const&): 他のプロセスで収集された物理量・閉じたクラスター数(collector_t)を追加
double num_clusters(): 現段階での閉じたクラスター数
void set_num_clusters(int n): 閉じたクラスター数を n に設定
void inc_num_clusters(int n): 閉じたクラスター数を n だけ増加
double num_open_clusters(): 現段階での開いたクラスター数
void set_num_open_clusters(int): 開いたクラスター数を設定
クラスターの結合関係(ツリー構造)を表現するためのクラス.
member
並列動作しているプロセスのグループ(正確には MPI の communicator) (constructor中の58行目で設定)
並列動作しているプロセス数 (= comm_ のサイズ) (constructor中の61行目で設定)
自プロセスの id (= comm_ における rank) (constructor中の64行目で設定)
サイト(スピン)数 (constructor中の58行目で設定)
上下の虚時間境界に露出しているサイト数 (= 2*num_sites_) (constructor中の58行目で設定)
バイナリツリーの段数 (constructor中の67-68行目で設定)
slaveプロセスから物理量(collector_t)を受け取るためのバッファー
現段階での閉じたクラスターについてフリップするか否かを記録する配列
現段階で結合を行なう前のクラスターについて, 結合後のクラスターid, もしくは, 結合後に閉じた場合にはフリップするか否かを記録する配列. この配列はメンバー関数 distribute() により master, slave それぞれの下位プロセスに分配され, 配列``flip``の更新に使われる.
クラスター結合のための作業領域. サイズ = 2*num_boundaries_ = 4*num_sites_
クラスター結合のための作業領域. 虚時間の小さい下半分の領域のツリー構造を収めておく. サイズ = num_boundaries_ = 2*num_sites_
クラスター結合のための作業領域. 虚時間の大きな上半分の領域のツリー構造を収めておく. サイズ = num_boundaries_ = 2*num_sites_
クラスター結合のための作業領域. サイズ = nc
クラスター結合のための作業領域. 虚時間の小さい下半分の領域の個々のクラスターの物理量を収めておく. サイズ = coll.num_open_clusters()
クラスター結合のための作業領域. 虚時間の大きな上半分の領域の個々のクラスターの物理量を収めておく. サイズ = coll_buf_.num_open_clusters()
メンバー関数 unify における処理
入力
各プロセス内で閉じたクラスターの物理量を収集したオブジェクト. また, プロセス内の全クラスター数と開いたクラスター数はそれぞれ coll.num_clusters() と coll.num_open_clusters() で与えられる.
std::vector<FRAGMENT> const& fragments
虚時間境界(上下)のサイト(総数 = num_boundaries_ = 2*num_sites_)の間のツリー構造(つながり方)を収めた配列. 0番目〜(num_sites_-1)番目の要素が下部虚時間境界(tau = tau0), num_sites_ 番目〜(2*num_sites_-1)番目の要素が上部虚時間境界(tau = tau1)上のサイトに対応.
unify に渡される配列のサイズは, 一般に num_boundary_ よりも大きい. しかし, それぞれのツリー内で 0 番目〜(num_boundaries_-1)番目の要素が, 他の要素よりも上にある(= rootに近い)ことは保証されている. (実際のコードでは unify 呼び出し前に set_root() 関数を用いて, それぞれのツリー内で並び換えを行なっている.) また, 虚時間境界のサイトを含むツリー(= クラスター)の id が 0 〜 (coll.num_open_clusters()-1) であることも保証されている.
std::vector<estimate_t> const& estimates
各クラスターの物理量を収めた配列. unify に渡される配列のサイズは, 一般に coll.num_open_clusters() よりも大きい. しかし, 虚時間境界のサイトを含むクラスター(coll.num_open_clusters() 個)の id は 0 〜 (coll.num_open_clusters()-1) であることは保証されている. 一方, id が coll.num_open_clusters() 〜(coll.num_open_clusters()+coll.num_clusters()-1) までのクラスターは各プロセス内で閉じており, それらの物理量はすでに coll に追加されている.
乱数発生器(0〜1の均等分布)
出力
master プロセスの coll は全物理量, 全クラスター数で上書きされる. slave プロセスの coll の返り値は不定.
各プロセスにおける開いたクラスター(coll.num_open_clusters() の 入力値)をフリップするか否かを記録した配列. この値を元にスピン状態, 演算子のタイプ(対角 or 非対角)が更新される.
処理内容
以下, 並列処理 (num_processes_ > 1) の場合についてのみ説明
flip と flip_stage_ の初期化. coll.num_open_clusters() 個の開いたクラスター(id は 0 〜 coll.num_clusters()-1)を準備
linksD_ に引数 fragments の情報をコピーする. estimatesD_ に引数 esteimates の情報をコピーする.
非並列の場合の処理
stage (バイナリツリーの段数)に関するループ. stage_mask は下 stage+1 ビットが 1, target_mask は下から stage+1 ビット目のみが1の定数.
それぞれの stage において, process_id の下 stage+1 ビットが全て1のプロセスが master, process_id の下から stage+1 ビット目が1, かつ下 stage ビットが全て 0 のプロセスが slave となる. 段数が増すに従って master, slave となるプロセスの数は減少する. 全プロセス数が2の羃でない場合には master に対応する slave が存在しない場合があるが, その場合 master は何もしない. process_id の下 stage ビットが 0 でないプロセスは, master もしくは slave プロセスの子ノードとなり, 配列 flip の更新のみを行なう.
現 stage における master プロセスの処理
slave から前 stage までで得られた物理量, 虚時間境界サイト間のつながり方(ツリー構造), 個々の開いたクラスターの物理量を受けとり, それぞれ coll_buff_, linksU_, estimatesU_ に格納し, さらに, 自プロセスがあらかじめ持っている下部虚時間領域の情報(linksD_)と受け取った上部虚時間領域(linksU_)の情報を links_ にまとめる. linksU_ についてはもともと index が 0 〜 num_boundaries_-1 だったものが num_boundaries_ 〜 2*num_boundaries_-1 の領域に写されるので, ツリー構造のリンクを修正する必要があることに注意する.
下部虚時間領域の上境界サイト(index が num_sites_ 〜 num_boundaries_-1)と上部虚時間領域の下境界サイト(index が num_boundaries_ 〜 num_boundaries_+num_sites_-1)を結合(unify).
虚時間方向の周期境界条件のため, 最終ステージでは下部虚時間領域の下境界サイト(tau = 0, index が 0 〜 num_sites_-1)と上部虚時間領域の上境界サイト(tau = 1, index が num_boundaries_+num_sites_ 〜 2*num_boundaries_-1)も結合する必要がある
下部虚時間領域の下境界サイトと上部虚時間領域の上境界サイトが新たな境界上のサイトとなるため, ツリー構造の中でこれらのサイトが他の全てのサイトよりも上(= root に近い)になるように set_root する.
下部虚時間領域の下境界サイトと上部虚時間領域の上境界サイトが属するクラスター(まだ開いているクラスター)に id (0 〜 noc-1)を割り当てる.
残りのクラスター(このステージで閉じたクラスター)に id (noc 〜 nc-1)を割り当てる.
最終ステージでは全てのクラスターは閉じるので noc = 0 とする.
閉じたクラスターをフリップするかどうか(確率1/2)を乱数を用いて決定し, 配列 flip_close_ に保存する. (この配列の 0 〜 noc-1 番目の要素は使用されない.)
結合されたクラスターについての物理量の配列(estimates_)を初期化する.
上部虚時間領域(slave分)の flip_stage_ を作成し, slave に送信する. また同時に結合前のクラスターの物理量(estimateU_)を新たなクラスターの物理量(estimate_)に足し込む. old_id は linkU_ 内でのクラスター id, new_id は結合後の link_ におけるクラスター id.
下部虚時間領域(master分)の flip_stage_ を作成する. また同時に結合前のクラスターの物理量(estimateD_)を新たなクラスターの物理量(estimate_)に足し込む. old_id は linkD_ 内でのクラスター id, new_id は結合後の link_ におけるクラスター id.
子ノードに結合処理結果(flip_stage_)を送信する. (distribute)
結合処理により閉じたクラスター(id = noc 〜 nc-1)の物理量を全物理量(coll)に足し込む. また, まだ開いているクラスター数(noc)をセットし, 新たに閉じたクラスターの数(nc-noc)を全クラスター数に足し込む.
次のステージのために, 結合後の虚時間境界のサイトの間の結合関係(ツリー構造)を作成し, 配列 linkD_ に格納する. まだ開いているクラスター(noc 個)の物理量を estimate_ から estimateD_ にコピーする.
現 stage における slave プロセスの処理
前 stage で得られた物理量(coll), 虚時間境界サイト間のつながり方(ツリー構造) (linksD_), 個々の開いたクラスターの物理量(estimatesD_)を master プロセスに送る
master から結合処理結果(flip_stage_)を受け取る.
子ノードに結合処理結果(flip_stage_)を送信する. (distribute)
現 stage における子ノードの処理
親ノードから結合処理結果(flip_stage_)を受け取り, さらに自分の子ノードに送信する. (distribute)
flip_stage_ を元に flip を更新する. クラスターが閉じた場合にはフリップするか否か, クラスターが結合後もまだ開いている場合にはその新しいクラスター id を格納する. (update)
処理・転送パターン
以下にプロセス数 8 (ステージ数 3)の場合の処理・転送パターンを示す. 青矢印がデータの転送を表す.
Copyright (c) 2007-2008 by 藤堂眞治 <wistaria@comp-phys.org>, 松尾春彦 <halm@looper.t.u-tokyo.ac.jp>