+---------------------------------Fortran 95---------------------------------+
目的
FORALL ステートメントは、サブオブジェクトのグループへの割り当て、特に配列エレメントへの割り当てを実行します。 WHERE ステートメントとは異なり、割り当ては配列レベルではなく、要素レベルで実行されます。 FORALL ステートメントでは、ポインター割り当ても可能です。
構文
>>-FORALL--forall_header--forall_assignment-------------------->< |
>>-(--forall_triplet_spec_list--+---------------------+--)----->< '-,--scalar_mask_expr-' |
>>-index_name-- = --subscript-- : --subscript-- : --subscript---> >--+-------------+--------------------------------------------->< '- : --stride-' |
規則
forall_header のマスク式、および forall_assignment の中で参照できるのは、純粋プロシージャーだけです (定義済み操作または割り当てによって参照されるものを含む)。
index_name は、スカラー整数の変数でなければなりません。また、これはステートメント・エンティティーです。つまり、有効範囲単位内の他のエンティティーに影響を与えたり、影響を受けたりしません。
forall_triplet_spec_list の中の subscript および stride には、forall_triplet_spec_list の中の index_name への参照を含めることはできません。 forall_header の中の式の評価は、forall_header の中の他の式の評価に影響を与えてはなりません。
forall_triplet_spec が次のとおりであるとします。
index1 = s1:s2:s3
指標の最大値は、次のようにして判別されます。
max = INT((s2-s1+s3)/s3)
ストライド (上記の s3) が指定されない場合、値 1 が想定されます。どの指標でも max <= 0 の場合、 forall_assignment は実行されません。以下に例を示します。
index1 = 2:10:3 ! The index values are 2,5,8. max = INT((10-2+3)/3) = 3. index2 = 6:2:-1 ! The index values are 6,5,4,3,2. index2 = 6:2 ! No index values.
マスク式が省略されると、.TRUE. の値が想定されます。
アトミック・オブジェクトを複数回割り当てることはできません。アトミックでないオブジェクトへの割り当ては、すべてのサブオブジェクトへ割り当てるか、またはターゲットをすべてのサブオブジェクトと関連させます。
FORALL (I=1:3,J=4:5) A(I,J) = A(J,I)I および J の組み合わせの集合は次のとおりです。
{(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)}
-1 および -qnozerosize コンパイラー・オプションは、このステップに影響を与えません。
{(1,4),(2,5),(3,4),(3,5)}
pointer_assignment の場合、すべてのアクティブな index_name 値の組み合わせについて、順序に関係なく、何がポインター割り当てのターゲットになるのかを判別し、すべての添え字、ストライド、およびサブストリング境界を評価します。ターゲットがポインターであるかどうかにかかわりなく、ターゲットの判別には、その値の評価は含まれません。
pointer_assignment の場合、すべてのアクティブな index_name 値の組み合わせについて、順序に関係なく、すべてのターゲットを、対応するポインター・エンティティーに関連させます。
FORALL ステートメントおよび FORALL 構造体は、代入ステートメントの並列化が可能となるように設計されています。 FORALL 内で代入ステートメントを実行する場合、オブジェクトの割り当ては、他のオブジェクトの割り当てに影響を与えません。次の例では、結果を変更しないで、順序に関係なく、A のエレメントへの割り当てを実行できます。
FORALL (I=1:3,J=1:3) A(I,J)=A(J,I)
+----------------------------------IBM 拡張----------------------------------+
INDEPENDENT ディレクティブを指定すると、 DO ループの各反復または FORALL ステートメントあるいは FORALL 構造体内での各操作を、任意の順序で、プログラムのセマンティクスに影響を与えずに実行することができます。FORALL ステートメントまたは FORALL 構造体内の操作は、以下のように定義されます。
したがって、以下のループ
INTEGER, DIMENSION(2000) :: A,B,C !IBM* INDEPENDENT DO I = 1, 1999, 2 A(I) = A(I+1) END DO
は、意味上では以下の配列割り当てに等価です。
INTEGER, DIMENSION(2000) :: A,B,C A(1:1999:2) = A(2:2000:2)
ヒント |
---|
特定の FORALL を並列処理することが可能であり、利点がある場合には、 FORALL の前に、INDEPENDENT ディレクティブを指定してください。 XL Fortran は、 FORALL を並列化することが有効かどうかを必ず判別できるわけではないので、 INDEPENDENT ディレクティブによって有効であることが保証されます。 |
+--------------------------------IBM 拡張の終り-------------------------------+
例
INTEGER A(1000,1000), B(200) I=17 FORALL (I=1:1000,J=1:1000,I.NE.J) A(I,J)=A(J,I) PRINT *, I ! The value 17 is printed because the I ! in the FORALL has statement scope. FORALL (N=1:200:2) B(N)=B(N+1) END
関連情報
+--------------------------------IBM 拡張の終り-------------------------------+