「Fortranはすべての生物よりも生きている」または「祖父の努力の新機能」







ご存知のように、新しいIntel Parallel Studio XE 2016が最近リリースされました。予想どおり、Fortranコンパイラを含むすべてのツールの新しいバージョンがリリースされました。 彼はまだ「喫煙室」であり、活発に開発されていますが、需要が高く、特にHPCおよび学術環境で多くの開発者が使用しています。 新しいバージョンは、いつものように、これらの開発者の生活を少し楽にし、新しい標準をサポートし、より多くの機会を与えます。 バージョン16.0で登場したものを見てみましょう。



F2008のサブモジュール(サブモジュール)



Fortran 2008規格のサブモジュール(サブモジュール)のサポートは長い間待たれており、それらは言語の最大の機能であり、最後のリリースまでサポートされていません。 現在では、世界で2番目のコンパイラにのみ実装されています。 最初は誰ですか? Fortran 2008を完全にサポートするコンパイラがあります-これはCrayです。



では、なぜサブモジュールは待機したのですか? 次に、良い例を示します。 したがって、次のコードがあります。

module bigmodcontains subroutine sub1 …<implementation of sub1> function func2 …<implementation of func2> subroutine sub47 …<implementation of sub47> … end module bigmod
      
      





ご覧のとおり、多くの異なる機能がある大きなモジュールがあります。 このモジュールは、 USEステートメントを使用して他のファイルで積極的に使用されます。

 ! Source source1.f90 use bigmod … all sub1 ! Source source2.f90 use bigmod … x = func2(…) ! Source source47.f90 use bigmod … call sub47
      
      





submodのようにbigmodモジュールの一部の関数のコードを変更したい場合(これが起こる場合があります)、モジュール自体と、それが使用されているすべてのファイルを再アセンブルする必要があります。 さらに、これは、関数インターフェースが変更されていなくても発生し、さらに、変更した関数自体がコード内でまったく呼び出されず、 USEのみである場合でも発生します。 その結果、大規模なアプリケーションでは、必ずしも必要ではない一連の再コンパイルが行われます。 これを回避し、必要なものだけを再構築することは素晴らしいことです。 この問題の解決策はサブモジュールです。



主なアイデアは、モジュールから関数の実装を削除することです。 これはインターフェイスを使用して行われます:

 module bigmod … interface module subroutine sub1 … module function func2 … module subroutine sub47 … end interface end module bigmod
      
      





その後、別のファイルにbigmod_submoduleサブモジュールと関数の実装が作成されます:

 submodule (bigmod) bigmod_submod contains module subroutine sub1 … <implementation of sub1> module function func2 … <implementation of func2> module subroutine sub3 … <implementation of sub3> end submodule bigmod_submod
      
      





この場合、関数を実装するときにmoduleキーワードを使用する必要があり、サブモジュール内で宣言するすべてのものはそこでのみ表示されます。 これで、サブモジュールの変更は、関数のインターフェースを変更するまで、すべての再コンパイルにつながりません。 最初に親モジュールをコンパイルしてから、サブモジュールに移動する必要があります。



相互運用性CとFortran



Fortran標準化委員会は引き続きC言語との友好関係を維持しているため、最新バージョンではF29標準の一部となるTS29113FortranとCのさらなる相互運用性 )技術仕様の機会を紹介しています。 一般に、技術仕様という用語は、標準で受け入れられるためにまだ完全には完了していない何らかの言語機能がある場合に表示されますが、さまざまなコンパイラメーカーが実装を開始するために大きな需要があります。 ちなみに、彼らはTR(テクニカルレポート)と呼ばれる前に。 通常、このような仕様が委員会によって承認されると、変更を加えずに次の標準に採用されるため、サポートを既に実装しているコンパイラーには厄介な状況はありません。



この仕様自体の外観は主にMPI3のニーズによって動機づけられます。 特に、CとFortran間の相互作用を2つの主な方向に拡張できます。





これらのタスクは、新しいキーワードを使用して実装されています。 そのため、想定されるタイプ(想定されるタイプ) TYPE(*) 、および配列の次元(想定されるランク) DIMENSION(..)が表示されます。 さらに、C記述子があります。 一般に、CとFortranのシームレスな共存の問題に直面した場合、Fortran2003標準のISO_C_BINDINGモジュールの機能を確実に理解できます(私はすでにそれらについてここに書いています )。



きれいですか?



同じF2008標準では、関数を不純なelementalとして宣言する新しい機能があります。



この機能の本質を理解するためには、最初にF2003標準に登場する要素的で純粋な機能を理解する必要があります。



純粋な関数の前を指して、関数はそれ自体の外では何も変更できず、常に同じ入力パラメーターで同じ結果を返すことをコンパイラーに伝えます。



 pure function calculate (x)
      
      





これにより、 すべての構成に対して並列で純粋な関数を使用できます。



すべての引数について、 intent(in)属性を明示的に指定する必要があります。これは入力パラメーターにすぎず、変更しないことを意味しますが、関数自体ではI / O操作の実行、 STOP演算子の実行、静的変数の使用( save属性を使用)は禁止されています。 純関数の例: sin(x)length(s)など。



不純関数とは、引数に関係なく、ローカル変数で動作しない関数、または異なる結果を与える関数です。 純粋な関数内でrandom()を使用することは禁止されていますが、不純であるとしましょう。



それでは、要素関数に移りましょう。



 elemental subroutine swap(a, b)
      
      





これらはスカラー引数で宣言されますが、実際の引数として配列を使用して呼び出すことができます。 この場合、コンパイラーはループを作成してその中の関数を呼び出し、配列を埋めます。 デフォルトでは、要素関数はすべて純粋です。 このように、不純な要素関数はまだ基本的ですが、多少の安心感があります。 特に、I / O操作の実行、 ランダム()静的変数の使用が許可されています。



オプティマイザは、この関数が何かを「外部」に変更できるかどうかを認識しないため、 不純の使用はベクトル化に影響する可能性があることに注意してください。



Openmp 4.1

「ポジティブ」コンパイラーに関する投稿で 、OpenMP 4.1のサポートの拡大に​​ついて書きました。 もちろん、Fortranは、C / C ++コンパイラのように、TARGET NOWAITおよびTARGET DEPENDだけでなく、新しいTARGET ENTER DATAおよびTARGET EXIT DATAディレクティブもサポートするようになりました。



Ompのsimdディレクティブ

以前はタスクと並行したタスクでのみ使用されていたomporderedディレクティブを使用して、並行して実行され、 順序付きブロックに到達するスレッドを、シリアルバージョンとまったく同じ順序で順番に実行することができます:

 !$omp ordered [simd] structured code block !$omp end ordered
      
      





これにより、スレッド間に一種の依存関係が作成されます。 これがどのように機能するかを示す簡単な例。 この場合、インデックスは昇順で連続して印刷されます。

 !$omp do ordered schedule(dynamic) do i=lb,ub,st call work(i) end do ... subroutine work(k) !$omp ordered write(*,*) k !$omp end ordered
      
      





ところで、これは以前は動的レイアウトでのみ機能していました。 現在、この設計は同じように機能しますが、SIMDサイクルを操作できるsimdオプション(デフォルトではthreadsオプションがあります)を指定する機能も追加されました。



ブロックサイクル

O3最適化レベルが有効になっているときに機能する新しいディレクティブを使用すると、キャッシュメモリをより適切に処理するために、スプリットループで最適化を制御できます。

 !DIR$ BLOCK_LOOP [clause[[,] clause]...] !DIR$ NOBLOCK_LOOP
      
      







初期化されていない変数をキャッチする

コンパイラの15番目のバージョンでは、 -initオプションが登場しました 。これにより、実行時に初期化されていない変数へのアクセスを定義できますが、静的変数を操作するためだけに実装されました。 現在では、自動( 割り当て済み )( 割り当て可能な )配列およびポインターで使用できます。

簡単な例:

 4 real, allocatable, dimension(:) :: A 5 6 ALLOCATE(A(N)) 7 8 do i = 1, N 9 Total = Total + A(I) 10 enddo
      
      





すべての変数がシグナルNaNで初期化される-init = arrays、snan switchを使用してこのケースを収集すると、ランタイムエラーが発生します。

 $ ifort -init=arrays,snan -g -traceback sample.F90 -o sample.exe $ sample.exe forrtl: error (182): floating invalid - possible uninitialized real/complex variable. Image PC Routine Line Source ... sample.exe 0000000000402E12 MAIN__ 9 sample.F90 ... Aborted (core dumped)
      
      





初期化されていない変数と結果のインシデントに基づいた空想的な結果を避けるために、科学者がこのオプションに細心の注意を払うことを願っています。



「降伏のために」

さらに、開発者がより簡単に生活できるように、いくつかのマイナーな改良点もあります。 そのため、たとえば、新しいオプション-fpp-nameが登場しました 。これにより、任意のプリプロセッサを指定できます。 または、非同期通信用の新しい属性非同期 。 通常どおり、コンパイラを改善しようとする多くの改善点があります。



ちなみに、VS 2010 Shellの特別なバージョンは、Fortran用のインテルコンパイラーと共に長い間提供されてきました。 いくつかの制限があります(たとえば、C / C ++のサポートはまったくありません)が、Windowsの開発者にとっては非常に便利です。IDEにお金を払う必要はありません(VS Shellに追加のキャッシュインジェクションは必要ありません)。 そのため、VSのバージョンは2013に更新され、Fortranコンパイラパッケージにのみ付属しています。



All Articles