
- •58 Параллельное умножение матриц в mpi.
- •59 Параллельное умножение матрицы и вектора в mpi.
- •60 Решение 2-мерного уравнения Лапласа методом 1-мерной декомпозиции.
- •62 Решение 3-мерного уравнения Лапласа методом 1-мерной декомпозиции.
- •64 Решение 3-мерного уравнения Лапласа методом 3-мерной декомпозиции.
- •65 Параллельная модификация метода Гаусса-Зейделя. Решение 2-мерного уравнения Лапласа 1 мерной декомпозицией (параллельный метод Гаусса-Зейделя).
58 Параллельное умножение матриц в mpi.
int size,rank;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int n=10,x=0, p=n/(size-1); // kazhdyi process schitaet po p strok
int a[n][n],c[n][n],b[n][n],d[p*n][n]; // a*b, c - rezul'tat
int i,k,l,r,j,s;
for (i=0;i<n;i++)
{ for(j=0;j<n;j++) { b[i][j]=j; a[i][j]=x; x++; } }
if (rank!=size-1)
{ for(k=rank*p;k<p*(rank+1);k++)
{ for(int j=0;j<n;j++){
s=0;
for (i=0; i<n; i++) {
s+=a[k][i]*b[i][j]; d[k][j]=s;
} } }
MPI_Send(&d[rank*p][0],p*n,MPI_DOUBLE,size-1,5,MPI_COMM_WORLD);
}
else
{ for (i=0; i<size-1;i++)
{ MPI_Recv(&c[i*p][0],p*n,MPI_DOUBLE,i,5,MPI_COMM_WORLD, &status); } }
MPI_Finalize();
59 Параллельное умножение матрицы и вектора в mpi.
int size,rank;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int i,k,j,s,x=0,p;
int n=10, a[n][n], c[n], b[n], d[p];
p=n/(size-1);
for (i=0;i<n;i++)
{
b[i]=i; for(j=0;j<n;j++) { a[i][j]=x;x++; }
}
if (rank!=size-1)
{ for(k=rank*p;k<p*(rank+1);k++) {
s=0; for(int j=0;j<n;j++)
{ s+=a[k][j]*b[j]; } d[k]=s; }
MPI_Send(&d[rank*p],p,MPI_DOUBLE,size-1,5,MPI_COMM_WORLD);
}
else
{ for (i=0; i<size-1;i++) { MPI_Recv(&c[i*p],p,MPI_DOUBLE,i,5,MPI_COMM_WORLD, &status); } }
60 Решение 2-мерного уравнения Лапласа методом 1-мерной декомпозиции.
const int N=100;
float P[N][N],
h=0.01, //шаг сетки
eps=0.01, //точность
max, //норма
**p, //текущая итерация
**pp, //предыдущая итерация
a[N],b[N]; //вспомогательные векторы
int i,j,
c, //кол-во строк матрицы на каждом процессоре
stop = 1; //условие заверщения цикла
int rank,size;
MPI_Init(&argc,&argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(rank<N%size)
{
c=N/size+1;
}else
{
c=N/size;
}
p=new float*[c];
pp=new float*[c];
for(i=0;i<c;i++)
{
p[i]=new float[N];
pp[i]=new float[N];
p[i][0]=1;
pp[i][0]=1;
for(int j=1;j<N;j++)
{
p[i][j]=0;
pp[i][j]=0;
}
}
if(rank==0)
{
do
{
if(size>1)
{
MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,
0,MPI_COMM_WORLD);
MPI_Recv(a,N,MPI_FLOAT,rank+1,size,
MPI_COMM_WORLD, &status);
}
max=0.0;
for(i=1;i<c-1;i++)
{
for(j=1;j<N-1;j++)
{
p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;
if(max<fabs(p[i][j]-pp[i][j]))
{
max=fabs(p[i][j]-pp[i][j]);
}
}
}
if(size>1)
{
for(j=1;j<N-1;j++)
{
p[c-1][j]=(pp[c-2][j]+a[j]+pp[c-1][j+1]+pp[c-1][j-1])/4;
if(max<fabs(p[c-1][j]-pp[c-1][j]))
{
max=fabs(p[c-1][j]-pp[c-1][j]);
}
}
float maxx;
for(i=1;i<size;i++)
{
MPI_Recv(&maxx,1,MPI_FLOAT,i,2*size,MPI_COMM_WORLD,&status);
if(maxx>max)
{
max=maxx;
}
}
}
if(max<=eps)
{
stop=0;
}
if(size>1)
{
for(i=1;i<size;i++)
{
MPI_Send(&stop,1,MPI_INT,i,3*size,MPI_COMM_WORLD);
}
}
for(i=0;i<c;i++)
{
for(j=0;j<N;j++)
{
pp[i][j]=p[i][j];
}
}
}while(stop==1);
for(i=0;i<c;i++)
{
for(int j=0;j<N;j++)
{
P[i][j]=p[i][j];
}
}
if(size>1)
{
int jj=c-1;
for(i=1;i<size;i++)
{
MPI_Recv(&c,1,MPI_INT,i,4*size,MPI_COMM_WORLD,&status);
for(j=0;j<c;j++)
{
jj++;
MPI_Recv(&P[jj][0],100,MPI_FLOAT,i,5*size,MPI_COMM_WORLD,&status);
}
}
}
ofstream out("result.txt");
for(i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
out<<P[i][j]<<'\t'; //вывожу в результаты в фаил
}
out<<'\n';
}
}
if(rank==size-1&&size>1)
{
do
{
MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);
MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD);
max=0;
for(i=1;i<c-1;i++)
{
for(j=1;j<N-1;j++)
{
p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;
if(max<fabs(pp[i][j]-p[i][j]))
{
max=fabs(pp[i][j]-p[i][j]);
}
}
}
for(j=1;j<N-1;j++)
{
p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+pp[0][j-1])/4;
if(max<fabs(pp[0][j]-p[0][j]))
{
max=fabs(pp[0][j]-p[0][j]);
}
}
MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);
for(i=0;i<c;i++)
{
for(j=0;j<N;j++)
{
pp[i][j]=p[i][j];
}
}
MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);
}while(stop==1);
MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);
for(i=0;i<c;i++)
{
MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD);
}
}
if(rank>0&&rank<size-1)
{
do
{
MPI_Recv(b,N,MPI_FLOAT,rank-1,0,MPI_COMM_WORLD,&status);
MPI_Send(&p[c-1][0],N,MPI_FLOAT,rank+1,0,MPI_COMM_WORLD);
MPI_Recv(a,N,MPI_FLOAT,rank+1,size,MPI_COMM_WORLD,&status);
MPI_Send(&p[0][0],N,MPI_FLOAT,rank-1,size,MPI_COMM_WORLD);
max=0;
int ii;
if(rank<N%size||100%size==0)
{
ii=rank*c;
}
if(rank>N%size&&100%size!=0)
{
ii=(N%size)*(c+1)+(rank-N%size)*c;
}
for(i=1;i<c-1;i++)
{
for(j=1;j<N-1;j++)
{
p[i][j]=(pp[i+1][j]+pp[i-1][j]+pp[i][j+1]+pp[i][j-1])/4;
if(max<fabs(pp[i][j]-p[i][j]))
{
max=fabs(pp[i][j]-p[i][j]);
}
}
}
for(j=1;j<N-1;j++)
{
p[0][j]=(pp[1][j]+b[j]+pp[0][j+1]+pp[0][j-1])/4;
if(max<fabs(pp[0][j]-p[0][j]))
{
max=fabs(pp[0][j]-p[0][j]);
}
p[c-1][j]=(pp[c-2][j]+a[j]+pp[c-1][j+1]+pp[c-1][j-1])/4;
if(max<fabs(pp[c-1][j]-p[c-1][j]))
{
max=fabs(pp[c-1][j]-p[c-1][j]);
}
}
MPI_Send(&max,1,MPI_FLOAT,0,2*size,MPI_COMM_WORLD);
for(i=0;i<c;i++)
{
for(j=0;j<N;j++)
{
pp[i][j]=p[i][j];
}
}
MPI_Recv(&stop,1,MPI_INT,0,3*size,MPI_COMM_WORLD,&status);
}while(stop==1);
MPI_Send(&c,1,MPI_INT,0,4*size,MPI_COMM_WORLD);
for(i=0;i<c;i++)
{
MPI_Send(&p[i][0],N,MPI_FLOAT,0,5*size,MPI_COMM_WORLD);
}
}