HPF仕様の概要 (5)

− データおよびタスク並列に関する公認拡張機能 −

 

(株) 日立製作所 太田 寛

1997年2月12日

 

1. 概要

HPF2.0言語ではデータのプロセッサへのマッピングが記述できた。本拡張機能は、計算(処理)のマッピングに関するものである。これによりユーザは、

  ・計算を実行するプロセッサの指定

  ・通信不要の指示

  ・タスク並列の記述

が可能となる。

 新たに次の指示文が導入される。(HPF言語仕様書での登場順は、(1)と(2)が逆)

  (1) ON 計算を実行するプロセッサを指定する

  (2) SUBSET 部分プロセッサ配置を宣言する

  (3) RESIDENT 変数の参照に対して通信不要であることを指示する

  (4) TASK_REGION タスク並列処理を記述する

 

 

2. ON指示

計算を実行するプロセッサ(集合)を明示的に指示する。

 

2.1 構文

(1) ON指示文(ON directive)

 

HOME (変数)

!HPF$ ON HOME (テンプレート要素) [ , RESIDENT [(実体,...) [ , NEW (変数名,...)

(プロセッサ要素)

{ }は選択、[ ]は省略可を表す。

 

(2) ON構造(ON construct): BEGIN...ENDで囲んでブロック構造にもできる。

 

!HPF$ ON ・・・ BEGIN ! ・・・の内容は(1)と同じ

文の列

!HPF$ END ON

 

(3) 構文上の制約等

 ・実行部に記述する。

 ・ON構造はネスト可能。(ON指示文が含まれていても良い)

 

2.2 意味と用例

(1) ON指示文は、直後の文に適用され、その計算(処理)を実行するプロセッサを指定する。

 

!HPF$ PROCESSORS P(2)

!HPF$ TEMPLATE T(8)

REAL X(6)

!HPF$ ALIGN X(I) WITH T(I+2)

!HPF$ DISTRIBUTE T(BLOCK) ONTO P

 

!HPF$ ON HOME(X(2)) ! 配列要素X(2)のオーナプロセッサで実行

X(6)=X(1)+X(2)+X(3)

 

!HPF$ ON HOME(T(4)) ! テンプレート要素T(4)のオーナプロセッサで実行

X(6)=X(1)+X(2)+X(3)

 

!HPF$ ON (P(1)) ! プロセッサP(1)で実行

X(6)=X(1)+X(2)+X(3)


この例では、結局どの文もプロセッサP(1)で実行されることになる。(図 1参照)

図 1

 

(2) 指定されたプロセッサ上にないデータに対しては、計算の前後で通信を行う。

 上の(1)の例では、計算前にX(3)の値がP(1)に転送され、計算後にX(6)の値がP(2)転送される。

 

(3) ON構造は、含まれるすべての文に対して、実行プロセッサを指示する。

 

REAL A(N), B(N), C(N), D(N)

!HPF$ DISTRIBUTE(BLOCK) :: A, B, C, D

 

DO I=1,N-1

!HPF$ ON HOME(A(I+1)) BEGIN

C(I) = A(I+1)+B(I+1)    ON構造

D(I) = D(I+1)+C(I)

!HPF$ END ON

ENDDO

 

この例では、ループの各繰り返しが、A(I+1)のオーナで実行されることになる。

注) ON内の配列添字に現れる変数(この場合はI)の値は、制御到達時のものを使う。

 

(4) ある計算を実行するプロセッサとして、プロセッサの「集合」も指定できる。これをその計算の活動(active)プロセッサ集合と呼ぶ。例えば、HOME内に部分配列を書けば、そのいずれかの要素を持つプロセッサ全員が、活動プロセッサ集合に含まれる。

 

 ・これに対して、ONで指定されていないプロセッサも含めた全体を、全体(universal)プロセッサ集合と呼ぶ。

 ・これまでの例は、活動プロセッサ集合が単一のプロセッサのみからなる場合である。

 ・ONがネストしているときは、内側の活動プロセッサ集合は、外側の活動プロセッサ集合の部分集合になっていなければならない。

 

REAL X(16,16)

!HPF$ PROCESSORS P(4,4)

!HPF$ DISTRIBUTE X(BLOCK,BLOCK)

 

DO J=1,16

!HPF$ ON HOME(X(:,J)) BEGIN ! 活動プロセッサ集合はPの一列

DO I=2,16

!HPF$ ON HOME(X(I,J)) ! 活動プロセッサ集合はPの一要素

X(I,J) = (X(I-1,J)+X(I,J)) / 2

ENDDO

!HPF$ END ON

ENDDO

 

この例では、ネストしたループの各繰り返しが、配列の2次元分散に従って各プロセッサに割り当られる。例えば、(I,J) = (10,6) の繰り返しに対する活動プロセッサ集合は図 2のようになる。

 

図 2

 

(5) ONはあくまでコンパイラへのアドバイスであり、強制ではない。(処理系によってはON指示に従わないかも知れない)

 

(6) RESIDENT節は、参照される変数が活動プロセッサ集合上に存在することを表明する。

 

REAL X(N), Y(N)

INTEGER IX(M)

!HPF$ DISTRIBUTE(BLOCK) :: X, Y

 

DO I=1,N

!HPF$ ON HOME(X(I)), RESIDENT(Y(IX(I)))

X(I) = X(I) + Y(IX(I))

ENDDO

 

この例では、右辺のY(IX(I))という参照は、X(I)と同じプロセッサ上にあることになる。したがって、通信が不要である。

 RESIDENT節の詳細は4節で後述。

 

(7) NEW節は、変数がONの適用範囲内でのテンポラリ変数であることを表明する。すなわち、NEW節に現れた変数は、適用範囲の入口と出口で不定となる。(INDEPENDENTのNEW節と同じ)

 

2.3 手続き呼出しとON指示

(1) ONが手続き呼出しに適用された場合、呼出し先では、呼出し元の活動プロセッサ集合を引き継ぐ。

 

(2) 実引数と仮引数のマッピングに関する規則

実引数

必ずしも活動プロセッサ集合上にマッピングされていなくても良い。

仮引数

活動プロセッサ集合上にマッピングされていなければならない。

 

(3) 手続き境界でのリマッピングに関する規則

 規定、記述の場合はHPF2.0言語と同じだが、複写の場合が少し異なる。

 

仮引数のマッピングの種類

リマッピングに関する規則

規定

実引数とマッピングが不一致ならば、活動プロセッサ集合上にリマップされる。

記述

実引数とマッピングが一致しているというユーザの表明。コンパイラがそうでないと判断すれば、リマップされる。

複写

実引数は既に活動プロセッサ上に存在していなければならない。(ユーザ責任)

 

(4) 呼出された手続き内の変数のマッピングに関して、以下の規則がある。

 

変数のスコープ

マッピングに関する規則

局所変数および仮引数

 

活動プロセッサ集合上にマッピングされていなければならない。

大域変数(コモン、モジュールなど)

非活動プロセッサにマッピングされていても良い。

 

 活動プロセッサ集合へのマッピングを指示するために、次節のSUBSET指示文が設けられている。

 

 

3. SUBSET指示

ONの適用範囲内から呼出される手続きにおいて、活動プロセッサ集合に対するプロセッサ配置を宣言する。これを、部分プロセッサ配置(subset processor arrangement)と呼ぶ。

 

3.1 構文

(1) PROCESSORS指示文の属性形式

 

!HPF$ PROCESSORS, SUBSET :: プロセッサ配置名 [ ( 各次元寸法,... )

[ ]は省略可を表す。

 

(2) SUBSET指示文(SUBSET directive): 独立した指示文形式

 

!HPF$ SUBSET プロセッサ配置名

 

このとき、プロセッサ配置名はPROCESSORS指示文で宣言されていなければならない。

 

(3) 注意

 ・プロセッサ配置は、スカラであるか、または大きさが活動プロセッサの数と一致しなければならない。(処理系によっては、それ以外のものも許すかも知れない)

 ・プロセッサ配置がスカラの場合は、活動プロセッサ集合の中のいずれか一つのプロセッサを指定したことになる。

 

3.2 用例

(1) 局所変数を部分プロセッサ配置にマッピングする。

 

!HPF$ PROCESSORS, SUBSET :: P(2,4) ! 部分プロセッサ配置の形状は2×4

REAL A(20,40)

!HPF$ DISTRIBUTE A(BLOCK,BLOCK) ONTO P

 

(2) 活動プロセッサの数を実行時に得る。

 

!HPF$ PROCESSORS, SUBSET :: P(ACTIVE_NUM_PROCS())

 

この例で、ACTIVE_NUM_PROCSは、活動プロセッサ集合の数を返す、組み込み関数である。

 

4. RESIDENT指示

参照される変数が、活動プロセッサ集合上に存在することを表明する。(活動プロセッサがただ一つならば、これは通信不要を意味する。)

 

4.1 構文

(1) RESIDENT節(RESIDENT clause): ON指示文のオプション形式(2.1節で既出)

 

!HPF$ ON ・・・ , RESIDENT [( 実体,... )

・・・の内容は2.1節参照。 [ ]は省略可を表す。

 

(2) RESIDENT指示文(RESIDENT directive): 独立した指示文形式

 

!HPF$ RESIDENT [( 実体,... )  

 

(3) RESIDENT構造(RESIDENT directive): ブロック構造形式

 

!HPF$ RESIDENT [( 実体,... ) BEGIN

文の列

!HPF$ END RESIDENT

 

4.2 意味と用例

(1) 「実体」と字面上一致する参照が、ONで指定された活動プロセッサ集合上に存在することを、ユーザが表明する。

 

REAL X(N), Y(N), Z(N)

INTEGER IY(M), IZ(M)

!HPF$ DISTRIBUTE(BLOCK) :: X, Y, Z

 

DO I=1,N

!HPF$ ON HOME(X(I)), RESIDENT(Y(IY(I)))

X(I) = X(I) + Y(IY(I)) + Z(IZ(I))

ENDDO

 

この例では、右辺のY(IY(I))という参照は、X(I)と同じプロセッサ上にあることになる。したがって、通信が不要である。右辺のZ(IZ(I))という参照については何も言っていない。(したがっておそらく通信が必要)

 

(2) RESIDENT指示文やRESIDENT構造の形式によって、ON構造内の一部分に対してRESIDENTの指示ができる。

 

REAL X(N), Y(N)

INTEGER IY(M)

!HPF$ DISTRIBUTE(BLOCK) :: X, Y

 

DO I=1,N

!HPF$ ON HOME(X(I)) BEGIN

X(I) = X(I) + Y(IY(I)) ! この参照はRESIDENTでない。

IY(I) = ...

!HPF$ RESIDENT(Y(IY(I))

X(I) = X(I) + Y(IY(I)) ! この参照はRESIDENTである。

!HPF$ END ON

ENDDO

 

(3) 「実体」が省略されたときは、すべての参照に対してRESIDENTが指示されたことになる。

 

(4) 活動プロセッサ集合が複数のプロセッサを含むときは、「少なくともどれか一つの活動プロセッサ上に存在する」という意味になる。

 

!HPF$ PROCESSORS P(4,4)

REAL X(N,N)

!HPF$ DISTRIBUTE X(BLOCK,BLOCK) ONTO P

 

!HPF$ ON (P(1,1:4)), RESIDENT(X(K,1:N))

CALL FOO(X(K,1:N))

 

この例では、RESIDENT節によって、Xの第K行が2次元プロセッサ配置Pの第1行に存在していることが表明される(図 3参照)。なおこの場合、手続きFOOの中で、Pの第1行のプロセッサ間ではXの通信が起こるかも知れない。

図 3

 

(5) RESIDENT指示の正当性はユーザ責任であり、誤った指示の場合は、プログラムの結果が保証されないことに注意。

 

4.3 手続き呼出しとRESIDENT指示

(1) RESIDENTが手続き呼出しに適用された場合、呼出し先での参照に関する以下の規則に従わなければならない。

RESIDENTに(実体,...)の指定があるか

呼出し先での参照の扱い

ある場合

RESIDENTでなくても良い。

ない場合

RESIDENTでなければならない。

 

なお、手続き内の局所変数と仮引数は、2.3節の規則により、常にRESIDENTであることに注意。

 

5. TASK_REGION構造

タスク並列処理を指示する。

 

5.1 構文

(1) TASK_REGION構造(TASK_REGION construct)

 

!HPF$ TASK_REGION

文の列

!HPF$ END TASK_REGION

 

囲まれた部分をタスクリージョン(task region)と呼ぶ。

 

(2) 構文上の制約等

 ・タスクリージョンへの制御の飛び込みがあってはならない。

 

4.2 意味と用例

(1) タスク並列モデルでは、タスクリージョン内の最外側ON指示の適用範囲を一つのタスクと見なし、これらが並列に実行されると想定している。

 

!HPF$ PROCESSORS P(8)

!HPF$ DISTRIBUTE A(BLOCK) ONTO P(1:4)

!HPF$ DISTRIBUTE B(BLOCK) ONTO P(5:8)

 

!HPF$ TASK_REGION

!HPF$ ON (P(1:4)), RESIDENT

CALL COMPUTE_ATMOSPHERE(A) ! タスク1

並列実行

!HPF$ ON (P(5:8)), RESIDENT

CALL COMPUTE_OCEAN(A) ! タスク2

!HPF$ END TASK_REGION

 

この例では、タスク1がP(1:4)で、タスク2がP(5:8)でそれぞれ並行して実行される。

 

(2) タスクリージョン内計算では、次の制約が守られねばならない。

 ・最外側のON指示(タスクに対応)は、(実体,...)の指定なしのRESIDENT節を持たねばならない。

 ・異なるタスク実行内で起こる入出力は、それらのタスクの活動プロセッサ集合が同一の場合を除いて、互いに依存してはならない。

これにより、各タスクが独立に実行できることが保証される。(と、仕様書には書いてあるが、他にSTOP文が無いなどの条件も必要であろう)

 

−以上−