1 概要
NAG Fortranコンパイラ リリース 7.1 はメジャーアップデートです。
NAG Fortranコンパイラの以前のリリースからアップグレードするお客様は、 このリリースの新しいライセンスキーが必要になります。
Kusariライセンス管理の詳細については KLICENCE.txt
を参照してください。
2 リリースの概要
NAG Fortran コンパイラのリリース 7.1 は、以下を含む、Fortran 2008 のすべてをサポートしています。
- データポインタを返す関数への参照が、代入文の左側を含む多くの場面で変数として使用できます。
- その他、マイナーな機能追加が行われ、ポインタ指示先の初期化(これにより割付け可能な要素が再帰的もしくは相互に再帰的な型を持つことができる)や 手続ポインタを返す関数がが行えるようになりました。
このリリースには、以下を含む、Fortran 2018の機能が大幅に追加されました。
-
組込みの“collective”サブルーチン(
CO_SUM
他)の追加により、 Fortran 2018の共配列並列プログラミング機能をすべてサポートしました。 項目 - C言語の高度な相互運用性を部分的にサポートしました。 具体的には、assumed-rank引数、assumed-type引数、およびC記述子がサポートされます。
-
RANK
組み込み関数とSELECT_RANK
構文を用いて、 (Cではなく)Fortranで直接次元引継ぎ引数が利用できます。 -
いくつかのマイナーな機能追加が行われ、
省略可能な仮引数が組み込み配列関数(
SUM
など)のDIM
引数として使用できるようになりました。
OpenMPプログラムでも、未定義変数のチェックができるようになり、OpenMPプログラミングへの対応が改善されました。 また、新しいOpenMPのマイナーな機能も追加されています。
最後に、追加のエラーチェックが可能となり、バンドルされているツールでもいくつかの機能が追加されています。
3 互換性
3.1 リリース7.0との互換性
リリース7.1は、-C=callsオプションを指定してコンパイルされたファイルが、 手続ポインタ引数を持つ手続を含んでいる場合に再コンパイルが必要である点を除き、 Release 7.0と互換性があります。3.2 リリース6.2との互換性
MacOSでは、-abi=32 で利用可能であった32ビットABIモードは削除されました。 その結果、64ビットコンパイルのみがサポートされ、-abi=オプションは完全に削除されました。これ以外については共配列が使用される場合、 または-C=callsオプションを選択戻りを持つサブルーチンに対して用いた場合を除き、 リリース7.1とリリース6.2は完全に互換性があります。このようなプログラムはすべて再コンパイルする必要があります。
3.3 リリース6.1との互換性
ILEN
組み込み関数やHPF_LIBRARY
モジュールなど、
HPF(High Performance Fortran)の機能を使用するプログラムはサポートされなくなりました。
Linux x86-64で以前廃止予定機能であった-abi=64オプションは廃止されました。 このオプションは、64ビットポインターを持つが32ビットのオブジェクトサイズと添え字演算を備えるABIを提供していましたが、 これはリリース5.1以前との互換性のためにのみ存在していました。
HPFサポートと非推奨のオプションの削除を除き、NAG Fortranコンパイラのリリース7.1はリリース6.1と完全に互換性があります。
3.4 リリース6.0との互換性
HPFサポートと非推奨オプションの削除を除き、NAG Fortranコンパイラのリリース7.1はリリース6.0と互換性があります。 ただし、“パラメタ化構造型”の割付け配列を使用するプログラムは再コンパイルする必要があります (これはモジュール変数及び仮引数にのみ影響します)。3.5 リリース5.3.1、5.3および5.2との互換性
HPFサポートと非推奨のオプションの削除を除き、NAG Fortranコンパイラのリリース7.1はリリース5.3.1と完全に互換性があります。 またWindowsでは、名前がドル記号($)で始まるモジュールまたはプロシージャを再コンパイルする必要があることを除いて、 リリース5.3および5.2と完全に互換性があります。新しい“パラメタ化構造型”機能を使用するプログラムの場合、 動的型がパラメーター化された派生型である可能性のある多相性変数を割り当て、 割り当て解除、初期化、またはコピーするプログラムのすべての部分を リリース7.1でコンパイルすることが強く推奨されています。
3.6 リリース5.1との互換性
NAG Fortranコンパイラのリリース7.1は、次の点を除き、NAGWare f95 リリース5.1と互換性があります。- HPFの機能を使用するプログラムはサポートされていません。
-
CLASS
キーワードを使用する、または拡張される型を含むプログラムまたはライブラリは、 再コンパイルする必要があります。 - Linux x86-64(製品NPL6A51NA)上でリリース5.1でコンパイルされた64ビットプログラム、 およびライブラリはバイナリ互換ではないため、再コンパイルする必要があります。
4 Fortran 2008の新機能
-
割付け成分は型を前方参照できます。
例)Type t2 Type(t),Pointer :: p Type(t),Allocatable :: a End Type Type t Integer c End Type
割付け成分は再帰的な型、もしくは二つの型がお互いに再帰的であっても構いません。
例)Type t Integer v Type(t),Allocatable :: a End Type
これにより、割付け成分を用いてリストやツリーを構築できます。 割付けにはポインタ代入に類似したものがないため、 このようなデータ構造の構築や探索には通常、再帰的な手続呼び出しが必要です。このような再帰的なデータ構造がどんなに深くネストされても、 循環させることはできません。(これもポインタ代入がないため) いつものように、このような構造体の最上位オブジェクトの割付けを解除すると、 すべての割付けが再帰的に解除されます。
-
仮引数は、関数結果の型パラメタ(文字長など)を指定しない限り、
要素別副プログラムの宣言式に使用できます。
関数結果の型パラメタについては、
問合せが無指定についてでない場合にのみ、宣言問合せ(
LEN
など)で利用できます。例)
Elemental Subroutine s(x,n,y) Real,Intent(In) :: x Integer,Intent(In) :: n Real,Intent(Out) :: y Real temp(n) ...
上記コードで、仮引数N
を用いて局所配列TEMP
を宣言する事ができます。 -
ポインタおよびポインタ成分は、指示先を示すように初期化できます。
指示先はそのポインタに対して有効でなければなりません。(例:同じ型、次元数など)
主なケースは以下の通りです。
- 名前付きポインタ初期化
- データポインタの場合、指示先に
SAVE
属性が必要です。 (モジュールや主プログラム内の変数は暗黙のうちにこの属性を持ちます) 手続ポインタの場合、指示先はモジュール手続または外部手続でなければならず、 仮手続、内部手続、文関数であってはなりません。例)
Module m Real,Target :: x Real,Pointer :: p => x End Module Program test Use m p = 3 Print *,x ! Will print the value 3.0 End Program
- 成分の暗黙的初期値指定
- ポインタ成分は、指示先を指すように暗黙的初期化することができます。
指示先に関する要件は、名前付きポインタの初期化の場合と同じです。
例)
Module m Real,Target :: x Type t Real,Pointer :: p => x End Type End Module Program test Use m Type(t) y y%p = 3 Print *,x ! 値 3.0 を出力 End Program
- 構築子による成分の初期化
- 定数式の構築子は、任意のポインタ成分の指示先を指定することができます。
指示先に関する要件は、名前付きポインタの初期化の場合と同じです。
例)
Module m Real,Target :: x Type t Real,Pointer :: p End Type End Module Program test Use m Type(t) :: y = t(x) y%p = 3 Print *,x ! 値 3.0 を出力 End Program
-
ポインタを返す関数への参照は、多くの場面で変数として使用することができます。
特に、代入文の変数として、
INTENT(OUT)
やINTENT(INOUT)
の仮引数に対応する実引数として、 また結合名を変更するASSOCIATE
やSELECT TYPE
構文の選択子として使用することが可能です。例)
Module m Real,Target,Save :: table(100) = 0 Contains Function f(n) Integer,Intent(In) :: n Real,Pointer :: f f => table(Min(Max(1,n),Size(table))) End Function End Module
上記モジュールおよび以下のコードでは “-1.23E+02
” が出力されます。Program example Use m f(13) = -123 Print 1,f(13) 1 Format(ES10.3) End Program
注意すべきは、文関数定義の構文は、変数としてのポインタ関数参照の構文の一部と同じであり、 スコープ内でアクセス可能なポインタ値関数が存在するかどうかで、そのどちらであるかが決定されることです。 このため、状況によっては、混乱しやすいエラーメッセージとなる場合があります。
上述のモジュールで、
ASSOCIATE
構文の使い方を示すプログラムを以下に示します。Program assoc_eg Use m Associate(x=>f(3), y=>f(4)) x = 0.5 y = 3/x End Associate Print 1,table(3:4) ! " 5.00E-01 6.00E+00" を出力 1 Format(2ES10.2) End Program
最後に、引数渡しを使った例を示します。
Program argument_eg Use m Call set(f(7)) Print 1,table(7) ! "1.41421" を出力 1 Format(F7.5) Contains Subroutine set(x) Real,Intent(Out) :: x x = Sqrt(2.0) End Subroutine End Program
変数名の代わりにポインタ値関数への参照が使用できる他の場合には、以下のようなものがあります。
-
WRITE
文の内部ファイル指定子として使用する。 (関数は文字列または配列へのポインタを返さなければならない) -
READ
文の入力項目として使用する。 -
ALLOCATE
またはDEALLOCATE
文、またはEVENT WAIT
などの像制御文で、STAT=
またはERRMSG=
変数として使用する。 -
FORM TEAM
の像のチーム変数として使用する。
-
-
関数の結果は手続ポインタであっても構いません。
例)Module ppfun Private Abstract Interface Subroutine charsub(string) Character(*),Intent(In) :: string End Subroutine End Interface Public charsub,hello_goodbye Contains Subroutine hello(string) Character(*),Intent(In) :: string Print *,'Hello: ',string End Subroutine Subroutine bye(string) Character(*),Intent(In) :: string Print *,'Goodbye: ',string Stop End Subroutine Function hello_goodbye(flag) Logical,Intent(In) :: flag Procedure(hello),Pointer :: hello_goodbye If (flag) Then hello_goodbye => hello Else hello_goodbye => bye End If End Function End Module Program example Use ppfun Procedure(charsub),Pointer :: pp pp => hello_goodbye(.True.) Call pp('One') pp => hello_goodbye(.False.) Call pp('Two') End Program
モジュールppfun
の関数hello_goodbye
は手続へのポインタを返し、 そのポインタは手続ポインタに代入して起動する必要があり、 実行されると、この例では以下が出力されます。Hello: One Goodbye: Two
この機能の使用は、データ実体と手続の境界を曖昧にし、 コードメンテナンス時に混乱や誤解を招く可能性があるため、推奨されません。 この機能は、手続ポインタ成分で既に提供されている以上の機能を提供しません。
5 Fortran 2018の新機能
-
組込サブルーチン
CO_BROADCAST
、CO_MAX
、CO_MIN
、CO_REDUCE
、およびCO_SUM
は collective 演算を行います。 これらはCoarray並列のためのもので、明示的な同期をとることなく、現在のチーム内のすべての像にまたがる値を計算します。これらのサブルーチンは、いずれも省略可能な
STAT
とERRMSG
の引数を持ちます。 実行に成功すると、STAT
引数には値0が代入され、ERRMSG
引数は変更されないままとなります。 エラーが発生した場合、STAT
に正の値が代入され、ERRMSG
には説明のメッセージが代入されます。 この方法で捕捉できる可能性があるのは、STAT_FAILED_IMAGE
とSTAT_STOPPED_IMAGE
のエラーのみです。 完全な同期がとられているわけではないので(下記参照)、像によって異なるエラーが発生したり、 全くエラーが発生しなかったりすることがあります。 エラーが発生し、STAT
が存在しない場合、実行は終了されます。 なお、STAT
やERRMSG
の実引数が省略可能な仮引数である場合、 その引数はすべての像で存在するか、あるいはすべての像で存在しないか、のいずれかでなければなりません。これらのサブルーチンの1つへの参照 (
CALL
) は、像制御文であり、現在のセグメントを終了させず、同期も意味しません (ただし、計算中に部分的に同期が発生します)。 また、このような呼び出しは、像制御文が許可されている場合にのみ許されます。チーム内の各像は、チーム内の他の像と同じように、 集合サブルーチンの
CALL
文シーケンスを実行しなければなりません。 呼び出し時に像間で同期をとってはいけません。つまり呼び出しは順不同のセグメントからでなければなりません。すべての集合サブルーチンは第1引数 “
A
”を持ちます。 この引数はINTENT(INOUT)
であり、並列添字付き実体であってはいけません。 また、この引数は計算のためのデータを含み、 現在のチーム内のすべての像で同じ型、型パラメタ、形状を持たなければなりません。 仮引数が共配列の場合は、すべての像で同じ末端引数を持たなければなりません。SUBROUTINE CO_BROADCAST ( A, SOURCE_IMAGE [, STAT, ERRMSG ] )
A
: 任意の型の変数。並列添字付き実体であってはならず、 現在のチームのすべての像で同じ型、型パラメタ、および形状を持っている必要がある。 code{A}が共配列の仮引数の場合、各像で同じ末端引数を持つ必要がある。SOURCE_IMAGE
: 整数スカラ。1からNUM_IMAGES()
の範囲、現在のチーム内のすべての像で同じ値でなければならない。STAT
(optional) : 整数スカラ変数。並列添字付きであってはならない。ERRMSG
(optional) : 基本種別の文字スカラ変数。並列添字付きであってはならない。像
SOURCE_IMAGE
上の引数A
の値は、他のすべての像上の引数A
に代入される。SUBROUTINE CO_MAX ( A [, RESULT_IMAGE, STAT, ERRMSG ] )
A
: 整数型、実数型、もしくは文字型の変数。 並列添字付き実体であってはならず、 現在のチームのすべての像で同じ型、型パラメタ、および形状を持っている必要がある。 code{A}が共配列の仮引数の場合、各像で同じ末端引数を持つ必要がある。RESULT_IMAGE
(optional) : 整数スカラ。1からNUM_IMAGES()
の範囲。 この引数はすべての像で存在するか、あるいはすべての像で存在しないか、のいずれかでなければならない。 存在する場合は、現在のチームのすべての像で同じ値でなければならない。STAT
(optional) : 整数スカラ変数。並列添字付きであってはならない。ERRMSG
(optional) : 基本種別の文字スカラ変数。並列添字付きであってはならない。このサブルーチンは、
A
の最大値をすべての像にわたって計算する。A
が配列の場合、値は要素別に計算される。 code{RESULT_IMAGE}が存在する場合、結果はその像上の引数A
に代入され、 そうでない場合はすべての像上の引数A
に代入されます。SUBROUTINE CO_MIN ( A [, RESULT_IMAGE, STAT, ERRMSG ] )
A
: 整数型、実数型、もしくは文字型の変数。 並列添字付き実体であってはならず、 現在のチームのすべての像で同じ型、型パラメタ、および形状を持っている必要がある。 code{A}が共配列の仮引数の場合、各像で同じ末端引数を持つ必要がある。RESULT_IMAGE
(optional) : 整数スカラ。1からNUM_IMAGES()
の範囲。 この引数はすべての像で存在するか、あるいはすべての像で存在しないか、のいずれかでなければならない。 存在する場合は、現在のチームのすべての像で同じ値でなければならない。STAT
(optional) : 整数スカラ変数。並列添字付きであってはならない。ERRMSG
(optional) : 基本種別の文字スカラ変数。並列添字付きであってはならない。このサブルーチンは、すべての像にわたって
A
の最小値を計算する。A
が配列の場合は、値は要素別に計算される。 code{RESULT_IMAGE}が存在する場合、結果はその像上の引数A
に代入され、 そうでない場合はすべての像上の引数A
に代入される。SUBROUTINE CO_REDUCE ( A, OPERATION [, RESULT_IMAGE, STAT, ERRMSG ] )
A
: 任意の型の非多相変数。並列添字付き実体であってはならず、 現在のチームのすべての像で同じ型、型パラメタ、および形状を持っている必要がある。 code{A}が共配列の仮引数の場合、各像で同じ末端引数を持つ必要がある。OPERATION
: 引数を2つだけ持つ純粋関数。OPERATION
の仮引数は,非割付け、非省略可能、非ポインタ、非多相の仮変数でなければならず、 各引数と関数の結果はA
と同じ型と型パラメタを持つスカラでなければならない。RESULT_IMAGE
(optional) : 整数スカラ。1からNUM_IMAGES()
の範囲。 この引数はすべての像で存在するか、あるいはすべての像で存在しないか、のいずれかでなければならない。 存在する場合は、現在のチームのすべての像で同じ値でなければならない。STAT
(optional) : 整数スカラ変数。並列添字付きであってはならない。ERRMSG
(optional) : 基本種別の文字スカラ変数。並列添字付きであってはならない。このサブルーチンは、
A
をすべての像にわたって任意に集約する。A
が配列の場合は、値は要素別に計算される。 集約は、すべての像のA
に対応する値の集合から計算される。 これは反復処理であり、集合から2つの値を取り出し、OPERATION
関数を適用して1つの値に変換する。 このプロセスは値が一つになるまで継続され、その値が結果となる。RESULT_IMAGE
があれば、その像上の引数A
に結果が代入され、 なければすべての像上の引数A
に代入される。SUBROUTINE CO_SUM ( A [, RESULT_IMAGE, STAT, ERRMSG ] )
A
: 整数型、実数型、もしくは複素型の変数。 並列添字付き実体であってはならず、 現在のチームのすべての像で同じ型、型パラメタ、および形状を持っている必要がある。 code{A}が共配列の仮引数の場合、各像で同じ末端引数を持つ必要がある。RESULT_IMAGE
(optional) : 整数スカラ。1からNUM_IMAGES()
の範囲。 この引数はすべての像で存在するか、あるいはすべての像で存在しないか、のいずれかでなければならない。 存在する場合は、現在のチームのすべての像で同じ値でなければならない。STAT
(optional) : 整数スカラ変数。並列添字付きであってはならない。ERRMSG
(optional) : 基本種別の文字スカラ変数。並列添字付きであってはならない。このサブルーチンは、
A
のすべての像にわたる合計を計算する。A
が配列の場合、値は要素別に計算される。RESULT_IMAGE
があれば、その像上の引数A
に結果が代入され、 なければすべての像上の引数A
に代入される。 -
ALL
、ANY
、FINDLOC
、IALL
、IANY
、IPARITY
、MAXLOC
、MAXVAL
、MINLOC
、MINVAL
、NORM2
、PARITY
、PRODUCT
、SUM
に対するDIM
引数は、実行時に存在すれば、省略可能な仮引数にすることができる。
例)Subroutine sub(x,n) Real,Intent(In) :: x(:,:,:) Integer,Intent(In),Optional :: n If (Present(n)) Then Print *,Norm2(x,n) ! Rank two array result. Else Print *,Norm2(x) ! Scalar result. End If End Subroutine
-
SIZE=
指定子は、ADVANCE='NO'
のないREAD
文、 つまりADVANCE=
指定子のない、あるいはADVANCE='YES'
を明示した文に用いることができる。
例)Character(65536) buf Integer nc Read(*,'(A)',Size=nc) buf Print *,'The number of characters on that line was',nc
なお、SIZE=
は並び書式、変数群書式では許可されません。 これは、そのような書式の編集記述子は存在せず、したがってSIZE=
でカウントされる文字も存在しないからです。 -
特定の組込関数は-f2018オプションで廃止予定機能(Obsolescent)として報告されます。
例えば、
SQRT
のような、個別でもありかつ総称でもある関数の場合、 実引数として渡す、手続引用仕様宣言として使う、手続ポインタ割り当ての指示先とするなど、 廃止された使い方の場合のみ報告されます。例)
Program obsolete_cos_usage Real x Intrinsic cos Procedure(cos),Pointer :: pp ! Obsolescent x = 1.5 pp => cos ! Obsolescent Call other_procedure(cos) ! Obsolescent Print *,cos(x),pp(x) End Program Subroutine other_procedure(f) Real,External :: f Print *,f(1.5) End Subroutine
コメントで示された3行の場合のみ警告メッセージが表示されます。 -
次元数引継ぎ仮引数は、任意の次元数の実引数を受け入れ、実引数の次元数を引継ぎます。
この次元数はゼロであってもよく(つまり、実引数がスカラであってもよい)、
さらに、次元数引継ぎ仮引数は
ALLOCATABLE
またはPOINTER
属性を持つことができ、 したがって任意の次元数の割付け/ポインタ変数を受け入れることができます。書式は以下の通りです
Real,Dimension(..) :: a, b Integer :: c(..)
上記は、3つの変数(仮引数でなければならない)を次元数引継ぎとして宣言しています。次元数引継ぎのFortranでの利用は非常に限定的です。組込み照会関数が使用でき、
SELECT RANK
構文も利用できますが、それ以外は、他の次元数引継ぎ引数に対応する手続の実引数としてのみ出現することが可能です。次元数引継ぎの主な用途は高度なC相互運用性です。 次元数引継ぎ引数は“C descriptor”として参照渡しされます。 引数が何を意味するかはCルーチン次第です。 Cディスクリプタは、それを操作するためのいくつかのユーティリティ関数とともに、ソースファイル
ISO_Fortran_binding.h
で定義されています。これはコンパイラのライブラリディレクトリ(Linuxでは通常/usr/local/lib/NAG_Fortran
ですが、インストール時に変更可能です)に置かれています。このトピックは非常に複雑であり、リリースノートの範囲を超えています。 読者はFortran 2018標準、またはMetcalf、Reid、Cohenによる“Modern Fortran Explained”などの優れた教科書に注意を向ける必要があります。
とてもシンプルな例)
Program assumed_rank_example Real x(1,2),y(3,4,5,6,7) Call showrank(1.5) Call showrank(x) Call showrank(y) Contains Subroutine showrank(a) Real,Intent(In) :: a(..) Print *,'Rank is',Rank(a) End Subroutine End Program
このプログラムは以下を出力します。Rank is 0 Rank is 2 Rank is 5
-
SELECT RANK
構文はFortranでの次元数引継ぎ実体の使用を容易にし、以下の書式を持ちます。[ construct-name ] SELECT RANK ( [ assoc_name => ] assumed-rank-variable-name ) [ rank-stmt block ]... END SELECT [ construct-name ]
ここでrank-stmtは以下のいずれか一つです。RANK ( scalar-int-constant-expression ) [ construct-name ] RANK ( * ) [ construct-name ] RANK DEFAULT [ construct-name ]
ある特定のSELECT RANK
構文において、複数のRANK DEFAULT
文、 複数のRANK (*)
文、または同じ値の整数式を持つ複数のRANK (integer)
があってはなりません。 次元数引継ぎ変数がALLOCATABLE
またはPOINTER
属性を持つ場合、RANK (*)
文は許可されません。整数の定数式を持つ
RANK
文に続くblockは、 次元数引継ぎ変数がその次元数ランクを持つ非想定ランク実引数に結合され、 かつ大きさ引継ぎ配列でない場合に実行されます。 blockの中では、あたかもその次元数の形状引継ぎ配列であるかのように振る舞います。RANK (*)
に続くblockは、末端引数が大きさ引継ぎ配列である場合に実行されます。 blockの中では、境界 ‘(1:*)
’ で宣言されているかのように動作します。 異なる境界や順位が必要な場合は、シーケンス結合を使って別の手続に渡すことができます。RANK DEFAULT
文に続くblockは、他のブロックが選択されていない場合に実行されます。 そのblock内では、まだ次元数引継ぎ変数です。(つまり変化はない)以下にシンプルな
SELECT RANK
構文の例を示します。Program select_rank_example Integer :: a = 123, b(1,2) = Reshape( [ 10,20 ], [ 1,2 ] ), c(1,3,1) = 777, d(1,1,1,1,1) Call show(a) Call show(b) Call show(c) Call show(d) Contains Subroutine show(x) Integer x(..) Select Rank(x) Rank (0) Print 1,'scalar',x Rank (1) Print 1,'vector',x Rank (2) Print 1,'matrix',x Rank (3) Print 1,'3D array',x Rank Default Print *,'Rank',Rank(x),'not supported' End Select 1 Format(1x,a,*(1x,i0,:)) End Subroutine End Program
このプログラムは以下を出力します。scalar 123 matrix 10 20 3D array 777 777 777 Rank 5 not supported
-
TYPE(*)
型指定子を用いてスカラ、大きさ引継ぎ、次元数引継ぎの仮引数を宣言することができます。 このような引数は引継ぎ型と呼ばれ、対応する実引数は任意の型にすることができます。 また、ALLOCATABLE
、CODIMENSION
、INTENT (OUT)
、POINTER
、VALUE
属性を持っていてはなりません。引継ぎ型変数はFortranでの直接の使用が非常に限られています。
- 他の引継ぎ型仮引数に実引数として渡すことができる。
-
組込み関数
IS_CONTIGUOUS
、LBOUND
、PRESENT
、SHAPE
、SIZE
、UBOUND
の第1引数として現れることがある。 -
関数
C_LOC
(ISO_C_BINDING
組込みモジュール内)の引数として使用できる。
この機能は主にC言語プログラムとの相互運用に有効です。
TYPE(*)
の仮引数は、“void *
” として宣言された C の引数と相互運用されます。 C側ではスカラか大きさ引継ぎかの違いはありませんが、Fortran側では、仮引数がスカラなら実引数もスカラでなければならず、仮引数が配列なら実引数も配列でなければなりません。TYPE(*)
仮引数に直接実引数を渡せるので、C_LOC
関数は不要であり、 従って実引数のTARGET
属性も不要です。例)
Program type_star_example Interface Function checksum(scalar,size) Bind(C) Use Iso_C_Binding Type(*) scalar Integer(C_int),Value :: size Integer(C_int) checksum End Function End Interface Type myvec3 Double Precision v(3) End Type Type(myvec3) x Call Random_Number(x%v) Print *,checksum(x,Storage_Size(x)/8) End Program int checksum(void *a,int n) { int i; int res = 0; unsigned char *p = a; for (i=0; i<n; i++) res = 0x3fffffff&((res<<1) + p[i]); return res; }
-
BIND(C)
手続は、省略可能な引数を持つことができます。 そのような引数はVALUE
属性を持つことはできません。BIND(C)
手続の省略可能な引数が存在しない場合は、NULLポインタの引数を渡すことで示します。例)
Program optional_example Use Iso_C_Binding Interface Function f(a,b) Bind(C) Import Integer(C_int),Intent(In) :: a Integer(C_int),Intent(In),Optional :: b Integer(C_int) f End Function End Interface Integer(C_int) x,y x = f(3,14) y = f(23) Print *,x,y End Program int f(int *arg1,int *arg2) { int res = *arg1; if (arg2) res += *arg2; return res; }
f
の2番目の参照では省略可能な引数b
がないので、NULLポインタが渡されます。 出力結果は以下の通りとなります。17 23
-
組込み照会関数
RANK
は、引数の次元数を返します。 以下の書式を持ちます。RANK ( A )
A
: 任意の型のデータ実体Result : 基本種別のスカラ整数
結果は
A
の次元数となります。スカラであれば0、A
が1次元配列であれば1、というようになります。この関数は、
A
が次元数引継ぎ変数である場合を除き、定数式で使用することができます。 -
組込み関数
REDUCE
は、ユーザー定義の配列集約を実行します。 以下の書式を持ちます。REDUCE ( ARRAY, OPERATION [, MASK, IDENTITY, ORDERED ] ) もしくは REDUCE ( ARRAY, OPERATION DIM [, MASK, IDENTITY, ORDERED ] )
ARRAY
: 任意の型の配列OPERATION
: 2つの引数を持つ純粋関数で、各引数はARRAY
と同じ宣言型および型パラメタを持つスカラー、非割付け、非ポインタ、非多相、非省略可能な変数 一方の引数がASYNCHRONOUS
、TARGET
、VALUE
属性を持つ場合、 他方もその属性を持たなければならない。 結果はARRAY
と同じ型と型パラメタを持つ非多相のスカラ変数でなければならない。DIM
: 1からNの範囲スカラ整数(ここでNはARRAY
の次元数)MASK
: 論理型、スカラもしくはARRAY
と同じ形状の配列IDENTITY
:ARRAY
と同じ宣言型および型パラメタを持つスカラORDERED
: 論理型のスカラResult :
ARRAY
と同じ型及び型パラメタ結果は、
ARRAY
をユーザが提供するOPERATION
で集約したものとなります。DIM
がない場合、(マスクされた)ARRAY
全体がスカラ結果に集約されます。DIM
がある場合、その結果は次元数N-1であり、ARRAY
の次元の形状を持ちます。DIM
を除去したもので、結果の各要素は、その次元のマスクされた要素の集約版となります。ちょうど1つの要素が結果値に寄与している場合、その値はその要素と等しくなります。 つまり、
OPERATION
は複数の要素が現れたときのみ呼び出されます。どの要素も結果値に寄与しない場合、
IDENTITY
引数が存在しなければならず、その値はIDENTITY
と等しくなります。例)
Module triplet_m Type triplet Integer i,j,k End Type Contains Pure Type(triplet) Function tadd(a,b) Type(triplet),Intent(In) :: a,b tadd%i = a%i + b%i tadd%j = a%j + b%j tadd%k = a%k + b%k End Function End Module Program reduce_example Use triplet_m Type(triplet) a(2,3) a = Reshape( [ triplet(1,2,3),triplet(1,2,4), & triplet(2,2,5),triplet(2,2,6), & triplet(3,2,7),triplet(3,2,8) ], [ 2,3 ] ) Print 1, Reduce(a,tadd) Print 1, Reduce(a,tadd,1) Print 1, Reduce(a,tadd,a%i/=2) Print 1, Reduce(Array=a,Dim=2,Operation=tadd) Print 1, Reduce(a, Mask=a%i/=2, Dim=1, Operation=tadd, Identity=triplet(0,0,0)) 1 Format(1x,6('triplet(',I0,',',I0,',',I0,')',:,'; ')) End Program
This will produce the output:triplet(12,12,33) triplet(2,4,7); triplet(4,4,11); triplet(6,4,15) triplet(8,8,22) triplet(6,6,15); triplet(6,6,18) triplet(2,4,7); triplet(0,0,0); triplet(6,4,15)
6 追加のOpenMPサポート
-
-C=undefined オプションによる未定義変数検出がサポートされました。
例)Program bad Use omp_lib Real x,y(10) x = 3 !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(y) Do i=1,Size(y) y(omp_get_thread_num() + 1) = x * omp_get_thread_num() End Do !$OMP END PARALLEL DO Print *,y End Program
以下が出力されます。Runtime Error: bad.f90, line 7: Reference to undefined variable X Program terminated by fatal error
-
OpenMP 4.0の
CANCEL
とCANCELLATION POINT
指示文がサポートされ、さらにOMP_CANCELLATION
環境変数とOMP_GET_CANCELLATION
関数もサポートされました。 また、CANCEL
のIF
節にあるOpenMP 5.0のCANCEL:
キーワードもサポートされました。CANCEL
指示文は以下の書式を持ちます。!$OMP CANCEL construct-type [ [,] IF ( [ CANCEL: ] scalar-logical-expr ) ]
ここでconstruct-typeはPARALLEL
、DO
、SECTIONS
、TASKGROUP
のいずれか一つです。 指示文は、指定された型のOpenMP構文の中に密接にネストされている必要があります。 但しTASKGROUP
は例外です。TASKGROUP
はOpenMPのTASK
構文の中に密接にネストされている必要があります。SECTIONS
の場合、構文がNOWAIT
節を持っていてはなりません。DO
の場合、構成がNOWAIT
節やORDERED
節を持っていてはなりません。CANCEL
指示文を実行すると、IF
句があればそれを評価し、IF
句がないか、 もしくは評価値が真でキャンセルが有効であれば、構文はキャンセルされます。 キャンセルされた場合、実行中のスレッドは即座に構文の最後にジャンプします。CANCELLATION POINT
指示文は以下の書式を持ちます。!$OMP CANCELLATION POINT construct-type
ここでconstruct-typeは、CANCEL
指示文と同じです。CANCEL
に関して、CANCELLATION POINT
指示文は適切なOpenMP構文に密接にネストされている必要があります。 この構文は、CANCEL
指示文も持つべきです。これがない場合、CANCELLATION POINT
指示文による効果は(CPU時間の浪費以外に)何もありません。CANCELLATION POINT
指示文を実行すると、構文がキャンセルされた場合は構文の最後に制御が移行し、それ以外の場合は何も影響しません。CANCELLATION POINT
指示文以外に、CANCEL
指示文 (たとえそれがfalseに評価されるIF
節を持っていたとしても)、BARRIER
指示文、または暗黙のバリアー (NOWAIT
のないEND SINGLE
などが含まれる構文の終わり)にもキャンセルポイントが存在します。構文がキャンセルされた後、領域内で実行されるバリアはキャンセルされた指示文の内部に密接にネストされていなければなりません(つまり、構文から呼ばれる手続内ではない)、さもなければ(NAGコンパイラによる)実行時エラーとなるか、もしくは(キャンセルしたスレッドがバリアに到達しないため)無限ハングが発生します。
環境変数
OMP_CANCELLATION
の値が‘TRUE
’である場合、キャンセルが有効になります。 (大文字・小文字を区別しない)また、この変数の値が‘FALSE
’である場合は無効となります。 この変数が存在しない場合、設定はコンパイラ依存です。 NAG Fortranコンパイラの場合、デフォルトはFALSE
です。OMP_GET_CANCELLATION
関数の仕様は以下の通りです。LOGICAL FUNCTION OMP_GET_CANCELLATION() END FUNCTION
キャンセルが有効な場合は.TRUE.
、無効な場合は.FALSE.
を返します。以下に、キャンセルのシンプルな例を示します。
Program example Real a(20000,4),b(4) Logical ok Call Random_Number(a) a = a*10 Call normalise(a,b,ok) Print 1,ok,b If (Any(a>2)) Print *,'Cancellation occurred' Call Random_Number(a) a = a*10 a(:,2) = -a(:,2) Call normalise(a,b,ok) Print 1,ok,b 1 Format(1X,'Succeeded = ',L1,', vmax =',4F8.4) If (Any(a>2)) Print *,'Cancellation occurred' Contains Subroutine normalise(x,y,succeeded) Use omp_lib Real,Intent(InOut) :: x(:,:) Real,Intent(Out) :: y(Size(x,2)) Logical,Intent(Out) :: succeeded Real z Integer me,i succeeded = .True. !$OMP PARALLEL PRIVATE(me,i,z) SHARED(x,y) NUM_THREADS(Size(x,2)) z = 0 me = omp_get_thread_num() + 1 Do i=1,Size(x,1) If (x(i,me)>z) z = x(i,me) End Do y(me) = z !$OMP CANCEL PARALLEL, IF (z==0) z = 2.0/z Do i=1,Size(x,1) x(i,me) = x(i,me)*z If (Iand(i,4095)==0) Then ! Every 4096 elements, check to see if the whole thing was cancelled already. !$OMP CANCELLATION POINT PARALLEL End If End Do !$OMP END PARALLEL succeeded = All(y/=0) End Subroutine End Program
出力は例えば以下のようになります。
Succeeded = T, vmax = 9.9993 9.9997 9.9998 9.9974 Succeeded = F, vmax = 9.9999 0.0000 9.9996 9.9998 Cancellation occurred
-
OpenMP 5.1の
MASKED
構文がサポートされました。 以下の形式を持ちます。!$OMP MASKED [ FILTER( スカラ整数式 ) ] 構造化ブロック !$OMP END MASKED
スレッドが構造化ブロックを実行するのは、スカラ整数式がスレッド番号と等しいと評価される場合のみです。 スレッド番号は0から始まり、PARALLEL
領域のプライマリスレッドの番号です。FILTER
節が存在しない場合、FILTER(0)
が存在するかのように振る舞います。つまり、プライマリスレッドのみが構造化ブロックを実行することになります。これは以下と完全に等価です。
IF (omp_get_thread_num()==スカラ整数式) THEN 構造化ブロック END IF
整数式は各スレッドで同じ値を持つ必要はなく、 その場合は複数のスレッドが同時にマスク領域を実行できることに注意して下さい。 この構成によって暗示されるロックまたは同期はありません。 つまり、スレッドにローカルではない変数が更新された場合、 プログラマが明示的に必要なロックを挿入する必要があります。
7 追加のエラー診断
-
ALLOCATE
文またはDEALLOCATE
文で、同じ変数が複数回出現した場合、 エラーとして検出されるようになりました。 - 型結合手続のオーバーライドとグローバルな整合性の診断で、仮引数の形状の違いを報告するようになりました。
-
SYSTEM_CLOCK
への8ビットまたは16ビットの整数引数は、値の受け取りには小さすぎるため、 エラーとして検出されるようになりました。 -
SYSTEM_CLOCK
の引数の不一致で警告を出すようになりました。- 引数が無い場合
- 整数引数が異なる種別である場合(Fortran 202xでは無効となるので)
- 整数引数と実数引数が混同された場合
- 整数引数がFortran 202xで推奨される64ビット整数でない場合
-
変数が利用者定義入出力によって処理されない場合、割付け、ポインタ、またはアクセスできない成分の要素を持つ変数で
NAMELIST
を使用するとエラーが発生します。 -
定数文字列の書式指定で、閉じる括弧の後に非空白文字がある場合、警告が発生します。
例)Print '(1X,I0) whatever',13
上記は以下のような警告を発します。Questionable: file.f90, line 2: Extraneous nonblank characters "whatever" after right parenthesis in character string format specification
-
CONTINUE
文は何の効果も持ちませんが、文番号があれば分岐先の文になったり、DO
ループの終わりになったりします。 しかし、文番号のないCONTINUE
文は、何ら役に立ちません。 このような場合、Note
レベルの警告が発せられます。CONTINUE
文がDO
ループの中にある場合、 CプログラマはこれがCYCLE
文の効果を持つと考えるかもしれないので、Questionable
に昇格されます。(Cではそうなっている)
例)Program continues Continue Do i=1,10 Print *,i**2 Continue End Do End Program
上記は以下の警告を発します。Note: file.f90, line 2: CONTINUE statement with no label Questionable: file.f90, line 5: CONTINUE statement with no label inside DO loop - did you mean CYCLE?
-
パラメタ化された構造型の共配列を割り付ける場合、異なる像で長さ型パラメタの値が異なる場合、
実行時エラーとして検出されるようになりました。
例)Allocate(w[*],Mold=z)
ここでZ
は別の像で異なる型パラメタ値を持つ仮引数を示しますが、この場合以下のような実行時エラーが発生します。Runtime Error: pco068.f90, line 17: Type parameter K1 in coarray allocation has value 1 on image one but 13 on image 2
-
空の
SELECT CASE
およびSELECT TYPE
構文は、選択子の評価以外には何も行われないため、 Questionable として報告されます。例えば
sub.f90
が以下を含む場合、Subroutine sub(x,n) Class(*) x Integer n Select Case (n) End Select Select Type (x) End Select End Subroutine
以下のような警告が発せられます。Questionable: sub.f90, line 4: Empty SELECT CASE construct Questionable: sub.f90, line 6: Empty SELECT TYPE construct
また、最適化(-Oオプション)が使用されている場合、選択子の評価が行われない場合があります。
-
-C=intovfオプションは、
SHAPE
とSIZE
組込み関数での整数オーバーフローを検出するようになりました。
例)Program shape_overflow_example Real a(1,123456,3) Call sub(a) Contains Subroutine sub(x) Use Iso_Fortran_Env Real,Intent(In) :: x(:,:,:) Integer(int16) sh(3) sh = Shape(x,int16) Print *,sh End Subroutine End Program
上記が-C=intovfを付けないでコンパイルされた場合、以下のようなナンセンスな結果となりますが1 -7616 3
-C=intovfを付けてコンパイルした場合には、以下のような実行時エラーが発生します。Runtime Error: shape_overflow_example.f90, line 9: INTEGER(int16) overflow for intrinsic SHAPE, true result value is 123456
-
-C=callsオプションは、手続ポインタの仮引数を、データポインタを返す関数と、
手続を返す関数(手続呼び出しのどのレベルでも)とで異なるものとして扱うようになりました。
これらのエラーは、手続が不正確な
引用仕様宣言
で呼び出された場合にのみ発生します。例)
Subroutine sub(f,x) Interface Function f(y) Real,Pointer :: f End Function End Interface Real,Intent(In) :: x Real,Pointer :: p p => f(x) Print *,Associated(p) End Subroutine
上記手続が以下のような不正確な引用仕様宣言で呼び出された場合Program bad Interface Subroutine sub(f,x) Real,External,Pointer :: f Real,Intent(In) :: x End Subroutine End Interface Real,External,Pointer :: pp Intrinsic sqrt pp => sqrt Call sub(pp,1.5) End Program
-C=callsオプション (さらにトレースバックを得るには-gline) を指定すると、 以下のような実行時エラーメッセージが出力されます。(指定しない場合はセグメンテーションフォルトとなります)Runtime Error: sub.f90, line 1: Incorrect interface block for SUB - Dummy argument F (number 1) is not a procedure pointer Program terminated by fatal error sub.f90, line 1: Error occurred in SUB bad.f90, line 11: Called by BAD
8 その他の追加機能
-
整形ツール(polish)のオプション-idcase=と-kwcase=に、
新たな選択肢が加わりました。squote{Camel_Case}です。
これは‘Capitalised’と異なり、最初の文字だけではなくアンダースコアの後の文字も大文字になります。
-kwcase=Camel_Case の場合、影響を受けるキーワードは
Non_Intrinsic
、Non_Overridable
、Non_Recursive
、及びOpenMPキーワードNum_Threads
です。 なお、選択肢の指定時に大文字と小文字は区別されず、Camel_Caseの場合(‘cam’と省略できる)を除いて、最初の一文字のみにまで省略する事も可能です。 -
ソース整形ツールのオプション-idcase=に新たな選択肢squote{Asis}が加わりました。
これは、ユーザー定義演算子(固有演算子は含まない)を含むすべての識別子の大文字と小文字を、
入力に現れたままの状態で保持するものです。
例えば、入力が大文字小文字の整合性が取れていない状態の“
eX = Ex + 1
”であった場合、 出力はそのまま全く同じ形のものとなります。 このオプションは、拡張整形ツールや他のツールでは使用できません。 -
拡張ソース整形ツールオプション -case: は、
名前の種類によって異なる大文字・小文字の設定を可能にします。
コロンの後には、“kind=case”のカンマ区切りリストが続きます。
ここでcaseは、ケース指定 (
UPPERCASE
、lowercase
、Capitalised
、Camel_Case
)で、 kindは以下に示すカテゴリーのうちの1つになります。comp
要素 constr
構文名 intr
組込み手続 param
パラメタ proc
手続 tbp
型結合手続 tparam
構造型パラメタ type
構造型 var
変数 例えば-case:var=lower,proc=uは変数に小文字を、手続に大文字を指定します。 特定の種類の名前に対する設定がない場合、適切なカテゴリにフォールバックします。 code{param}、
type
、comp
、tparam
、proc
はすべてvar
に、intr
はproc
に、tbp
はcomp
かproc
にフォールバックされます。 ルールやフォールバックルールがない場合は、 -idcase=オプション設定(もしくはデフォルト)が使用されます。 -
拡張ソース整形ツールオプション-casex:は、大文字小文字の規則の例外を指定します。
コロンの後に、任意の大文字・小文字指定を適用する例外文字列をカンマで区切ったリストを記述します。
例えば、-casex:MaxVal,XYz は、
maxval
やxyz
と同等の名前が出現するたびに、 それぞれを、MaxVal
やXYz
とします。 - -quietオプションは、コンパイラ(またはツール)のバナーメッセージと、最後の要約行を抑止します。 つまり診断メッセージのみが出力されるようになります。
-
Extensionメッセージは、それがどのような種類の拡張であるかの情報を提供するようになりました。
追加の情報は、その機能を追加したFortran標準の版 (例: “
Extension(F2018)
”) か、NAGの拡張か (“Extension(NAG)
”)か、標準機能に取って代わられた FORTRAN77 などの古い拡張か (“Non-standard(Obsolete)
”) のいずれかであることを示します。 - Informationalメッセージは3つのレベルに分けられました。 Note(最高)、Info、Remark(最低)です。 デフォルトではNoteメッセージは出力されるようになっていますが、-w=noteオプションでこれを抑制することもできます。 -infoオプションでInfoとRemarkの両方のメッセージを表示させることができます。