我正在尝试使用openACC实现三对角PCR算法,该例程具有矢量并行性。并通过具有帮派并行性的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 );
}
}
}
答案 0 :(得分:1)
我的最佳猜测是向量长度为256,因此当超过此长度时,您将有多个帮派。由于solvePCR中的“ j”循环没有循环指令,因此它将以“帮派冗余”模式运行,即所有帮派将执行“ j”的所有迭代。
假设您要从“并行”区域调用此例程,请尝试添加“ num_gangs(1)”。
#pragma acc parallel num_gangs(1)
{
solvePCR(index);
}
如果我是正确的话,比赛条件应该消失了。
如果没有,您可以发表完整的复制示例吗?