+---------------------------------Fortran 95---------------------------------+
目的
FORALL ステートメントは、サブオブジェクトのグループへの割り当て、 特に配列エレメントへの割り当てを実行します。 WHERE ステートメントとは異なり、 割り当ては配列レベルではなく、要素レベルで実行されます。 FORALL ステートメントでは、 ポインター割り当ても可能です。
構文
>>-FORALL--forall_header--forall_assignment-------------------->< |
>>-(--forall_triplet_spec_list--+---------------------+--)----->< '-,--scalar_mask_expr-' |
>>-index_name-- = --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 ディレクティブを指定してください。 FORALL を並列化することが正しいかどうかを XL Fortran が判別できないこともあるため、 INDEPENDENT ディレクティブが、これが正しいことを断定します。 |
+------------------------------End of 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
関連情報
+------------------------------End of IBM 拡張-------------------------------+