XcalableMP / Specification

Specification of XcalableMP
0 stars 0 forks source link

reduction節の意味の再検討 #14

Open mnakao opened 8 years ago

mnakao commented 8 years ago

報告者:岩下

現仕様では、loop指示文のreduction節の意味は、loop指示文を実行後、reduction指示文を実行したのと同じと定義されています。 この定義ではループ実行前の全ノードの値が加算されるため、利用者が普通に想像するloop reductionの結果(逐次実行と同じ結果)になりません。 OpenMPとHPFとXPFortranでは、仕様書の表現はまったく違うものの、逐次実行と同じ結果になるよう考えられています。

n=0                      ! 単位元で初期化
!$xmp loop on t(i) reduction(+:n)
do i=1,10
  n=n+1
enddo

この結果はノード数に依らず逐次と同じ 10 になります。

n=3                      ! nが単位元以外のとき
!$xmp loop on t(i) reduction(+:n)
do i=1,10
  n=n+1
enddo

この結果は、ノード数が N のとき 3*N+10 になります。 OpenMP、HPF、XPFortranでは、後者のように書いた場合にも、逐次と同じ 13 になります。 XMPの仕様をこのように決めた理由は忘れました。以下の2点で、当時と状況が異なっていますので、OpenMPなどと同じ仕様にする方がよいと考えます。

  1. XMP仕様は、スレッド並列を自然に扱えるようにしたい。OpenMPとXMPの両方が書ける、ではなく、できれば1つの自然な言語に見えるようにしていきたい。そういう方向性で考えると、OpenMPとXMPでreductionの仕様が違うのは障害になりそう。
  2. reduction節の定義は、OpenMP2.0のものもHPFのものもXMPとしては受け入れ難かった(これがXMPの仕様を独自にした理由だったか?)だが、最新OpenMP4.0の仕様定義は、XMPで受け入れられるのではないか?

1.について、例えば、XMPのloop指示行とOpenMPの!$omp doを1行で書こう、reductionは1つで済ませよう、という話をしていますが、このreductionの意味が難しくなります。現仕様では、

n=3
!$xmp loop on t(i) omp reduction(+:n)
do i=1,10
  n=n+1
enddo

と書くと、4プロセス×4スレッド実行の場合、3(プロセス数)+10=22 となります。3(プロセス数)*(スレッド数)+10 ならまだましですが、プロセス数だけ加算されるという仕様は不自然だと思います。

2.について、HPFでは、reduction variable(上の例ではn)が出現できる文をreduction statement(上の例ではn=n+1)として厳密に定義しています。OpenMP3.0以前では、HPFとは違う定義ですが、やはりreduction statementの縛りがあります。

XMPでは、ループ内のreduction variableの出現に制限を設けたくないので、これらと同じ定義にはできない、という考えだったと思います。OpenMP4.0になって、reductionの定義が大きく変わっています。ループの中reduction variableの出現には制限がなくなったように読めます。

具体的には、以下の定義とすればどうでしょうか。

!$xmp loop (i) on t(i) reduction(op:var)
do i
  ...
end do

は以下と等価である。

tmp = var             ! 各ノードで現在の値を退避
var = 0               ! 演算opの単位元を代入
!$xmp loop (i) on t(i)
do i
      ...
end do
!$xmp reduction(op:var)
var = tmp op var      ! 退避していた値を左から加える

ただし、op が '-' のときについてはべつの議論 BTS:37 op が FIRSTMAX/MIN, LASTMAX/MINのときについても検討が必要