>> English


通信と同期

グローバルビューモデル

reduction指示文

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

[F] !$xmp reduction ( reduction-kind : variable [, variable ]... ) [on node-ref | template-ref] [async ( async-id )]
[C] #pragma xmp reduction ( reduction-kind : variable [, variable ]... ) [on node-ref | template-ref] [async ( async-id )]

  • variableはローカル変数および分散配列が指定可能
  • reduction-kindは下記が利用可能
[F] +, *, -, .and., .or., .eqv., .neqv., max, min, iand, ior, ieor
[C] +, *, -, &, |, ^, &&, ||, max, min

bcast指示文

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

[F] !$xmp bcast ( variable [, variable]... ) [from nodes-ref | template-ref] [on nodes-ref] | template-ref] [async ( async-id )]
[C] #pragma xmp bcast  ( variable [, variable]... ) [from nodes-ref | template-ref] [on nodes-ref] | template\
-ref] [async ( async-id )]

  • from節で転送元を指定します.省略した場合はp(1)が指定されます
  • on節で転送先を指定します.省略した場合は全ノードに転送されます
  • on節で指定する転送先のノード集合はon節で指定する転送元ノードを含む必要があります
  • 例1:ローカル変数aを全ノードにブロードキャストします.

    #pragma xmp bcast (a)

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

    #pragma xmp bcast (a) from p(5) on p(5:7)

barrier指示文

バリア同期を行う.

[F] $!xmp barrier [on nodes-ref | template-ref]
[C] #pragma xmp barrier [on nodes-ref | template-ref]

  • on節が省略された場合,全ての実行ノードのバリア同期が発生する
  • 例1:すべてのノードは関数func_a()が終了するまで待機する

    func_a();
    #pragma xmp barrier
    func_b();

  • 例2:テンプレートtのインデックスが10から20を持つノードのみが,バリア同期の対象になる

    #pragma xmp barrier on t(10:20)

shadow指示文

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

[F] !$xmp shadow array-name ( shadow-width [, shadow-width]... )
[C] #pragma xmp shadow array-name ( shadow-width [, shadow-width]... )

where shadow-width must be one of:
   int-expr
   int-expr : int-expr
   *

  • shadow-widthは参照範囲の大きさを示します
  • int-exprは0以上の整数です
  • int-exprの場合は当該次元の上端と下端に同じ幅の袖領域が定義されます
  • int-expr:int-exprを用いると上端と下端に異なる幅の袖領域が定義できます
  • の場合は配列の全領域が袖領域になります

reflect指示文

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

[F] !$xmp reflect ( array-name [, array-name]... ) [width ( reflect-width [, reflect-width]... )] [async ( async-id )]
[C] #pragma xmp reflect array-name [, array-name]... ) [width ( reflect-width [, reflect-width]... )] [async ( async-id )]
  • 例:

    #pragma xmp template t(0: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];

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

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

  • n次元配列のm次元のみを分散させている場合(n>m),分散させていない次元は下記のように0という数字を用いて,その次元は袖領域がないことを宣言します.

    #pragma xmp template t(0:9)
    #pragma xmp nodes p(*)
    int a[10][20][30];
    #pragma xmp align a[i][*][*] with t(i)
    #pragma xmp shadow a[1][0][0]

gmove指示文

データ通信を行います.

[F] !$xmp gmove [in | out] [async ( async-id )]
[C] #pragma xmp gmove [in | out] [async ( async-id )]

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

    #pragma xmp gmove
      s1 = s2              // s1,s2 はスカラ変数

  • 例2:スカラ変数の代入文2

    #pragma xmp gmove
      a[3] = b[i][j]      // aとbはローカルで宣言された配列変数

  • 例3:分散配列の代入文1

    #pragma xmp gmove
      a[:] = b[:]      // aとbは分散配列.配列の全要素が代入される

  • 例4:分散配列の代入文2

    #pragma xmp gmove
    a[1:9] = b[n:9]   // 対応する要素数は一致している必要がある.

  • 例5:分散配列の代入文3

    #pragma xmp gmove
    a[1:10] = c    // cはスカラ変数.a[1:10]の要素すべてにcが代入される

  • 例6:in節の場合

    #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]

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

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

ローカルビューモデル

片側通信の記述を行う.Fortranの場合は,Coarray Fortranと同じである.

  • [C] 仕様書 ver. 1.0以前

    int tmp[N];
    #pragma xmp coarray tmp:[*]
    
    if(me == 1)   // me is a node number
      a[k:m] = tmp[j:m]:[2];
    
    #pragma xmp sync_memory

  • [C] 仕様書 ver. 1.1以降

    int tmp[N]:[*];
    int status;
    
    if(me == 1)   // me is a node number
      a[k:m] = tmp[j:m]:[2];
    
    xmp_sync_memory(&status);

    配列データをcoarrayとして定義し,ノード番号2が持つtmp[j]からm個の要素をノード1のa[k]から代入することを示している.sync_memoryでcoarrayによって行われた操作の完了を保証します.