Я пытаюсь реализовать трехдиагональный алгоритм ПЦР с openACC, этот метод имеет векторный параллелизм.и вызывается через solvesolvePCR () с параллелизмом банд.когда я увеличиваю размер меша выше 256 (например, 300, ... 512), я сталкиваюсь с состоянием гонки.
#pragma acc routine vector
void pcr(int n, double *a, double *c, double *d)
{
int level = log2(n)+1;
int s;
double r;
int m=512;
int size=n/m+1;
// these should go on register
double a0[20];
double a1[20];
double a2[20];
double c0[20];
double c1[20];
double c2[20];
double d0[20];
double d1[20];
double d2[20];
int index;
#pragma acc loop seq private(a0[0:20],a1[0:20],a2[0:20],c0[0:20],c1[0:20],c2[0:20],d0[0:20],d1[0:20],d2[0:20])
for (int p = 0; p < level; p++)
{
s = 1 << p;
#pragma acc loop vector private(a0[0:20],a1[0:20],a2[0:20],c0[0:20],c1[0:20],c2[0:20],d0[0:20],d1[0:20],d2[0:20],index)
for(int i = 0; i < n ; i++) {
index=i/m;
if (i - s < 0 && i + s < n) {
a0[index]=a[i];
a1[index]=0.0;
a2[index]=a[i+s];
c0[index]=c[i];
c1[index]=0.0;
c2[index]=c[i+s];
d0[index]=d[i];
d1[index]=0.0;
d2[index]=d[i+s];
}
else if (i + s >= n && i - s >= 0)
{
a0[index]=a[i];
a1[index]=a[i-s];
a2[index]=0.0;
c0[index]=c[i];
c1[index]=c[i-s];
c2[index]=0.0;
d0[index]=d[i];
d1[index]=d[i-s];
d2[index]=0.0;
}
// both indices are ok to assign
else
{
a0[index]=a[i];
a1[index]=a[i-s];
a2[index]=a[i+s];
c0[index]=c[i];
c1[index]=c[i-s];
c2[index]=c[i+s];
d0[index]=d[i];
d1[index]=d[i-s];
d2[index]=d[i+s];
}
}
// both indices are ok to assign
#pragma acc loop vector private(a0[0:20],a1[0:20],a2[0:20],c0[0:20],c1[0:20],c2[0:20],d0[0:20],d1[0:20],d2[0:20],index,r)
for(int i=0;i<n;i++)
{
index=i/m;
r = 1. / (1. - a0[index] * c1[index] - c0[index] * a2[index]);
a[i] = -r * a0[index] * a1[index];
c[i] = -r * c0[index] * c2[index];
d[i] = r * (d0[index] - a0[index] * d1[index] - c0[index] * d2[index]);
}
}
}
и вызывается из параллельного цикла банды.
#pragma acc routine gang
void solvePCR( const int index )
{
double eig;
int count = 0;
int i, j;
for ( int j = 0; j < nxChunk; j++ )
{
#pragma acc loop private(eig)
for ( int i = 0; i < nyChunk; i++ )
{
T.pcr(nz, crpcr_lower+nz*i, crpcr_upper+nz*i,crpcr_rhs+nz*i );
}
}
}