flag=(Abs(fold-F[l][i*Iz+j])<eps);
}
return flag;
}
main(int argc,char** argv)
{
float *x0,*x1,*y0,*z0,*y1,*z1;// м-цы граней
int i,j,jj,ii,k,i1,i2;
int *sendcounts,*displs; // массивы размерностей и смещений
char file[20];
float s,alfa;
FILE *fd,*fd1;
int flag=0,*flg,iter=0;
MPI_Status st;
MPI_Request req;
struct timeval tv1,tv2;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if((fd1=fopen("gran.txt","rt"))==NULL)
{printf("Запусти генератор\n");
MPI_Finalize();
return(1);
}
/* Читаем данные */
fscanf(fd1,"%f %f",&alfa,&eps);
fscanf(fd1,"%d %d %d",&Ix,&Iy,&Iz);
fscanf(fd1,"%f %f %f",&hx2,&hy2,&hz2);
hx2*=hx2;hy2*=hy2;hz2*=hz2; // возводим шаги в квадрат
dim=Ix/size;
ost=Ix%size;// кол-во первых процессоров со строками остатка
c=2/hx2+2/hy2+2/hz2+alfa;
sendcounts=(int *)malloc(size*sizeof(int));
displs=(int *)malloc(size*sizeof(int));
xdims(sendcounts,displs);
/* M – число слоев для данного процессора. Первый и последний процессоры получают по одному дополнительному слою для обмена данными, остальные – по два слоя */
M=(((rank==0)||(rank==size-1)) ? (sendcounts[rank]+1):(sendcounts[rank]+2));
/* Первый процесс не имеет первого дополнительного слоя */
i1=rank ? 1:0;
/* Выделяем память для F, слой – одномерный массив длины Iy*Iz */
F=(float **)malloc(M*sizeof(float *));
for(i=0;i<M;i++)
{
F[i]=(float *)malloc(Iy*Iz*sizeof(float));
for(j=0;j<Iy*Iz;j++)
F[i][j]=0;
}
/* Выделяем память для вспомогательных массивов граней */
x0=(float *)malloc(Iy*Iz*sizeof(float ));
y0=(float *)malloc(Ix*Iz*sizeof(float ));
y1=(float *)malloc(Ix*Iz*sizeof(float ));
z0=(float *)malloc(Ix*Iy*sizeof(float ));
z1=(float *)malloc(Ix*Iy*sizeof(float ));
if(rank==size-1) // последний процессор читает данные и рассылает остальным
{
/* Читаем грань Х=0 */
for(i=0;i<Iy*Iz;i++)
fscanf(fd1,"%f",&x0[i]);
MPI_Isend(&x0[0],Iy*Iz,MPI_FLOAT,0,tag,MPI_COMM_WORLD,&req);
/* Читаем грань Х=Хм */
for(i=0;i<Iy*Iz;i++)
fscanf(fd1,"%f",&F[M-1][i]);
/* Заполняем для пересылки грани Y */
for(i=0;i<size;i++)
{ sendcounts[i]*=Iz; // кол-во элементов для ш-го процессора
displs[i]*=Iz; // смещение по массиву y0
}
/* Читаем грань Y=0 */
for(i=0;i<Ix*Iz;i++)
fscanf(fd1,"%f",&y0[i]);
for(k=0;k<size-1;k++)
MPI_Isend(&y0[displs[k]],sendcounts[k],MPI_FLOAT,k,tag+1,
MPI_COMM_WORLD,&req);
for(i=1;i<M-1;i++)
for(j=0;j<Iz;j++)
F[i][j]=y0[displs[size-1]+(i-1)*Iz+j];
/* Читаем грань Y=Yм */
for(i=0;i<Ix*Iz;i++)
fscanf(fd1,"%f",&y1[i]);
for(k=0;k<size-1;k++)
MPI_Isend(&y1[displs[k]],sendcounts[k],MPI_FLOAT,k,tag+2,
MPI_COMM_WORLD,&req);
for(i=1;i<M-1;i++)
for(j=0;j<Iz;j++)
F[i][Iz*(Iy-1)+j]=y1[displs[size-1]+(i-1)*Iz+j];
/* Читаем грань Z=0 */
for(i=0;i<Ix*Iy;i++)
fscanf(fd1,"%f",&z0[i]);
xdims(sendcounts,displs); // заново заполняем массивы для Z
for(i=0;i<size;i++)
{ sendcounts[i]*=Iy;
displs[i]*=Iy;
}
for(k=0;k<size-1;k++)
MPI_Isend(&z0[displs[k]],sendcounts[k],MPI_FLOAT,k,tag+3,
MPI_COMM_WORLD,&req);
for(i=1;i<M-1;i++)
for(j=0;j<Iy;j++)
F[i][Iz*j]=z0[displs[size-1]+(i-1)*Iy+j];
/* Читаем грань Z=Zm */
for(i=0;i<Ix*Iy;i++)
fscanf(fd1,"%f",&z1[i]);
for(k=0;k<size-1;k++)
MPI_Isend(&z1[displs[k]],sendcounts[k],MPI_FLOAT,k,tag+4,
MPI_COMM_WORLD,&req);
for(i=1;i<M-1;i++)
for(j=0;j<Iy;j++)
F[i][Iz*(j+1)-1]=z1[displs[size-1]+(i-1)*Iy+j];
}
else
{/* Прием данных от последнего компьютера */
if(rank==0)
{ MPI_Irecv(&F[0][0],Iy*Iz,MPI_FLOAT,size-1,tag,MPI_COMM_WORLD,&req);
MPI_Wait(&req,&st);
}
/* Грань Y=0 */
MPI_Irecv(y0,sendcounts[rank]*Iz,MPI_FLOAT,size-1,tag+1,
MPI_COMM_WORLD,&req);
MPI_Wait(&req,&st);
for(i=i1;i<sendcounts[rank]+i1;i++)
for(j=0;j<Iz;j++)
F[i][j]=y0[(i-i1)*Iz+j];
/* Грань Y=Ym */
MPI_Irecv(y1,sendcounts[rank]*Iz,MPI_FLOAT,size-1,tag+2,
MPI_COMM_WORLD,&req);
MPI_Wait(&req,&st);
for(i=i1;i<sendcounts[rank]+i1;i++)
for(j=0;j<Iz;j++)
F[i][(Iy-1)*Iz+j]=y1[(i-i1)*Iz+j];
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.