2017-05-17 23 views
0

私はブロック対角行列を扱っています(各ブロックは同じ大きさを持っている)、私はprivate動的に割り当てられた2次元配列を使用する場合、私はillegal address errorを持っている...OpenACC - プライベート2D配列

// NB is the number of block 
// N is the block size 
// A is the main matrix (block diagonal) 

double** B; // a block 
B = new double*[N]; 
for (unsigned int i = 0; i < N; i++) 
    B[i] = new double[N]; 

#pragma acc parallel loop private(B[:N][:N]) copyin(A[:NB*N][:NB*N]) 
for (unsigned int b = 0; b < NB; b++) { 
    #pragma acc loop 
    for (unsigned int i = 0; i < N; i++) { 
     #pragma acc loop 
     for (unsigned int j = 0; j < N; j++) { 
      B[i][j] = A[b*N+i][b*N+j]; 
     } 
    } 
    // process B 
} 

for (unsigned int i = 0; i < N; i++) 
    delete[] B[i]; 
delete[] B; 

エラーI取得です:

call to cuStreamSynchronize returned error 700: Illegal address during kernel execution 

ので、私は、ダイナミック2Dに固執することを好むだろう、私は1次元配列に配列を平らにし、辞書式インデックスまたは静的な2次元配列を使用する場合、それは正常に動作しますが、私は、パラメータとしてdouble**を必要とする機能を使用しています配列...

私はスペックにprivate句にまで読んだが、それは私が何か間違ったことをやっていると仮定しているダイナミックな2次元配列がそのようにサポートされていないと言っていません...

+0

「A」の寸法は何ですか? – user463035818

+0

@ tobi303 'A 'は' N * NBxN * NB'マトリックスです。申し訳ありません、 'A'は**ブロック対角です**、私はそれを編集しました。各ブロックは「N×N」行列であり、「A」は「NB」ブロックで構成される。 –

答えて

3

申し訳ありませんが、使用してprivate節のポインタの配列はサポートされていません。問題は、コンパイラのランタイムは、個々のギャング、ワーカー、またはベクタ(プライベート句を持つループに応じて)ごとにプライベートを動的に作成し、すべてのデバイスポインタを埋めなければならないということです。これには非常に高いオーバーヘッドコストが伴います。

"B"が固定サイズの静的配列 "double B [N] [N]"の場合、private節で使用できます。

それ以外の場合は、3次元を追加して手動で民営化することをお勧めします。

// NB is the number of block 
// N is the block size 
// A is the main matrix (block diagonal) 

double*** B; // a block 
B = new double**[NB]; 
for (unsigned int i = 0; i < NB; i++) { 
    B[i] = new double*[N]; 
    for (unsigned int j = 0; j < N; j++) { 
    B[i][j] = new double[N]; 
}} 


#pragma acc parallel loop create(B[:NB][:N][:N]) copyin(A[:NB*N][:NB*N]) 
for (unsigned int b = 0; b < NB; b++) { 
    #pragma acc loop 
    for (unsigned int i = 0; i < N; i++) { 
     #pragma acc loop 
     for (unsigned int j = 0; j < N; j++) { 
      B[b][i][j] = A[b*N+i][b*N+j]; 
     } 
    } 
    // process B 
} 

for (unsigned int i = 0; i < NB; i++) { 
    for (unsigned int j = 0; j < N; j++) { 
    delete[] B[i][j]; 
    } 
    delete[] B[i]; 
} 
delete[] B;