目的
ASSERT ディレクティブは、コンパイラーに、 ソース・コードの最適化を支援する DO ループの特性を提供します。
ASSERT ディレクティブは、-qhot または -qsmp コンパイラー・オプションを指定すると有効になります。
構文
>>-ASSERT--(--assertion--)------------------------------------->< |
規則
ASSERT ディレクティブに続く 最初の非コメント行 (他のディレクティブは含まない) は、DO ループで なければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 ASSERT ディレクティブは、 ディレクティブの直後にある DO ループにのみ適用され、 ネストされた DO ループには適用されません。
ITERCNT は、DO ループが通常実行する 繰り返し回数のおおまかな見積もりをコンパイラーに提供します。 この値は正確である必要はありません。 ITERCNT はパフォーマンスにのみ影響し、正確度には影響しません。
NODEPS を指定すると、ユーザーは、DO ループ内、 または DO ループ内から呼び出されたプロシージャー内に、 ループ運搬依存関係が存在しないことを明示的にコンパイラーに宣言したことになります。 ループ運搬依存関係には、DO ループ内にあって 相互に妨害する 2 つの繰り返しが関係しています。 妨害は、次の状況で生じます。
互いに補完する 2 つの ASSERT ディレクティブを 1 つ の DO ループに適用することは可能です。 しかし、ASSERT ディレクティブの後に、 同一の DO ループの 矛盾した ASSERT ディレクティブを入れることはできません。
!IBM* ASSERT (ITERCNT(10)) !IBM* INDEPENDENT, REDUCTION (A) !IBM* ASSERT (ITERCNT(20)) ! invalid DO I = 1, N A(I) = A(I) * I END DO
上記の例では、ASSERT(ITERCNT(20)) ディレクティブは、 ASSERT(ITERCNT(10)) ディレクティブと矛盾しているので、無効です。
ASSERT ディレクティブは、ASSERT ディレクティブが 指定されている DO ループ の -qassert コンパイラー・オプションをオーバーライドします。
例
例 1:
! An example of the ASSERT directive with NODEPS. PROGRAM EX1 INTEGER A(100) !IBM* ASSERT (NODEPS) DO I = 1, 100 A(I) = A(I) * FNC1(I) END DO END PROGRAM EX1 FUNCTION FNC1(I) FNC1 = I * I END FUNCTION FNC1
例 2:
! An example of the ASSERT directive with NODEPS and ITERCNT. SUBROUTINE SUB2 (N) INTEGER A(N) !IBM* ASSERT (NODEPS,ITERCNT(100)) DO I = 1, N A(I) = A(I) * FNC2(I) END DO END SUBROUTINE SUB2 FUNCTION FNC2 (I) FNC2 = I * I END FUNCTION FNC2
関連情報
目的
BLOCK_LOOP ディレクティブを使用すると、ユーザーは、ループ・ネスト内の 特定 DO ループの最適化をより制御できます。 BLOCK_LOOP ディレクティブはブロック化という技法を使用して、 反復カウントの多い DO ループを小さな反復グループに分けます。 これらの小さなグループを実行することにより、キャッシュ・スペースの 使用および引き数パフォーマンスの効率を高めることができます。
依存関係を持つループに BLOCK_LOOP を適用すると、 代替の入り口点または出口点が、予期しない結果を発生させます。
構文
>>-BLOCK_LOOP--(--n--+--------------+--)----------------------->< '-,--name_list-' |
name を指定しない場合、BLOCK_LOOP ディレクティブの直後にある 最初の DO ループでブロック化が発生します。
規則
ループ・ブロック化を行う場合、BLOCK_LOOP ディレクティブは DO ループの前になければなりません。
BLOCK_LOOP ディレクティブを複数回指定することはできません。 また、1 つの DO の構文で、このディレクティブを NOUNROLL_AND_FUSE、NOUNROLL、UNROLL、UNROLL_AND_FUSE、 または STREAM_UNROLL ディレクティブと結合することはできません。
BLOCK_LOOP ディレクティブを DO WHILE ループ または無限 DO ループに指定することはできません。
例
! Loop Tiling for Multi-level Memory Heirarchy 2 3 4 INTEGER :: M, N, i, j, k 5 M = 1000 6 N = 1000 7 8 !IBM* BLOCK_LOOP(L3_cache_size, L3_cache_block) 9 do i = 1, N 10 11 !IBM* LOOPID(L3_cache_block) 12 !IBM* BLOCK_LOOP(L2_cache_size, L2_cache_block) 13 do j = 1, N 14 15 !IBM* LOOPID(L2_cache_block) 16 do k = 1, M 17 do l = 1, M 18 . 19 . 20 . 21 end do 22 end do 23 end do 24 end do 25 26 end 27 28 The compiler generated code would be equivalent to: 29 30 do index1 = 1, M, L3_cache_size 31 do i = 1, N 32 do index2 = index1, min(index1 + L3_cache_size, M), L2_cache_size 33 do j = 1, N 34 do k = index2, min(index2 + L2_cache_size, M) 35 do l = 1, M 36 . 37 . 38 . 39 end do 40 end do 41 end do 42 end do 43 end do 44 end do
関連情報
目的
CNCALL ディレクティブを DO ループの前に置くと、ユーザーは、DO ループから呼び出された プロシージャー内にループ運搬依存関係が存在しないことをコンパイラーに明示的に宣言したことになります。
このディレクティブが有効なのは、-qsmp または -qhot コンパイラー・オプションのいずれかが 指定されているときに限られます。
構文
>>-CNCALL------------------------------------------------------>< |
規則
CNCALL ディレクティブに続く最初の非コメント行 (他のディレクティブは含まない) は、 DO ループでなければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 CNCALL ディレクティブは、 ディレクティブの直後にある DO ループにのみ適用され、 ネストされた DO ループには適用されません。
CNCALL ディレクティブを指定すると、ユーザーは、DO ループ内で呼び出されたプロシージャーには ループ運搬依存関係がないことをコンパイラーに明示的に宣言したことになります。 DO ループがプロシージャーを呼び出す場合、ループのそれぞれの繰り返しがそのプロシージャーを同時に 呼び出せなければなりません。 CNCALL ディレクティブは、ループ内の他の操作に依存性がないと断定するものではありません。 これは単にプロシージャーの参照についての断定です。
ループ運搬依存関係は、DO ループ内にある 2 つの繰り返しが互いに妨害するときに生じます。 妨害の定義については、 ASSERT ディレクティブを参照してください。
例
! An example of CNCALL where the procedure invoked has ! no loop-carried dependency but the code within the ! DO loop itself has a loop-carried dependency. PROGRAM EX3 INTEGER A(100) !IBM* CNCALL DO I = 1, N A(I) = A(I) * FNC3(I) A(I) = A(I) + A(I-1) ! This has loop-carried dependency END DO END PROGRAM EX3 FUNCTION FNC3 (I) FNC3 = I * I END FUNCTION FNC3
関連情報
目的
COLLAPSE ディレクティブは、配列次元の下限のエレメントのみがアクセス可能であると指定することによって、 配列次元全体を単一のエレメントまでに削減します。 下限を指定しない場合は、デフォルトの下限は 1 になります。
慎重に使用すれば、COLLAPSE ディレクティブは、複数次元の配列に関連した反復メモリー・アクセスを 削減することによって、容易にパフォーマンスを向上させることができます。
構文
>>-COLLAPSE--(--collapse_array_list--)------------------------->< |
collapse_array の意味は次のとおりです。
>>-array_name--(--expression_list--)--------------------------->< |
ここで expression_list は、コンマで区切られた式のリストです。
規則
COLLAPSE ディレクティブには、最低でも 1 つの配列を含む必要があります。
COLLAPSE ディレクティブは、 そのディレクティブが指定されている有効範囲単位に対してのみ適用されます。 COLLAPSE ディレクティブに含まれる配列の宣言は、 そのディレクティブと同じ有効範囲単位内にある必要があります。使用関連付けまたはホスト関連付けによって有効範囲単位内でアクセス可能な配列は、 その有効範囲単位内の COLLAPSE ディレクティブに指定してはなりません。
expression_list に指定できる下限の値は 1 です。上限の値は、 対応する配列内の次元数より大きくすることはできません。
単一の有効範囲単位に複数の COLLAPSE 宣言を含むことができますが、 配列は特定の有効範囲単位について一度だけしか指定できません。
1 つの配列を COLLAPSE ディレクティブと EQUIVALENCE ステートメントの両方に指定することはできません。
COLLAPSE ディレクティブは、派生型のコンポーネントである配列と一緒に使用することはできません。
1 つの配列に対して COLLAPSE と SUBSCRIPTORDER の両方のディレクティブを適用する場合は、 最初に SUBSCRIPTORDER ディレクティブを指定する必要があります。
COLLAPSE ディレクティブは、以下の配列に適用されます。
例
例 1: 以下の例では、COLLAPSE ディレクティブは明示的形状配列 A および B に 適用されます。 内部ループの A(m,2:100,2:100) と B(m,2:100,2:100) の参照は、A(m,1,1) と B(m,1,1) になります。
!IBM* COLLAPSE(A(2,3),B(2,3)) REAL*8 A(5,100,100), B(5,100,100), c(5,100,100) DO I=1,100 DO J=1,100 DO M=1,5 A(M,J,I) = SIN(C(M,J,I)) B(M,J,I) = COS(C(M,J,I)) END DO DO M=1,5 DO N=1,M C(M,J,I) = C(M,J,I) + A(N,J,I)*B(6-N,J,I) END DO END DO END DO END DO END
関連情報
SUBSCRIPTORDER ディレクティブの詳細については、SUBSCRIPTORDERを参照してください
目的
EJECT は、ソース・リストの新しいページを開始するよう コンパイラーに指示するためのものです。 ソース・リストの要求がない場合、 コンパイラーは、このディレクティブを無視します。
構文
>>-EJECT------------------------------------------------------->< |
規則
EJECT コンパイラー・ディレクティブには、インライン・コメントやラベルを組み込めます。 しかし、ステートメント・ラベルを指定しても、コンパイラーはそれを破棄します。 したがって、EJECT ディレクティブ内のラベルを参照してはなりません。 ディレクティブの使用例としては、リスト内の複数ページに分割したくない重要な DO ループがある場合に、 そのループの前で使用します。 ソース・リストをプリンターに送信すると、EJECT ディレクティブは改ページの役目を果たします。
目的
INCLUDE コンパイラー・ディレクティブは、 指定されたステートメントまたは一群の ステートメントをプログラム単位に挿入します。
構文
>>-INCLUDE--+-char_literal_constant-+--+---+------------------->< '-(--name--)------------' '-n-' |
必要なファイルの絶対パスを必ずしも指定する必要はありませんが、存在する場合はファイル拡張子を指定する必要があります。
name には、XL Fortran の文字セットで使用可能な文字のみを入れます。 XL Fortran でサポートしている文字については、文字を参照してください。
char_literal_constant は文字リテラル定数です。
条件付きインクルードを使用すると、コンパイル時に Fortran ソース内で INCLUDE ディレクティブを選択的に 活動化することができます。 -qci コンパイラー・オプションを使用して、組み込むファイルを指定します。
固定ソース形式では、INCLUDE コンパイラー・ディレクティブは 6 桁目から始める必要があります。 ラベルも付けられます。
インライン・コメントを INCLUDE 行に追加することができます。
規則
インクルード・ファイルには、完全な Fortran ソース・ステートメントまたはコンパイラー・ディレクティブであれば、 どのようなステートメント (他の INCLUDE コンパイラー・ディレクティブも含む) でも入れることができます。 再帰的 INCLUDE コンパイラー・ディレクティブは使用できません。 END ステートメントは組み込まれるグループに含めてもかまいません。 最初および最後の組み込み行は、継続行であってはなりません。 インクルード・ファイルのステートメントは、組み込み先のファイルのソース形式で処理されます。
SOURCEFORM ディレクティブがインクルード・ファイル内にある場合、インクルード・ファイルの処理が 完了すると、ソース形式は、組み込み先のファイルのソース形式に戻ります。 すべてのグループを組み込んで完成した Fortran プログラムは、ステートメントの順序に関する Fortran のすべての 規則に従うものでなければなりません。
XL Fortran は、左括弧と右括弧の構文を持つ INCLUDE コンパイラー・ディレクティブについて、 -qmixed コンパイラー・オプションがオンになっている場合を除いて、ファイル名を小文字に変換します。
ファイル・システムは以下のようにして、指定された filename を探します。
例
INCLUDE '/u/userid/dc101' ! full absolute file name specified INCLUDE '/u/userid/dc102.inc' ! INCLUDE file name has an extension INCLUDE 'userid/dc103' ! relative path name specified
INCLUDE (ABCdef) ! includes file abcdef
INCLUDE '../Abc' ! includes file Abc from parent directory ! of directory being searched
関連情報
「XL Fortran ユーザーズ・ガイド」の『-qci オプション』
目的
INDEPENDENT ディレクティブを使用する場合は、 DO ループ、FORALL ステートメント、または FORALL 構文の 前に置かなければなりません。 INDEPENDENT ディレクティブは、FORALL ステートメント または FORALL 構文の各演算をどの順序で行ってもプログラムの セマンティクスに影響しないで済むようにします。 このディレクティブは、プログラムのセマンティクスに影響することなく、 DO ループ内で任意の順序で反復を行うことを指定します。
型
このディレクティブが有効なのは、-qsmp または -qhot コンパイラー・オプションのいずれかが 指定されているときに限られます。
構文
.---------------------------------------------. V | >>-INDEPENDENT----+-----------------------------------------+-+->< +-,--NEW--(--named_variable_list--)-------+ '-,--REDUCTION--(--named_variable_list--)-' |
規則
INDEPENDENT に続く 最初の非コメント行 (他のディレクティブは含まない) は、DO ループ、 FORALL ステートメント、または FORALL 構文の 最初のステートメントでなければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 INDEPENDENT ディレクティブは、 ディレクティブの直後にある DO ループにのみ適用され、 ネストされた DO ループには適用されません。
INDEPENDENT ディレクティブには、最大で 1 つの NEW 文節 と最大で 1 つの REDUCTION 文節を組み込めます。
このディレクティブを DO ループに適用すると、 ループの繰り返しは互いに妨害することはありません。 妨害は、次の状況で生じます。
NEW 文節を指定する場合は、このディレクティブを DO ループに適用する必要があります。 NEW 文節は、このディレクティブとそのまわりにある INDEPENDENT ディレクティブを修正します。 この修正は、NEW 文節がそのようなディレクティブによる断定を正しいと見なすことによって生じるもので、 NEW 文節で指定されている変数がループの繰り返しごとに修正される場合でも発生します。 NEW 文節で指定されている変数は、DO ループ本体のプライベート変数であるかのような働きをします。 つまり、これらの変数 (およびそれと関連している変数) がループの繰り返しの前後に未定義になっても、プログラムには 影響がありません。
NEW 文節または REDUCTION 文節で指定する変数には、次の制約事項があります。
FORALL の場合、INDEPENDENT ディレクティブによって影響を受けた指標値の組み合わせは、 他の組み合わせによって要求されるまではアトミック記憶装置に割り振りを行いません。 DO ループ、FORALL ステートメント、または FORALL 構文が同じ本体を持ち、 それぞれの前に INDEPENDENT ディレクティブがある場合、これらはみな同じ機能を果たします。
REDUCTION 文節は、INDEPENDENT ループの REDUCTION ステートメント内で名前付き変数が 更新されたと断定します。 さらに並列セクション内では、REDUCTION 変数の中間値は、更新そのもの以外では使用されません。 したがって、構文の後の REDUCTION 変数の値は、縮約ツリーの結果になります。
REDUCTION 文節を指定する場合は、このディレクティブを DO ループに適用しなければなりません。 INDEPENDENT DO ループの REDUCTION 変数に対する唯一の参照は、縮約ステートメントになければ なりません。
REDUCTION 変数は、組み込み型でなければなりませんが、型文字であってはなりません。 REDUCTION 変数は割り振り可能配列にはできません。
REDUCTION 変数は、以下のものの中に入れることはできません。
REDUCTION ステートメントの形式は、次のいずれかになります。
>>-reduction_var_ref--=--expr--reduction_op--reduction_var_ref->< >>-reduction_var_ref--=--reduction_var_ref--reduction_op--expr->< >>-reduction_var_ref =--reduction_function--(expr,--reduction_var_ref)->< >>-reduction_var_ref =--reduction_function--(reduction_var_ref,--expr)->< |
それぞれの意味は次のとおりです。
REDUCTION ステートメントには次の規則が適用されます。
>>-reduction_var_ref-- = --expr-- - --reduction_var_ref-------->< |
例
例 1:
INTEGER A(10),B(10,12),F !IBM* INDEPENDENT ! The NEW clause cannot be FORALL (I=1:9:2) A(I)=A(I+1) ! specified before a FORALL !IBM* INDEPENDENT, NEW(J) DO M=1,10 J=F(M) ! 'J' is used as a scratch A(M)=J*J ! variable in the loop !IBM* INDEPENDENT, NEW(N) DO N=1,12 ! The first executable statement B(M,N)=M+N*N ! following the INDEPENDENT must END DO ! be either a DO or FORALL END DO END
例 2:
X=0 !IBM* INDEPENDENT, REDUCTION(X) DO J = 1, M X = X + J**2 END DO
例 3:
INTEGER A(100), B(100, 100) !IBM* INDEPENDENT, REDUCTION(A), NEW(J) ! Example showing an array used DO I=1,100 ! for a reduction variable DO J=1, 100 A(I)=A(I)+B(J, I) END DO END DO
関連情報
目的
#line ディレクティブは、cpp によって 作成されるコードまたは Fortran ソース・コード生成プログラムを、 プログラマーによって作成される入力コードと関連付けます。プリプロセッサーによりコード行が挿入されたり削除されたりする ことがありますが、#line ディレクティブはオリジナルのソースの どの行からプリプロセッサーが中間ファイルの対応する行を生成したかを 示すので、エラーの報告やデバッグの際に便利です。
構文
>>-#line--line_number--+----------+---------------------------->< '-filename-' |
#line ディレクティブは非コメント・ディレクティブであり、この型のディレクティブの 構文規則に従います。
規則
The #line ディレクティブは、他の非コメント・ディレクティブと同じ規則に従います。 ただし、次のものは例外です。
#line ディレクティブは、現行ファイルのそのディレクティブに続くすべてのコードの起点を示します。別の #line ディレクティブが現れると、前のものは取り消されます。
filename を指定すると、現行ファイル内の続くコードは、その起点がその filename からで あるときと同じようになります。 filename を省略し、現行ファイル内のそれよりも前に filename を指定した #line ディレクティブが存在しない場合、現行ファイルのコードは、指定された行番号の 現行ファイルが起点になっているかのように扱われます。 filename が指定されている、前の #line ディレクティブが現行ファイルに存在する場合、 その前のディレクティブの filename が使用されます。
line_number は、適切なファイル内の、ディレクティブに続くコードの行の位置を示します。そのファイル内の続く行は、別の #line ディレクティブが指定されるか、またはファイルが 終了するまで、ソース・ファイルにある続く行と 1 対 1 で対応していると想定されます。
XL Fortran がファイルに対して cpp を起動するときに、プリプロセッサーは、#line ディレクティブを 出力します。 これは、-d オプションを指定すると行われません。
例
ファイル test.F の内容は以下のとおりです。
! File test.F, Line 1 #include "test.h" PRINT*, "test.F Line 3" ... PRINT*, "test.F Line 6" #include "test.h" PRINT*, "test.F Line 8" END
ファイル test.h の内容は以下のとおりです。
! File test.h line 1 RRINT*,1 ! Syntax Error PRINT*,2
C プリプロセッサー () で、デフォルト・オプションを 指定してファイル test.F を処理した後は次のようになります。
#line 1 "test.F" ! File test.F, Line 1 #line 1 "test.h" ! File test.h Line 1 RRINT*,1 ! Syntax Error PRINT*,2 #line 3 "test.F" PRINT*, "test.F Line 3" ... #line 6 PRINT*, "test.F Line 6" #line 1 "test.h" ! File test.h Line 1 RRINT*,1 ! Syntax Error PRINT*,2 #line 8 "test.F" PRINT*, "test.F Line 8" END
コンパイラーは、C プリプロセッサーによって作成されたファイルを 処理した後に、次のメッセージを表示します。
2 2 |RRINT*,1 !Syntax error ......a................ a - "test.h", line 2.6: 1515-019 (S) Syntax is incorrect. 4 2 |RRINT*,1 !Syntax error ......a................ a - "test.h", line 2.6: 1515-019 (S) Syntax is incorrect.
関連情報
目的
LOOPID ディレクティブを使用すると、有効範囲単位内のループに固有 ID を割り当てることができます。 この ID を使用してループ変換を指示できます。 -qreport コンパイラー・オプションでは、 ユーザーが作成した ID を使用して、ループ変換についてのレポートを提供できます。
構文
>>-LOOPID--(--name--)------------------------------------------>< |
規則
LOOPID ディレクティブは、BLOCK_LOOP ディレクティブ または DO 構文の直前になければなりません。
指定のループについて LOOPID ディレクティブを複数回指定することはできません。
制御ステートメントのない DO 構文、DO WHILE 構文、 または無限 DO には、LOOPID ディレクティブを指定しないでください。
関連情報
目的
NOSIMD ディレクティブは、ディレクティブの直後にあるループ、 または FORALL 構文でコンパイラーが自動的に Vector Multimedia eXtension (VMX) 命令を生成することを禁止します。
構文
>>-NOSIMD------------------------------------------------------>< |
規則
NOSIMD に続く 最初の非コメント行 (他のディレクティブは含まない) は、DO ループ、FORALL ステートメント、 または FORALL 構文の最初のステートメントでなければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 NOSIMD ディレクティブは、 ディレクティブの直後にある DO ループにのみ適用され、 ネストされた DO ループには適用されません。
NOSIMD ディレクティブを、ループ最適化と SMP ディレクティブとともに 使用することができます。
例
SUBROUTINE VEC (A, B) REAL*8 A(200), B(200) !IBM* NOSIMD FORALL (N = 1:200), B(N) = B(N) / A(N) END SUBROUTINE
関連情報
アプリケーション全体に対する VMX サポートの制御については、-qhot=simd コンパイラー・オプションを参照してください。
目的
NOVECTOR ディレクティブは、ディレクティブの直後にあるループ、または FORALL ステートメントでコンパイラーが自動ベクトル化 を行うことを禁止します。 自動ベクトル化とは、ループまたは連続する配列エレメントで実行される操作を、 いくつかの結果を同時に計算するルーチンへの呼び出しに変換することを指します。
構文
>>-NOVECTOR---------------------------------------------------->< |
規則
NOVECTOR に続く 最初の非コメント行 (他のディレクティブは含まない) は、DO ループ、FORALL ステートメント、 または FORALL 構文の最初のステートメントでなければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 NOVECTOR ディレクティブは、 ディレクティブの直後にある DO ループにのみ適用され、 ネストされた DO ループには適用されません。
NOVECTOR ディレクティブを、ループ最適化と SMP ディレクティブとともに 使用することができます。
例
SUBROUTINE VEC (A, B) REAL*8 A(200), B(200) !IBM* NOVECTOR DO N = 1, 200 B(N) = B(N) / A(N) END DO END SUBROUTINE
関連情報
アプリケーション全体に対する自動ベクトル化の制御については、-qhot=vector コンパイラー・オプションを参照してください。
目的
PERMUTATION ディレクティブは、integer_array_name_list でリスト されている各配列のエレメントが繰り返し値を持たないように指定します。 このディレクティブは、配列エレメントが他の配列参照の添え字として 使用されているときに便利です。
PERMUTATION ディレクティブが有効なのは、-qsmp また は -qhot コンパイラー・オプションのいずれかが 指定されているときに限られます。
構文
>>-PERMUTATION--(--integer_array_name_list--)------------------>< |
規則
PERMUTATION ディレクティブに続く最初の非コメント行 (他のディレクティブは 含まない) は、DO ループでなければなりません。 この行は、無限の DO または DO WHILE ループに することはできません。 PERMUTATION ディレクティブは、ディレクティブの直後にある DO ループ にのみ適用され、ネストされた DO ループには適用されません。
例
PROGRAM EX3 INTEGER A(100), B(100) !IBM* PERMUTATION (A) DO I = 1, 100 A(I) = I B(A(I)) = B(A(I)) + A(I) END DO END PROGRAM EX3
関連情報
目的
ソース・ファイルに @PROCESS コンパイラー・ディレクティブを 入れることにより、個々のコンパイル単位に影響を与えるように コンパイラー・オプションを指定することができます。 構成ファイルまたはデフォルト設定あるいはコマンド行 で指定したオプションをオーバーライドすることができます。
構文
.-+---+----------------------------. | '-,-' | V | >>-@PROCESS----option--+----------------------+-+-------------->< '-(--suboption_list--)-' |
規則
固定ソース形式では、@PROCESS は 1 桁目から、または 6 桁目より後から開始できます。 自由ソース形式では、@PROCESS コンパイラー・ディレクティブは、 どの桁からでも開始できます。
ステートメント・ラベルまたはインライン・コメント を @PROCESS コンパイラー・ディレクティブと同じ行に入れることはで きません。
デフォルト時には、@PROCESS コンパイラー・ディレクティブで指定する オプション設定は、ステートメントが存在するコンパイル単位に対してのみ有効です。 ファイルが複数のコンパイル単位を持っている場合は、 オプション設定は、次の単位がコンパイルされる前に、元の状態にリセットされます。 DIRECTIVE オプション によって指定されたトリガー定数は、 ファイルの終わりまで (または、NODIRECTIVE が処理されるまで) 有効です。
@PROCESS コンパイラー・ディレクティブは、通常、 コンパイル単位の最初のステートメントの前になければなりません。 唯一の例外は、SOURCE および NOSOURCE を指定する場合です。 この 2 つは、コンパイル単位内のいかなる場所にある @PROCESS ディレクティブ でも使用できます。
関連情報
コンパイラー・オプションについて詳しくは、「XL Fortran ユーザーズ・ガイド」の 『コンパイラー・オプションの詳細記述』を 参照してください。
目的
SNAPSHOT ディレクティブを使用して、デバッグ・プログラムでブレークポイントを設定できる安全な位置を 指定できます。 さらに、デバッグ・プログラムに対して可視のままにする必要のある変数のセットを提供できます。 SNAPSHOT ディレクティブは、-qsmp コンパイラー・オプション (非マルチスレッド・プログラムでも使用できます) のサポートを提供します。
SNAPSHOT ディレクティブが設定されたポイントで、わずかなパフォーマンス低下がある場合があります。 これは、デバッグ・プログラムがアクセスするために、変数をメモリーに保持する必要があるためです。 SNAPSHOT ディレクティブによって可視にされた変数は、読み取り専用です。 これらの変数をデバッガーを通して変更すると、未定義の動作が発生します。 慎重に使用してください。
構文
>>-SNAPSHOT--(--named_variable_list--)------------------------->< |
規則
SNAPSHOT ディレクティブを使用するには、 コンパイル時に -qdbg コンパイラー・オプションを指定する必要があります。
例
例 1: 次の例では、プライベート変数の値をモニターするために、 SNAPSHOT ディレクティブが使用されています。
INTEGER :: IDX INTEGER :: OMP_GET_NUM_THREADS, OMP_GET_THREAD_NUM INTEGER, ALLOCATABLE :: ARR(:) ! ... !$OMP PARALLEL, PRIVATE(IDX) !$OMP MASTER ALLOCATE(ARR(OMP_GET_NUM_THREADS())) !$OMP END MASTER !$OMP BARRIER IDX = OMP_GET_THREAD_NUM() + 1 !IBM* SNAPSHOT(IDX) ! The PRIVATE variable IDX is made visible ! to the debugger. ARR(IDX) = 2*IDX + 1 !$OMP END PARALLEL
例 2: 次の例では、プログラムのデバッグで中間値をモニターするために、 SNAPSHOT ディレクティブが使用されます。
SUBROUTINE SHUFFLE(NTH, XDAT) INTEGER, INTENT(IN) :: NTH REAL, INTENT(INOUT) :: XDAT(:) INTEGER :: I_TH, IDX, PART(1), I, J, LB, UB INTEGER :: OMP_GET_THREAD_NUM INTEGER(8) :: Y=1 REAL :: TEMP CALL OMP_SET_NUM_THREADS(NTH) PART = UBOUND(XDAT)/NTH !$OMP PARALLEL, PRIVATE(NUM_TH, I, J, LB, UB, IDX, TEMP), SHARED(XDAT) NUM_TH = OMP_GET_THREAD_NUM() + 1 LB = (NUM_TH - 1)*PART(1) + 1 UB = NUM_TH*PART(1) DO I=LB, UB !$OMP CRITICAL Y = MOD(65539_8*y, 2_8**31) IDX = INT(REAL(Y)/REAL(2_8**31)*(UB - LB) + LB) !SMP$ SNAPSHOT(i, y, idx, num_th, lb, ub) !$OMP END CRITICAL TEMP = XDAT(I) XDAT(I) = XDAT(IDX) XDAT(IDX) = TEMP ENDDO !SMP$ SNAPSHOT(TEMP) ! The user can examine the value ! of the TEMP variable !$OMP END PARALLEL END
関連情報
-qdbg コンパイラー・オプションの 詳細については、「XL Fortran ユーザーズ・ガイド」を参照してください。
目的
SOURCEFORM コンパイラー・ディレクティブは、ファイルの終わりに到達 するか、@PROCESS ディレクティブまたは別 の SOURCEFORM ディレクティブが異なるソース形式を指定するまで、 後続するすべての行を指定のソース形式で処理するように指示します。
構文
>>-SOURCEFORM--(--source--)------------------------------------>< |
規則
SOURCEFORM ディレクティブは、ファイルのどの位置にでも入れることができます。 インクルード・ファイルは、ソース形式のインクルード・ファイルとともにコンパイルされます。 SOURCEFORM ディレクティブがインクルード・ファイル内にある場合、インクルード・ファイルの処理が 完了すると、ソース形式は、組み込み先のファイルのソース形式に戻ります。
SOURCEFORM ディレクティブでは、ラベルを指定することはできません。
ヒント |
---|
既存のファイルを、インクルード・ファイルを含む Fortran 90 自由ソース形式に変更するには、次のように行います。
|
例
@PROCESS DIRECTIVE(CONVERT*) PROGRAM MAIN ! Main program not yet converted A=1; B=2 INCLUDE 'freeform.f' PRINT *, RESULT ! Reverts to fixed form END
ファイル freeform.f には以下のコードが含まれています。
!CONVERT* SOURCEFORM(FREE(F90)) RESULT = A + B
目的
STREAM_UNROLL ディレクティブはコンパイラーに対して、 ソフトウェア・プリフェッチとループ・アンロールを結合した機能を 反復カウントの大きな DO ループに適用することを指示します。 ストリーム・アンロール機能は POWER4(TM) 以上の プラットフォームでのみ使用可能で、複数のストリームを使用するように DO ループを最適化します。 STREAM_UNROLL は内部と外部の両方の DO ループに指定できます。 コンパイラーは、可能であればストリームの最適な番号を使用してストリーム・アンロールを 実行します。依存関係を持つループに STREAM_UNROLL を適用すると、 予期しない結果が生じます。
構文
>>---STREAM_UNROLL--+---------------------+-------------------->< '-(--unroll_factor--)-' |
規則
ループ・アンロールを使用可能にするには、次のいずれかのコンパイラー・オプションを指定する必要があります。
-qstrict オプションが有効である場合、ストリーム・アンロールは行われないことに注意してください。 -qhot オプションだけでストリーム・アンロールを使用可能にするには、-qnostrict も指定する必要があります。
ストリーム・アンロールを行う場合、STREAM_UNROLL ディレクティブは DO ループの 前になければなりません。
STREAM_UNROLL ディレクティブを複数回指定することはできません。 また、1 つの DO 構文で、このディレクティブを BLOCK_LOOP 、UNROLL、NOUNROLL、UNROLL_AND_FUSE、 または NOUNROLL_AND_FUSE ディレクティブと結合することはできません。
STREAM_UNROLL ディレクティブを DO WHILE ループ および無限 DO ループに指定することはできません。
例
以下に、パフォーマンスを向上できる STREAM_UNROLL の例を示します。
integer, dimension(1000) :: a, b, c integer i, m, n !IBM* stream_unroll(4) do i =1, n a(i) = b(i) + c(i) enddo end
unroll factor は、次のようにして、反復数を n から n/4 まで減らします。
m = n/4 do i =1, n/4 a(i) = b(i) + c(i) a(i+m) = b(i+m) + c(i+m) a(i+2*m) = b(i+2*m) + c(i+2*m) a(i+3*m) = b(i+3*m) + c(i+3*m) enddo
読み取り操作と保管操作の増加数は、 コンパイラーが決定したストリーム数に振り分けられ、 計算時間が短縮されてパフォーマンスが向上します。
関連情報
目的
SUBSCRIPTORDER ディレクティブは、配列の添え字を再配置します。 ディレクティブが宣言で配列次元の順序を変更するので、 この結果、新しい配列形状になります。 配列に対するすべての参照は、 新しい配列形状に一致させるために、それに応じて再配置されます。
慎重に使用すれば、SUBSCRIPTORDER ディレクティブは、 キャッシュ・ヒット数およびデータ・プリフェッチの量を増やすことによって、 パフォーマンスを向上させることができます。 パフォーマンスを最大限に上げる配置が見つかるまで、 このディレクティブを試さなければならない場合があります。 通常キャッシュを使用しないハードウェア・アーキテクチャー用であったコードを移植するときは、 特に SUBSCRIPTORDER が便利です。
PowerPC などの キャッシュを使用するハードウェア・アーキテクチャーでは、各データ・エレメントにアクセスする ために、データのキャッシュ・ライン全体がプロセッサーにロードされることがよくあります。 ストレージ配置の変更を使用して、連続してアクセスされるエレメントを隣接して保管することができます。 参照される各キャッシュ・ラインのエレメントのアクセスが増えるに従って、パフォーマンスが向上します。 さらに、連続してアクセスされる配列エレメントを隣接して保管すると、プロセッサーのプリフェッチ機能を 活用するために役立ちます。
構文
.-,--------------------. V | >>-SUBSCRIPTORDER--(----subscriptorder_array-+--)-------------->< |
subscriptorder_array の意味は次のとおりです。
.-,---------------------. V | >>-array_name--(----subscriptorder_number-+--)----------------->< |
規則
SUBSCRIPTORDER ディレクティブは、subscriptorder_array リスト内の配列に対するすべての宣言または 参照に先行する有効範囲単位で使用する必要があります。 ディレクティブはその有効範囲単位のみに適用され、少なくとも 1 つの配列を含む必要があります。 複数の有効範囲単位が 1 つの配列を共用する場合は、SUBSCRIPTORDER ディレクティブを、同一の 添え字配置で、適用できるそれぞれの有効範囲単位に適用する必要があります。 有効範囲単位間で配列を共用する方法の例には、COMMON ステートメント、USE ステートメント、 およびサブルーチン引き数があります。
subscriptorder_number リスト内の最小の添え字の番号は、1 にする必要があります。 最大番号は、対応する配列内の次元数と等しくなければなりません。 これら 2 つの限界の間にある各整数の数値 (限界の値を含む) は、再配置の前の添え字の番号を示し、リストに 正確に 1 度だけ含まれている必要があります。
有効範囲単位内の特定の配列に対し、SUBSCRIPTORDER ディレクティブを、複数回適用してはなりません。
配列の 1 つを SUBSCRIPTORDER ディレクティブで使用する場合、エレメント型プロシージャーに対する 実際の引き数として配列を渡すときには、配列形状の一致を維持する必要があります。 さらに、SHAPE、SIZE、LBOUND、および UBOUND 照会組み込みプロシージャーの 実引き数、および大部分の変形可能組み込みプロシージャーの実引き数も調整する必要があります。
入力データ・ファイルのデータ、および SUBSCRIPTORDER ディレクティブ内で使用する配列の 明示的初期化のデータは、手動で変更する必要があります。
さらに COLLAPSE ディレクティブも適用される配列上では、COLLAPSE ディレクティブは、 常に以前の subscriptorder 次元数を参照します。
想定サイズ配列の最後の次元を再配置してはなりません。
例
例 1: 次の例では、SUBSCRIPTORDER ディレクティブは明示的形状配列に適用され、 プログラム出力に影響を及ぼすことなく、配列のそれぞれの参照で添え字をスワップします。
!IBM* SUBSCRIPTORDER(A(2,1)) INTEGER COUNT/1/, A(3,2) DO J = 1, 3 DO K = 1, 2 ! Inefficient coding: innermost index is accessing rightmost ! dimension. The subscriptorder directive compensates by ! swapping the subscripts in the array's declaration and ! access statements. ! A(J,K) = COUNT PRINT*, J, K, A(J,K) COUNT = COUNT + 1 END DO END DO
上記のディレクティブがない場合は、配列の形状は (3,2) になり、 配列エレメントは、次の順序で保管されます。
A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2)
上記のディレクティブがある場合、配列の形状は (2,3) になり、 配列エレメントは、次の順序で保管されます。
A(1,1) A(2,1) A(1,2) A(2,2) A(1,3) A(2,3)
関連情報
COLLAPSE ディレクティブの詳細については、COLLAPSEを参照してください。
目的
UNROLL ディレクティブはコンパイラーに対して、 可能であればループ・アンロールを試みることを指示します。 ループ・アンロールは DO ループの本体を複製して、 ループを完了するために必要となる反復の回数を減らします。
-qunroll コンパイラー・オプションを指定して、 ファイル全体のループ・アンロールを制御できます。 特定の DO ループにディレクティブを指定すると、コンパイラー・オプションは 必ずオーバーライドされます。
構文
>>-+-UNROLL--+---------------------+-+------------------------->< | '-(--unroll_factor--)-' | '-NOUNROLL------------------------' |
規則
ループ・アンロールを使用可能にするには、次のいずれかのコンパイラー・オプションを指定する必要があります。
-qstrict オプションが有効である場合、ループのアンロールは行われないことに注意してください。 -qhot オプションだけでループのアンロールを使用可能にするには、-qnostrict も指定する必要があります。
ループ・アンロールを行う場合、UNROLL ディレクティブは DO ループの 前になければなりません。
UNROLL ディレクティブを複数回指定することはできません。 また、1 つの DO 構文で、このディレクティブを BLOCK_LOOP、NOUNROLL、STREAM_UNROLL、UNROLL_AND_FUSE、 または NOUNROLL_AND_FUSE ディレクティブと結合することはできません。
UNROLL ディレクティブを DO WHILE ループ および無限 DO ループに指定することはできません。
例
例 1: この例では、1 回の繰り返しで 2 回の繰り返し作業が 実行されるよう、ループ本体が複製可能であることをコンパイラーに 通知するために、UNROLL(2) ディレクティブが使用されています。 コンパイラーがループをアンロールすると、コンパイラーは 1000 回の繰り返しを 実行するのではなく、500 回だけ繰り返しを実行します。
!IBM* UNROLL(2) DO I = 1, 1000 A(I) = I END DO
コンパイラーが直前のループをアンロールすることを選択すると、 コンパイラーはそのループが本質的に以下と同じになるようにそのループを変換します。
DO I = 1, 1000, 2 A(I) = I A(I+1) = I + 1 END DO
例 2: 最初の DO ループでは、 UNROLL(3) が使用されています。 アンロールが実行されると、 コンパイラーは 1 回の繰り返しで 3 回の繰り返し作業が行われるように、 ループをアンロールします。 2 番目の DO ループでは、コンパイラーはパフォーマンスが 最大になるようにループをアンロールする方法を決定します。
PROGRAM GOODUNROLL INTEGER I, X(1000) REAL A, B, C, TEMP, Y(1000) !IBM* UNROLL(3) DO I = 1, 1000 X(I) = X(I) + 1 END DO !IBM* UNROLL DO I = 1, 1000 A = -I B = I + 1 C = I + 2 TEMP = SQRT(B*B - 4*A*C) Y(I) = (-B + TEMP) / (2*A) END DO END PROGRAM GOODUNROLL
関連情報
目的
UNROLL_AND_FUSE ディレクティブはコンパイラーに対して、 可能であればループ・アンロールとヒューズを試みることを指示します。 ループ・アンロールは、DO ループの複数の本体を 複製して、必要な反復を 1 つのアンロール・ループに結合します。 フューズ・ループを使用すると、ループ反復の必要数を最小化し、その上、 キャッシュ・ミスの回数を減らすことができます。 依存関係を持つループに UNROLL_AND_FUSE を適用すると、 予期しない結果が生じます。
構文
>>-+-UNROLL_AND_FUSE--+---------------------+-+---------------->< | '-(--unroll_factor--)-' | '-NOUNROLL_AND_FUSE------------------------' |
規則
ループ・アンロールを使用可能にするには、次のいずれかのコンパイラー・オプションを指定する必要があります。
-qstrict オプションが有効である場合、ループのアンロールは行われないことに注意してください。 -qhot オプションだけでループのアンロールを使用可能にするには、-qnostrict も指定する必要があります。
ループ・アンロールを行う場合、UNROLL_AND_FUSE ディレクティブは DO ループの 前になければなりません。
UNROLL_AND_FUSE ディレクティブを最も内側の DO ループに 指定することはできません。
UNROLL_AND_FUSE ディレクティブを複数回指定することはできません。 また、1 つの DO の構文で、このディレクティブを BLOCK_LOOP、NOUNROLL_AND_FUSE、NOUNROLL、UNROLL、 または STREAM_UNROLL ディレクティブと結合することはできません。
UNROLL_AND_FUSE ディレクティブを DO WHILE ループ および無限 DO ループに指定することはできません。
例
例 1: 次の例では、UNROLL_AND_FUSE ディレクティブが ループの本体を複製してフューズします。 これにより、配列 B のキャッシュ・ミスの数が減少します。
INTEGER, DIMENSION(1000, 1000) :: A, B, C !IBM* UNROLL_AND_FUSE(2) DO I = 1, 1000 DO J = 1, 1000 A(J,I) = B(I,J) * C(J,I) END DO END DO END
下の DO ループは、UNROLL_AND_FUSE ディレクティブを 適用した場合の、考えられる結果を示します。
DO I = 1, 1000, 2 DO J = 1, 1000 A(J,I) = B(I,J) * C(J,I) A(J,I+1) = B(I+1, J) * C(J, I+1) END DO END DO
例 2: 以下の例では、複数の UNROLL_AND_FUSE ディレクティブを 使用します。
INTEGER, DIMENSION(1000, 1000) :: A, B, C, D, H !IBM* UNROLL_AND_FUSE(4) DO I = 1, 1000 !IBM* UNROLL_AND_FUSE(2) DO J = 1, 1000 DO k = 1, 1000 A(J,I) = B(I,J) * C(J,I) + D(J,K)*H(I,K) END DO END DO END DO END
関連情報
+------------------------------End of IBM 拡張-------------------------------+