/* Грань Z=0 */
MPI_Irecv(z0,sendcounts[rank]*Iy,MPI_FLOAT,size-1,tag+3,MPI_COMM_WORLD,&req);
MPI_Wait(&req,&st);
for(i=i1;i<sendcounts[rank]+i1;i++)
for(j=0;j<Iy;j++)
F[i][j*Iz]=z0[(i-i1)*Iy+j];
/* Грань Z=Zm */
MPI_Irecv(z1,sendcounts[rank]*Iy,MPI_FLOAT,size-1,tag+4,MPI_COMM_WORLD,&req);
MPI_Wait(&req,&st);
for(i=i1;i<sendcounts[rank]+i1;i++)
for(j=0;j<Iy;j++)
F[i][(j+1)*Iz-1]=z1[(i-i1)*Iy+j];
}
free(y0);
free(y1);
free(z0);
free(z1);
/* Выделяем память для ро и заполняем нулями */
xdims(sendcounts,displs);
/* Для rank=0 считываем со 2-го слоя, т.к. 1-й не используется*/
sendcounts[0]--;
r=(float **)malloc(sendcounts[rank]*sizeof(float *));
for(i=0;i<sendcounts[rank];i++)
{ r[i]=(float *)malloc(Iy*Iz*sizeof(float ));
for(j=0;j<Iy*Iz;j++) r[i][j]=0;
}
/* Читаем данные для ро */
if(rank==size-1)
{if((fd=fopen("dat_r.txt","rt"))==NULL)
{printf("Запусти генератор1\n");
MPI_Finalize();
return(1);
}
for(k=0;k<size-1;k++)// по процессорам
{
for(i=0;i<sendcounts[k];i++)// по слоям
{
for(j=0;j<Iy*Iz;j++)
fscanf(fd,"%f",&x0[j]);
MPI_Send(&x0[0],Iy*Iz,MPI_FLOAT,k,tag+5,MPI_COMM_WORLD);
}
}
/* Для rank=size-1 */
for(i=0;i<sendcounts[rank];i++)
for(j=0;j<Iy*Iz;j++)
fscanf(fd,"%f",&r[i][j]);
fclose(fd);
}
else
{
for(i=0;i<sendcounts[rank];i++)
MPI_Recv(&r[i][0],Iy*Iz,MPI_FLOAT,size-1,tag+5,MPI_COMM_WORLD,&st);
}
fclose(fd1);
xdims(sendcounts,displs);
flg=(int*)malloc(size*sizeof(int)); // массив флагов
for(i=0;i<size;i++) flg[i]=1;
/* Замеряем время */
if(!rank) gettimeofday(&tv1,(struct timezone*)0);
/*-------------------------- ВЫЧИСЛЕНИЯ -----------------------------*/
while(!flag)
{flag=1;
iter++;
/* Ожидаем «старый» слой от следующего процесса */
if(rank<size-1)
MPI_Irecv(&F[M-1][0],Iy*Iz,MPI_FLOAT,rank+1,tag+1,MPI_COMM_WORLD,&req);
/* отправляем первый «старый» слой предыдущему процессу и получаем «новый» слой от предыдущего процесса */
if(rank>0)
{ MPI_Isend(&F[1][0],Iy*Iz,MPI_FLOAT,rank-1,tag+1,MPI_COMM_WORLD,&req);
MPI_Recv(&F[0][0],Iy*Iz,MPI_FLOAT,rank-1,tag,MPI_COMM_WORLD,&st);
}
/* Вычисляем слои, кроме последнего */
for(i=1;i<M-2;i++)
flag*= vichisl(i);
/* для последнего слоя нужен слой от следующего процесса */
if(rank<size-1)
MPI_Wait(&req,&st);
/* Получаем последний слой */
flag*=vichisl(M-2);
/* отправляем последний слой следующему процессу */
if (rank<size-1)
MPI_Send(&F[M-2][0],Iy*Iz,MPI_FLOAT,rank+1,tag,MPI_COMM_WORLD);
/* Получаем флаги */
MPI_Allgather(&flag,1,MPI_INT,flg,1,MPI_INT,MPI_COMM_WORLD);
flag=1;
for(i=0;i<size;i++) flag*=flg[i];
}
/*-------------------Вычисления окончены----------------------------- */
/* Замеряем время завершения вычислений */
if(!rank) gettimeofday(&tv2,(struct timezone*)0);
{ s=(tv2.tv_sec-tv1.tv_sec)+(tv2.tv_usec-tv1.tv_usec)*0.000001;
printf("Время исполнения %f с\nЧисло итераций %d\n",s,iter);
}
/*Запись в файл */
if(!rank)
{xdims(sendcounts,displs);
fd=fopen("rez.dat","wt");
fprintf(fd,"Количество процессоров: %d\n",size);
fprintf(fd,"Размерность данных: Ix=%d Iy=%d Iz=%d\n",Ix-1,Iy-1,Iz-1);
fprintf(fd,"Точность решения: %f\n",eps);
fprintf(fd,"Число итераций: %d\n",iter);
fprintf(fd,"Время исполнения: %f c\n\n",s);
fprintf(fd,"rank=0 sendc=%d \n",sendcounts[0]);
for(i=0;i<M-1;i++)
{ for(j=0;j<Iy;j++)
{for(k=0;k<Iz;k++)
fprintf(fd,"%f ",F[i][j*Iz+k]);
fprintf(fd,"\n");
}
fprintf(fd,"\n");
}
for(k=1;k<size;k++)// принимаем данные от других процессоров
{fprintf(fd,"rank=%d sendc=%d\n",k,sendcounts[k]);
for(i=0;i<sendcounts[k];i++)
{ MPI_Recv(x0,Iy*Iz,MPI_FLOAT,k,tag,MPI_COMM_WORLD,&st);
for(j=0;j<Iy;j++)
{ for(l=0;l<Iz;l++)
fprintf(fd,"%f ",x0[j*Iz+l]);
fprintf(fd,"\n");
}
fprintf(fd,"\n");
}
fprintf(fd,"\n");
}
fclose(fd);
}
else
{
for(i=0;i<sendcounts[rank];i++)
MPI_Send(&F[i+i1][0],Iy*Iz,MPI_FLOAT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return(0);
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.