私はOpenACCを使用してのblock diagonal matricesに取り組んでいます。
コードを順番に実行すると、分解が正しく行われますが、OpecACCディレクティブで実行すると、分解を実行するときに間違った結果が得られます。OpenACC - ネストされたループの不思議な動作
LU分解が(hereLUPSolve
関数を参照)、そのタイプのネストされたループを含む:
for (unsigned int i = 0; i < N; i++)
for (unsigned int k = 0; k < i; k++)
ネストされたループのこのタイプは、並列領域内routine seq
ディレクティブで使用される場合、デバイスは常に管理する表示しますi=0
(k<i
の条件のために可能ではない可能性があります)でもネストされたループに入ります。私はOpenACCのないコードを実行したときに私が得る
x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
しかし、正しいもの(:
#pragma acc routine seq
void test (int* x, int const n) {
for (unsigned int i = 0; i < n; i++) {
x[i] = -1;
for (unsigned int k = 0; k < i; k++)
x[i] = k < i;
}
}
int main () {
unsigned const n(4);
unsigned const nb(3);
int x[nb*n];
#pragma acc parallel loop copyout(x[:nb*n])
for (unsigned int b = 0; b < nb; b++)
test(x+b*n,n);
// display x
}
私が得る結果はこの1つである:
は、私はそれをチェックするために簡単なコードを作りました)次のようになります。x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1,
とき012それは、ネストされたループに入るべきではありませんので、私は何か間違ったことしなければなりません...
プラスループを並列領域に直接置くと(関数呼び出しを使用せずに)うまく動作します。
は私はこのタイプのネストされたループとも試みたが、非常に奇妙です: 'のために(INT I = N-1、I> = 0; i--){(INT kに対する= I + 1。 (i = n-1; i> = 0; for n-1);これは次のように変更されます。 同じ奇妙な動作が起こり、デバイスは 'i = n-1'のネストループに入ります...' 0 <0'はネストされたループに当てはまります...私はちょうど私が間違っていることを知らない、それは私のループの状態のどこかにあるはずです... –