OPENMP-带预条件的并行Schwarz算法

OPENMP-带预条件的并行Schwarz算法,c,parallel-processing,mpi,openmp,C,Parallel Processing,Mpi,Openmp,我需要将下面的Schwarz算法并行化,但我不知道如何处理前提条件和存在嵌套循环的事实。 我必须使用OpenMP或MPI void ssor_forward_sweep(int n, int i1, int i2, int j1, int j2, int k1, int k2, double* restrict Ax, double w) { #define AX(i,j,k) (Ax[((k)*n+(j))*n+(i)]) int i, j, k; double xx, xn, xe, xu

我需要将下面的Schwarz算法并行化,但我不知道如何处理前提条件和存在嵌套循环的事实。 我必须使用OpenMP或MPI

void ssor_forward_sweep(int n, int i1, int i2, int j1, int j2, int k1, int k2, double* restrict Ax, double w)
{
#define AX(i,j,k) (Ax[((k)*n+(j))*n+(i)])

int i, j, k;
double xx, xn, xe, xu;

for (k = k1; k < k2; ++k) {
   for (j = j1; j < j2; ++j) {
      for (i = i1; i < i2; ++i) {
         xx = AX(i,j,k);
         xn = (i > 0)   ? AX(i-1,j,k) : 0;
         xe = (j > 0)   ? AX(i,j-1,k) : 0;
         xu = (k > 0)   ? AX(i,j,k-1) : 0;
         AX(i,j,k) = (xx+xn+xe+xu)/6*w;
      }
   }
}
#undef AX
}
void ssor_-forward_-sweep(整数n、整数i1、整数i2、整数j1、整数j2、整数k1、整数k2、双*限制Ax、双w)
{
#定义AX(i,j,k)(AX[(k)*n+(j))*n+(i)])
int i,j,k;
双xx,xn,xe,xu;
对于(k=k1;k0)?AX(i-1,j,k):0;
xe=(j>0)?AX(i,j-1,k):0;
xu=(k>0)?AX(i,j,k-1):0;
AX(i,j,k)=(xx+xn+xe+xu)/6*w;
}
}
}
#未定义的AX
}
考虑到每个循环使用以前循环中的值,如何并行化此函数以获得最佳时间

我已经尝试过将循环两个接两个地并行化,或者通过分块(如Stencil Jacobi 3D)来并行化,但是没有成功


多谢各位

不幸的是,循环间数据依赖关系限制了嵌套循环中可获得的并行度

您可以使用具有依赖项的任务,这将是最简单的方法。OpenMP运行时库将负责调度,您只关注您的算法。另一个好的方面是,在任何循环的末尾都没有同步,而只是在代码的依赖部分之间

#pragma omp parallel
#pragma omp single
for (int k = 0; k < k2; k += BLOCK_SIZE) {
  for (int j = 0; j < j2; j += BLOCK_SIZE) {
    for (int i = 0; i < i2; i += BLOCK_SIZE) {
      #pragma omp task depend (in: AX(i-1,j,k),AX(i,j-1,k),AX(i,j,k-1)) \
                       depend (out: AX(i,j,k))
      // your code here
    }
  }
}
在波前并行化的情况下,最后一步是将外部循环(块间迭代)转化为波前,以便迭代彼此之间不依赖的元素。在三维迭代空间中,它基本上是一个从(0,0,0)到(i2,j2,k2)的对角线平面。类似下图中以红色突出显示的部分

我要举一个二维波前的例子,因为它更容易理解

#define min(a,b) ((a)<(b)?(a):(b))
#pragma omp parallel
for (int d = 1; d < i2+j2; d++ ) {
    int i = min(d,i2) - 1;
    int j = 0;
    // Iterations in the inner loop are independent
    // Implicit thread barrier (synchronization) at the end of the loop
    #pragma omp for
    for ( ; i >= 0 && j < min(d,j2); i--, j++) {
      // your code here
    }
}
定义最小值(a,b)((a)=0&&j
#define min(a,b) ((a)<(b)?(a):(b))
#pragma omp parallel
for (int d = 1; d < i2+j2; d++ ) {
    int i = min(d,i2) - 1;
    int j = 0;
    // Iterations in the inner loop are independent
    // Implicit thread barrier (synchronization) at the end of the loop
    #pragma omp for
    for ( ; i >= 0 && j < min(d,j2); i--, j++) {
      // your code here
    }
}