2017-05-17 51 views
0

我處理塊對角矩陣(每個塊具有相同的尺寸),並且我有一個illegal address error當我使用private動態分配的2D陣列...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; 

錯誤我得到的是:

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

如果我陣列壓扁成一維數組,並使用詞典的索引或靜態二維數組,但我使用需要double**作爲參數的函數,所以我寧願堅持使用動態2D它工作正常數組...

我已經閱讀了關於在規範的private條款,但它並沒有說,動態二維數組,不支持,所以我想我做錯了什麼......

+0

'A'的尺寸是多少? – user463035818

+0

@ tobi303'A'是'N * NBxN * NB'矩陣。對不起'A'是**塊對角線**,我剛編輯過。每個塊是一個'N×N'矩陣,'A'由'NB'塊組成。 –

回答

3

很抱歉,但使用不支持私有子句中的指針數組。問題在於,編譯器運行時必須爲每個組,工作者或向量動態創建一個私有(取決於使用私有子句的循環)並填寫所有設備指針。這會帶來非常高的間接費用。

如果「B」是一個固定大小的靜態數組,「double B [N] [N]」,那麼你可以在private子句中使用它。

否則,我會建議通過添加第三維手動私有化數組。

// 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;