>> English


通信と同期

グローバルビューモデル

reduction指示文

データの集約演算を行う.

  • reduction節の演算子は下記が利用可能

    [F] +, *, -, .and., .or., .eqv., .neqv., max, min, iand, ior, ieor
    [C] +, *, -, &, |, ^, &&, ||, max, min

bcast指示文

データをブロードキャストする.

  • from節で転送元を指定します.省略した場合はp[0](p(1))が指定されます
  • on節で転送先を指定します.省略した場合は全ノードに転送されます
  • on節で指定する転送先のノード集合はon節で指定する転送元ノードを含む必要があります
  • ローカル変数aを全ノードにブロードキャストします.
    C
    #pragma xmp bcast (a)
    Fortran
    !$xmp bcast (a)
  • C:ノードp[5]が持つローカル変数aをノードp[5]からp[7]に転送します.

    #pragma xmp bcast (a) from p[5] on p[5:3]

  • Fortran:ノードp(5)が持つローカル変数aをノードp(5)からp(7)に転送します.

    !$xmp bcast (a) from p(5) on p(5:7)

barrier指示文

バリア同期を行う.

  • on節が省略された場合,全ての実行ノードのバリア同期が発生する
  • 例:すべてのノードは関数func_a()が終了するまで待機する
    C
    func_a();
    #pragma xmp barrier
    func_b();
    Fortran
    call func_a()
    !$xmp barrier
    call func_b()
  • テンプレートtのインデックスが10から20を持つノードのみが,バリア同期の対象になる
    C
    #pragma xmp barrier on t[10:11]
    Fortran
    !$xmp barrier on t(10:20)

shadow指示文

分散された配列における隣接する要素の値を保持する領域(袖領域)を定義する.

reflect指示文

shadow指示文で定義した袖領域の同期をとります.

  • C
    #pragma xmp template t[8]
    #pragma xmp nodes p[3]
    int a[9], b[9];
    #pragma xmp align a[i] with t[i]
    #pragma xmp align b[i] with t[i]
    #pragma xmp shadow a[1]
    
    #pragma xmp loop on t[i]
    for(i=0;i<9;i++){
       a[i] = init(i);     // a[]の初期化
    }
    #pragma xmp reflect (a)  // 同期
    
    #pragma xmp loop on t[i]
    for(i=1;i<8;i++){
      b[i] = a[i-1] + a[i] + a[i+1];
    }
    Fortran
    !$xmp template t(9)
    !$xmp nodes p(3)
    integer :: a(9), b(9)
    !$xmp align a(i) with t(i)
    !$xmp align b(i) with t(i)
    !$xmp shadow a(1)
    
    !$xmp loop on t(i)
    do i = 1, 9
      a(i) = init(i);     ! a()の初期化
    end do
    !$xmp reflect (a)  ! 同期
    
    !$xmp loop on t(i)
    do i=2, 7
      b(i) = a(i-1) + a(i) + a(i+1)
    end do

    下記はCの例です.shadow指示文は配列a[]の上端と下端に袖領域を作成します.下図の灰色の領域が袖領域です.

    reflect指示文は袖領域に対して同期をとります.下図のような隣接ノード間の通信が発生します.

  • n次元配列のm次元のみを分散させている場合(n>m),分散させていない次元は下記のように0という数字を用いて,その次元は袖領域がないことを宣言します.
    C
    #pragma xmp template t[10]
    #pragma xmp nodes p[*]
    int a[10][20][30];
    #pragma xmp align a[i][*][*] with t[i]
    #pragma xmp shadow a[1][0][0]
    Fortran
    !$xmp template t(10)
    !$xmp nodes p(*)
    integer :: a(30,20,10)
    !$xmp align a(*,*,i) with t(i)
    !$xmp shadow a(0,0,1)

gmove指示文

データ通信を行います.

in, outのいずれの指定もない場合には,両辺で参照されるデータは現在のノード集合が保持しているデータでなくてはならない.右辺にあるデータは,そのデータのあるノードから送信され,左辺のあるノードで受信される.

  • ノード間における分散配列,ローカル配列およびローカルのスカラ変数の代入を行える
  • 代入文は,算術演算を伴わない単純な代入に限る
  • XMP/Cの場合,例えばA[n:m]は,配列要素A[n]からm個の要素,すなわちA[n]からA[n+m-1]までの要素を意味する
  • XMP/Fortranの場合,例えばA(n:m)は,配列要素A[n]からA[m]までの要素を意味する
  • 右辺がローカル変数の場合は,そのデータはすべてのノードで同じ値でなくてはならない
  • 左辺がローカル変数の場合は,同じ値が代入される(ブロードキャスト操作と等価)
  • 両辺が分散配列の場合,all-to-all の通信が発生する.左辺が重複配列の場合,multicastになる
  • 右辺が分散配列の場合,特定ノードからのブロードキャスト通信となる
  • 例1:スカラ変数の代入文1
    C
    #pragma xmp gmove
      s1 = s2;              // s1,s2 はスカラ変数
    Fortran
    !$xmp gmove
      s1 = s2              !  s1,s2 はスカラ変数
  • 例2:スカラ変数の代入文2
    C
    #pragma xmp gmove
      a[3] = b[i][j];      // aとbはローカル配列
    Fortran
    !$xmp gmove
      a(3) = b(j,i)      !  aとbはローカル配列
  • 例3:分散配列の代入文1
    C
    #pragma xmp gmove
      a[:] = b[:];      // aとbは分散配列.配列の全要素が代入される
    Fortran
    !$xmp gmove
      a(:) = b(:)      ! aとbは分散配列.配列の全要素が代入される
  • 例4:分散配列の代入文2
    C
    #pragma xmp gmove
    a[1:9] = b[n:9];   // 対応する要素数は一致している必要がある.
    Fortran
    !$xmp gmove
    a(1:9) = b(n:n+8)   !  対応する要素数は一致している必要がある.
  • 例5:分散配列の代入文3
    C
    #pragma xmp gmove
    a[1:10] = c;    // cはスカラ変数.a[1:10]の要素すべてにcが代入される
    Fortran
    !$xmp gmove
    a(1:10) = c    !  cはスカラ変数.a(1:10)の要素すべてにcが代入される
  • 例6:in節の場合
    C
    #pragma xmp nodes p[4]
    int a[4], b[4];
    #pragma xmp distribute t[block] onto p
    // (中略)
    #pragma xmp task on p[1:2]
    #pragma xmp gmove in
      a[1:2] = b[2:2];
    Fortran
    !$xmp nodes p(4)
    integer :: a(4), b(4)
    !$xmp distribute t(block) onto p
    ! (中略)
    !$xmp task on p(2:3)
    !$xmp gmove in
      a(2:3) = b(3:4)

    in節が指定された場合には,左辺のデータを保持しているノードがリモートコピー操作により,対応する右辺のデータを取得する(get)ことにより,代入操作を行う.したがって,左辺で参照するデータは現在のノード集合が保持しているデータでなくてはならない.

  • out節が指定された場合には,右辺のデータを保持しているノードがリモートコピー操作により,対応する左辺のデータを更新する(put)ことにより,代入操作を行う.したがって,右辺で参照するデータは現在のノード集合が保持しているデータでなくてはならない.

ローカルビューモデル

片側通信の記述を行う.

C
int a[100]:[*], b[100];
if(xmpc_this_image() == 0){
   a[0:100]:[1] = b[0:100];  // PUT
}
Fortran
integer :: a(100)[*], b(100)
if (this_image() == 1) then
  a(1:100):[2] = b(1:100)  ! PUT
end if