非同期データ転送を開始するか、同期データ転送を開始して完了します。 このプラグマは、インテル® MIC アーキテクチャーにのみ適用されます。
#pragma offload_transfer specifier[specifier...] |
target ( target-name [ :target-number ])
if-specifier
signal ( tag )
wait ( tag[, tag, ...] )
mandatory
offload-parameter [, offload-parameter, …]
ターゲットを表す識別子。 ターゲット名 mic のみ利用可能です。
値が次のように解釈される整数式。
この引数を指定しない場合、ランタイムシステムがコードを実行するコプロセッサーまたは CPU を選択します。複数のコプロセッサーが利用可能な場合は、特定のコプロセッサーを選択します。
0 以上の値は、特定のコプロセッサーでの実行を指定します。 特定のコプロセッサーは次のように指定します。
coprocessor=target-number % number_of_coprocs
オフロードプログラムの実行に必要な正しいターゲット・ハードウェアがシステムで利用できない場合、プログラムは実行に失敗してエラーメッセージを出力します。
2 または 6 を指定すると、ランタイムシステムはコプロセッサー 2 でコードを実行します (2 % 4 と 6 % 4 はどちらも 2 になるため)。
1000 を指定すると、ランタイムシステムはコプロセッサー 0 でコードを実行します (1000 % 4 = 0 になるため)。
ブーリアン式。
式が TRUE と評価されると、プラグマで指定されたデータ転送が行われます。指定したターゲット・コプロセッサーがシステムにない、またはその時点で完全にロードされていて利用できない場合、操作は行われません。
式が FALSE と評価されると、操作は行われません。ほかのオフロード節には影響しません。
tag 式は、ベースライン言語のアドレス式です。
signal とともに使用された場合、非同期データ転送のハンドルとなります。
wait とともに使用された場合、tag 式は signal 節の式と同じ値を使用した、開始した非同期処理のハンドルとなります 処理は、非同期演算または非同期データ転送です。
次のいずれかです。
in ( variable-ref [, variable-ref…] [ modifier[ modifier… ] ] )
out ( variable-ref [, variable-ref…] [ modifier[ modifier… ] ] )
nocopy ( variable-ref [, variable-ref…] [ modifier[ modifier… ] ] )
ヘテロジニアス環境でプログラムを実行すると、プログラム変数は CPU とターゲット間でコピーされます。offload-parameter は、変数がコピーされる方向 (ポインターの場合はコピーされるデータの量) を指定します。
| in | 変数は CPU からコプロセッサーへコピーされます。 |
| out | 変数はコプロセッサーから CPU へコピーされます。 |
| nocopy | コプロセッサー上で変数用にメモリーが割り当てられます。 |
in または outelement-count-expr 式 (後述の modifier の説明を参照) は、式が記述される文または節の前で評価されます。
宣言からサイズが分かる配列変数は全体でコピーされます。 配列のサブセットを処理する場合、サブセットの開始要素へのポインターと element-count-expr を使用して配列のサブセットを転送します。
次のいずれかです。
C/C++ 識別子。
variable-ref . identifier
array-slice
variable-ref '[' integral-expression [ : integral-expression ] ']'
array-slice は、1 つの連続する配列要素のセットを表す配列式です。
次のいずれかです。
length ( element-count-expr )
element-count-expr は整数式で、ランタイムに計算されます。 ポインター変数または可変長配列とともに使用します。
ポインター変数。
ホスト CPU とターゲットのメモリーアドレスが対応していないため、ポインター変数の値はホスト/ターゲットのインターフェイス間でコピーされません。 代わりに、ポインターが指すオブジェクトがターゲットに、またはターゲットからコピーされ、ポインター変数の値が更新されます。 デフォルトでは、単一要素がコピーされます。
element-count-expr を使用して、ポインターが指すデータとして見なすポインター型の要素の数を指定できます。 式の値が 0 または負の場合、ランタイムエラーが発生します。
可変長配列。
element-count-expr は、CPU とターゲット間でコピーする要素の数を指定します。
alloc_if ( condition ) | free_if (condition ) condition はブーリアン式です。
alloc_if は、オフロードがターゲットで実行されるときに in 節の割り当て変数がターゲットに新しいメモリーブロックを割り当てるかどうかを制御するブーリアン条件を指定します。 式が TRUE と評価されると、節でリストされている各変数に新しいメモリーが割り当てられます。 条件が FALSE と評価されると、ターゲットにすでに割り当てられている値が再利用 されます (データ保持)。 前のオフロードに対して free_if (0) 節を使用し、十分なサイズのメモリーブロックがターゲットの変数に割り当てられていることを確認する必要があります。
free_if は、in 節の割り当て変数に割り当てたメモリーを解放するかどうかを制御するブーリアン条件を指定します。 式が TRUE と評価されると、節でリストされている各変数に割り当てられたメモリーは解放されます。 条件が FALSE と評価されると、リストの各変数に割り当てられたメモリーに対する操作は行われません。 割り当てられたメモリーは後の節で再利用できます (データ保持)。
詳細は、「ポインター変数のメモリー割り当ての管理」を参照してください。
align (expression) expression の値は 2 の累乗でなければなりません。 この修飾子はポインター変数に適用され、インテル® MIC アーキテクチャーで割り当てたポインターデータの最小アライメントに合わせます。
alloc (array-slice) array-slice は、割り当てが必要な配列要素のセットを指定します。 in/out 式で指定されたデータは、コプロセッサー上に割り当てられた配列の対応する部分に転送されます。詳細は、「部分配列のメモリー割り当て」を参照してください。
into (var-exp) var-exp は変数式です。 into 修飾子は、CPU 上の 1 つの変数からコプロセッサー上の別の変数へ (またはその逆に) データを転送します。 into 修飾子を使用する場合、variable-ref では 1 つの項目のみ指定できます。 詳細は、「1 つの変数から別の変数へのデータの移動」を参照してください。
offload_transfer は、非同期データ転送を開始します。 同期データ転送も開始して完了します。
offload-parameter [, offload-parameter, …] は必須です。 offload-parameter は、すべて in 節またはすべて out 節でなければなりません。
signal ( tag ) はオプションです。 非同期データ転送を有効にする場合に指定します。指定した場合、CPU はデータ転送を開始した後、このプラグマ以降の文を実行できます。 指定しない場合、データ転送は同期されます。
wait ( tag[, tag, ...] ) はオプションです。 開始した非同期データ転送または非同期計算を待つ場合に指定します。
mandatory はオプションです。コプロセッサーで実行する場合に指定します。CPU で実行することはできません。 オフロードプログラムの実行に必要な正しいターゲット・ハードウェアがシステムで利用できない場合、プログラムは実行に失敗してエラーメッセージを出力します。
mandatory と if は一緒に指定することはできません。
データセットのサイズのようなランタイムの条件に基づいて文をオフロードするかどうか決定することができます。 if-specifier は、条件を指定します。
パラメーター・リスト: ヘテロジニアス環境でプログラムを実行すると、プログラム変数は CPU とターゲット間でコピーされます。 offload-parameter は、変数がコピーされる方向 (ポインターの場合はコピーされるデータの量) を指定します。
次の例は、2 つの異なるプラグマの節として signal および wait を使用してコプロセッサーから CPU のデータを非同期に受信します。最初のプラグマはデータ転送を開始し、次のプラグマはデータ転送が完了するのを待機します。
01 const int N = 4086;
02 float *f1, *f2;
03 f1 = (float *)memalign(64, N*sizeof(float));
04 f2 = (float *)memalign(64, N*sizeof(float));
...
10 // CPU は入力同期として f1 を送信
11 // 出力は f2 にあるが直ちに必要ではない
12 #pragma offload in( f1 : length(N) ) \
13 nocopy( f2 : length(N) ) signal(f2)
14 {
15 foo(N, f1, f2);
16 }
..
20 #pragma offload_transfer wait(f2) out( f2 : length(N)
21
22 // CPU は f2 の結果を使用可能
23