declare ディレクティブは、 Fortran サブルーチン、関数、モジュール(MODULE)の宣言部、または、C/C++の変数宣言の直後に指定する。これは、関数、サブルーチン、プログラムの暗黙のデータ領域とされる場所で、変数あるいは配列がデバイスメモリ上にアロケートされることを指示するために使用する。そして、暗黙のデータ領域の開始するポイントにおいて当該データがホストからデバイスへのデータコピーを行うかどうか、あるいは、暗黙のデータ領域の終了ポイントでデバイスからホストへデータをコピーするかどうか等の挙動も指定することができる。このディレクティブは、変数あるいは配列の visible device copy (コンパイラがコンパイル段階でコピー挙動が明示的に分かること)の生成を行う。
【Syntax】 C and C++ の declare ディレクティブ #pragma acc declare clause-list new-line Fortran の declare ディレクティブ !$acc declare clause-list Clause(節)は、次のものが指定できる copy( var-list ) copyin( var-list ) copyout( var-list ) create( var-list ) present( var-list ) present_or_copy( var-list ) present_or_copyin( var-list ) present_or_copyout( var-list ) present_or_create( var-list ) deviceptr( var-list ) device_resident( var-list ) link( var-list ) [OpenACC 2.0]
該当する領域は、当ディレクティブが現れている関数、サブルーチン、プログラムに関連した暗黙のデータ領域に対してとなる。 もし、このディレクティブが Fortran Module サブプログラムの宣言部、あるいは、C/C++ のグローバルなスコープエリア内に指定されると、その対応する領域はプログラム全体が暗黙のデータ領域とみなされる。それ以外、 当該 clause (節) は、これら clause を使ってプロシジャー本体に対して適用する「明示的な」data 構文と全く同じように振る舞う。
declareディレクティブの制限事項
複合 Parallel loop と kernels loop ディレクティブは、これに続くネストループに対して parallel あるいは kernels 構文の内部で loop ディレクティブを指定している状態と同じ機能を提供する。すなわち、明示的に loop ディレクティブを含んだ parallel あるいは kernels ディレクティブを指定していることと同じ意味を成す。この Parallel loop ディレクティブで利用できる clause は、parallel あるいは loop ディレクティブで許されているものと同じとなる。同様に kernels loop ディレクティブで利用できる clasue は、kernels あるいは loop ディレクティブで許されているものと同じとなる。このディレクティブは、これに続く直後のループに対して機能する。このディレクティブの使用例は、8章の姫野ベンチマークのプログラムにあるので、参照して欲しい。
【Syntax】 C and C++ の parallel loop ディレクティブ #pragma acc parallel loop [clause-list] new-line for loop Fortran の parallel loop ディレクティブ !$acc parallel loop [clause-list] do loop !$acc end parallel loop C and C++ の kernelsl loop ディレクティブ #pragma acc kernels loop [clause-list] new-line for loop Fortran の kernels loop ディレクティブ !$acc kernels loop [clause-list] do loop !$acc end kernels loop
制限事項
update ディレクティブは、アクセラレータのライフタイムの間に、デバイス・メモリ内の変数、配列に対応するローカル(ホスト)側変数、配列の一部あるいは全部の値を更新する機能、あるいは、ローカル(ホスト)側のメモリ内の変数、配列に対応するデバイス上の変数、配列の一部あるいは全部の値を更新するための機能を提供する。これは、「実行文」として機能するため、ディレクティブを挿入した箇所で、その機能が実行される。update ディレクティブを使用した例を第12章の「OpenACC Fortran と CUDA library (cufft)」に示したので参照のこと。
【Syntax】 C and C++ の update ディレクティブ #pragma acc update [clause-list] new-line Fortranの update ディレクティブ !$acc update [clause-list] Clause(節)は、次のものが指定できる async [( int-expr )] wait [( int-expr-list )] device_type( device-type-list ) if( condition ) self( var-list ) host( var-list ) device( var-list )
update ディレクティブの clause の var-list 引数には、コンマで区切って変数、配列、サブ配列を指定する。同じ配列の中のサブ配列を複数指定できる。すなわち、同じディレクティブの上でこれらは同じ clause 内、もしくは異なる clause の var-list の中に現れてもよい。update の clause の機能として、update self とするとアクセラレータ・デバイスからローカル(ホスト)・メモリへのコピーを行い、一方、update device とするとローカル・メモリからデバイス・メモリへのコピーを行う。その更新は、ディレクティブ上に指定した順番で行われる。このディレクティブを使用するには、少なくとも一つの self、host あるいは device clause を指定する必要がある。
self clause は var-list 内に指定された変数、配列、サブ配列が、アクセラレータ上のデバイスメモリからローカルメモリへコピーすることを指示するものである(non-shared メモリ型のアクセラレータ構成の場合)。もし、アクセラレータ上で当該スレッドがそれぞれ同じメモリを共有している場合、このアクションは実行されない。なお、「ローカルメモリ」の定義に関しては、7章を参照いただきたい。
host は、self と同義語である。これは、OpenACC 1.0 において使用されていた clause である。OpenACC 1.0 では、デバイスメモリからホストメモリへデータコピーを行うための指定方法である。
device clause は var-list 内に指定された変数、配列、サブ配列が、ローカルメモリからアクセラレータ上のデバイスメモリへコピーすることを指示するものである(non-shared メモリ型のアクセラレータの場合)。もし、アクセラレータ上で当該スレッドとそれぞれ同じメモリを共有している場合、このアクションは実行されない。
if clause はオプションである。この if clause が指定されていない場合、コンパイラは、アップデートを実行するコード生成する。if clause を指定されている場合は、条件付きでアップデートを行うコードを生成する。この条件の評価法は、C/C++ の場合はノンゼロで Fortran の場合は .true. の時のみ、更新が実行される。
6 章を参照されたし。あるいは、OpenACC 2.0 の仕様書を確認してください。
制限事項
OpenACC 2.0 の仕様書 2.14 Asynchronous Behavior を確認のこと。
7 章を参照のこと。あるいは、OpenACC 2.0 の仕様書 2.6.4 Asynchronous Behavior を確認のこと。
7 章を参照のこと。あるいは、OpenACC 2.0 の仕様書 2.6.4 Enter Data and Exit Data Directives を確認のこと。