Je travaille sur LU decomposition de block diagonal matrices en utilisant OpenACC.
Je reçois la décomposition correcte lorsque je cours mon code de manière séquentielle, alors que lorsque je l'exécute sous les directives OpecACC, j'obtiens un mauvais résultat lors de la décomposition.OpenACC - Comportement étrange de la boucle imbriquée
décomposition LU implique boucle imbriquée de ce type (voir la fonction hereLUPSolve
):
for (unsigned int i = 0; i < N; i++)
for (unsigned int k = 0; k < i; k++)
Il semble que lorsque ce type de boucle imbriquée est utilisée dans une directive routine seq
dans une région parallèle, le dispositif gère toujours pour entrer dans la boucle imbriquée même lorsquei=0
(ce qui ne devrait pas être possible en raison de la condition k<i
).
J'ai fait un code simple à vérifier:
#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
}
Le résultat que je reçois est celui-ci:
x = 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
Mais le bon (que je reçois quand je lance le code sans OpenACC) devrait être:
x = -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1,
Je dois faire quelque chose de mal parce qu'il ne doit pas entrer dans la boucle imbriquée lorsque i=0
...
Plus quand je mets les boucles directement dans la région parallèle (sans utiliser un appel de fonction) cela fonctionne très bien.
Il est très étrange, j'ai essayé aussi avec boucle imbriquée de ce type: ' for (int i = n-1, i> = 0; je--) {for (int i = k + 1; k = 0; i--) {for (int k = 0; k