Как использовать MPI и OpenMP для запуска параллельного цикла - PullRequest
0 голосов
/ 04 июля 2019

Мне нужно использовать MPI и OpenMP (2 разные проблемы) для распараллеливания кода из марафона Sbac-Pad (ссылка: http://lspd.mackenzie.br/marathon/18/problems.html).. Я работаю над тестом himeno. Я считаю, что единственная часть этого кодастоит распараллелить, это функция jacobi:

#define MR(mt,n,r,c,d)  mt->m[(n) * mt->mrows * mt->mcols * mt->mdeps + (r) * mt->mcols* mt->mdeps + (c) * mt->mdeps + (d)]

struct Matrix {
  float* m;
  int mnums;
  int mrows;
  int mcols;
  int mdeps;
};

float
jacobi(int nn, Matrix* a,Matrix* b,Matrix* c,
       Matrix* p,Matrix* bnd,Matrix* wrk1,Matrix* wrk2)
{
  int    i,j,k,n,imax,jmax,kmax;
  float  gosa,s0,ss;

  imax= p->mrows-1;
  jmax= p->mcols-1;
  kmax= p->mdeps-1;

  for(n=0 ; n<nn ; n++){
    gosa = 0.0;
    for(i=1 ; i<imax; i++)
      for(j=1 ; j<jmax ; j++)
        for(k=1 ; k<kmax ; k++){
          s0= MR(a,0,i,j,k)*MR(p,0,i+1,j,  k)
            + MR(a,1,i,j,k)*MR(p,0,i,  j+1,k)
            + MR(a,2,i,j,k)*MR(p,0,i,  j,  k+1)
            + MR(b,0,i,j,k)
             *( MR(p,0,i+1,j+1,k) - MR(p,0,i+1,j-1,k)
              - MR(p,0,i-1,j+1,k) + MR(p,0,i-1,j-1,k) )
            + MR(b,1,i,j,k)
             *( MR(p,0,i,j+1,k+1) - MR(p,0,i,j-1,k+1)
              - MR(p,0,i,j+1,k-1) + MR(p,0,i,j-1,k-1) )
            + MR(b,2,i,j,k)
             *( MR(p,0,i+1,j,k+1) - MR(p,0,i-1,j,k+1)
              - MR(p,0,i+1,j,k-1) + MR(p,0,i-1,j,k-1) )
            + MR(c,0,i,j,k) * MR(p,0,i-1,j,  k)
            + MR(c,1,i,j,k) * MR(p,0,i,  j-1,k)
            + MR(c,2,i,j,k) * MR(p,0,i,  j,  k-1)
            + MR(wrk1,0,i,j,k);

          ss= (s0*MR(a,3,i,j,k) - MR(p,0,i,j,k))*MR(bnd,0,i,j,k);

          gosa+= ss*ss;
          MR(wrk2,0,i,j,k)= MR(p,0,i,j,k) + omega*ss;
        }

    for(i=1 ; i<imax ; i++)
      for(j=1 ; j<jmax ; j++)
        for(k=1 ; k<kmax ; k++)
          MR(p,0,i,j,k)= MR(wrk2,0,i,j,k);

  } /* end n loop */

  return(gosa);
}

Проблема в том, что эта функция, по-видимому, имеет последовательный характер, поскольку каждая итерация nn зависит от последней. Что я пробовал, используя MPI, создавал вспомогательную переменную для gosa (auxgosa) и использовал MPI_REDUCE после циклов i j k for, как показано ниже (корневой процесс имеет ранг = 0):

//rank is the current process
//size is the total amount of processes

int start = ((imax+1)/size)*rank; 
int stop = ((imax+1)/size)*(rank+1)-1;

  if(rank == 0){start++;}

  for(n=0 ; n<nn ; n++){
    gosa = 0.0;
    auxgosa = 0.0;

    for(i=start ; i<stop; i++)
      for(j=1 ; j<jmax ; j++)
        for(k=1 ; k<kmax ; k++){
          s0= MR(aa,0,i,j,k)*MR(pp,0,i+1,j,k)
            + MR(aa,1,i,j,k)*MR(pp,0,i,  j+1,k)
            + MR(aa,2,i,j,k)*MR(pp,0,i,  j,  k+1)
            + MR(bb,0,i,j,k)
             *( MR(pp,0,i+1,j+1,k) - MR(pp,0,i+1,j-1,k)
              - MR(pp,0,i-1,j+1,k) + MR(pp,0,i-1,j-1,k) )
            + MR(bb,1,i,j,k)
             *( MR(pp,0,i,j+1,k+1) - MR(pp,0,i,j-1,k+1)
              - MR(pp,0,i,j+1,k-1) + MR(pp,0,i,j-1,k-1) )
            + MR(bb,2,i,j,k)
             *( MR(pp,0,i+1,j,k+1) - MR(pp,0,i-1,j,k+1)
              - MR(pp,0,i+1,j,k-1) + MR(pp,0,i-1,j,k-1) )
            + MR(cc,0,i,j,k) * MR(pp,0,i-1,j,  k)
            + MR(cc,1,i,j,k) * MR(pp,0,i,  j-1,k)
            + MR(cc,2,i,j,k) * MR(pp,0,i,  j,  k-1)
            + MR(awrk1,0,i,j,k);

          ss= (s0*MR(aa,3,i,j,k) - MR(pp,0,i,j,k))*MR(abnd,0,i,j,k);

          auxgosa+= ss*ss;
          MR(awrk2,0,i,j,k)= MR(pp,0,i,j,k) + omega*ss;
        }

    MPI_Reduce(&auxgosa,&gosa,1,MPI_FLOAT,MPI_SUM,0,MPI_COMM_WORLD);

    for(i=1 ; i<imax ; i++)
      for(j=1 ; j<jmax ; j++)
        for(k=1 ; k<kmax ; k++)
          MR(pp,0,i,j,k)= MR(awrk2,0,i,j,k);

  } /* end n loop */

К сожалению, этоне сработало. Может ли кто-нибудь дать мне некоторое представление об этом? Я планирую использовать аналогичную стратегию с OpenMP.

1 Ответ

0 голосов
/ 04 июля 2019

Если awrk2 отличается от a, p, b, c и wrk1, то зависимость от цикла не переносится.

Простой поиск в Google укажет вам параллельные версии теста Himeno (доступны версии MPI, OpenMP и гибридные MPI + OpenMP).

...