0

これがopenaccに関する私の質問です。API (v1 および v2) を読みましたが、同じ配列の異なるサブパートを持つネストされたデータ環境の動作がわかりません。

コード例:

#pragma acc data pcopyin(a[0:20])
{
  #pragma acc data pcopyin(a[100:20])
  {
    #pragma acc parallel loop
    for(i=0; i<20; i++)
      a[i] = i;
      a[i+100] = i;
  }
}

私の理解では、これは機能するはずです(または少なくとも2つのaccデータ部分):

  • 最初のプラグマは、a[0,20] がアクセラレータ上にあるかどうかをチェックします
  • NO -> データはデバイスに割り当てられ、転送されます
  • 2 番目のプラグマは、a[100,120] がアクセラレータ上にあるかどうかをチェックします
  • ポインタ a はアクセラレータ上にありますが、a[100,120] からのデータではありません
  • データはデバイスに割り当てられ、転送されます

この種のことを CAPS コンパイラ (テスト マシンで現在のみ利用可能な v3.3.0) で試しましたが、2 番目の pragma acc data がエラーを返しました (2 番目のサブ配列の形状が正しくありません)。したがって、私のテストで何が起こるか (おそらく) は、ポインター "a" がアクセラレーターで見つかりましたが、それに関連付けられた形状 ([0:20]) は、2 番目のプラグマ ([100:20]) と同じではありません。 )。

これは API で計画されている通常の動作ですか、それとも私の例は機能するはずですか?

さらに、これが機能する場合、同じ配列のサブパーツ間に何らかの一貫性がありますか (どういうわけか、それらはホストのように配置され、a[i] += a[100+ を配置できます) i]私のカーネルで)?

4

1 に答える 1

1

現在のテストは、「a」がデバイス上にあるかどうかを調べます。したがって、2 番目のデータ領域が検出されたとき、「a」はすでにデバイス上にありますが、部分的にしか存在しません。代わりに、"a" を指すポインターを追加し、デバイス上でこのポインターを参照することをお勧めします。何かのようなもの:

#include <stdio.h>

int main () {

   int a[200];
   int *b;
   int i;
   for(i=0; i<200; i++) a[i] = 0;
   b=a+100;

#pragma acc data pcopy(a[0:20])
{
  #pragma acc data pcopy(b[0:20])
  {
    #pragma acc parallel loop
    for(i=0; i<20; i++) {
      a[i] = i;
      b[i] = i;
    }
  }
}
   for(i=0; i<22; i++) printf("%d = %d \n", i, a[i]);
   for(i=100; i<122; i++) printf("%d = %d \n", i, a[i]);
  return 0;
 }

「a[100:20]」をコピーしたばかりの場合、この範囲外へのアクセスはプログラマ エラーと見なされます。

これが役に立てば幸いです、マット

于 2014-01-16T22:44:16.993 に答える