параллельное программирование

  • Автор темы not dead
  • Дата начала
Статус
Закрыто для дальнейших ответов.
N

not dead

Гость
#1
помогите кто может!!!Валюсь по учебе
Нужно подробное описание программы.Неважно рабочая ли она или нет..Она решает задачу теплопроводности с помощью распараллеливания..а именно создание виртуальной декартовой двумерной топологии ..Рассчетная область делится на I=J равных частей по осям х и у и происходит обмен межде процессорами..Данные ,рассчитанные в каждые в своей область,собираются в отдельные файлы ,которые потом обьединяются в один..Здесь представлена сама программа создания вирт.топологии и программа объединяющая файлы в один..
Скажите пожалуйста что означает записьMPI_Comm COMM,MPI_File fh ,что такое fh ,зачем это нужно ,где и вкаких функциях это используется и для чего...
Что делает функция MPI_File_open(MPI_COMM_SELF,fname,MPI_MODE_CREATE|MPI_MODE_RDWR,MPI_INFO_NULL,&fh); и что означают ее параметры и в какой части программы они используются... особенно MPI_COMM_SELF...И зачем этот комменикато нужен?
Дайте пожалуйста подробное описание всех функций в программе и в частности функций типа MPI_*_*()
Как происходит обмен данными в программе?
HELP!!!!

Код:
//рассчетная программа
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <mpi.h>
#include <string.h>

#define C(U) (1.0/(0.00225 - 0.000000000608*U*U)) 
#define Ro(U) (7860.0 + 41500.0/U)
#define Lambda(U) (1.45 + 0.023*U - 0.000002*U*U)
#define U_XO(x, t, L) (340.0*x/L + (1.0 - x/L)*(300.0 + 700.0*t/T))
#define U_XL(x, t, L) ((300.0 + 350.0*t/T)*(1.0 - x/L) + 340.0*x/L*exp(-0.125*t/T))
#define U_OY(y, t, L) ( 300.0 + t/T*700.0/(1 + y/L) )
#define U_LY(y, t, L) ( 340.0*exp( -0.125*t/T*y/L))
#define U_XYO(x, y, L) ( (300.0 + 40.0*x/L)*(sin(3.14*y/L) + 1.0) )

int funk_vyich();
int funk_trans();
int funk_fwrite();

MPI_Comm COMM;
MPI_File fh;

int maxi, maxj, Hi,Hj,IDi,IDj;//кординаты процессора
int gridrank;идентификатор процессора
int NACHi,NACHj;
int Uid,Rid,Lid,Did;//на границах блока

int Numproc,Myid,h,N,st,end,I,J;
int r[2],l[2],u[2],d[2];
double *U1,*U2,*Temp,T; 
double start,Tau,dx,dy,dt,L;
double *Rl,*Rr,*Rd,*Ru;
double *Sl,*Sr,*Sd,*Su;

int main (int argc,char* argv[])
{
int n,i,j;	 
double a_max;
int Periods[2]= {0,0};//периодичность 
int Dims[2]  = {0,0};//количество процессоров по двум направлениям решетки
int Coords[2] = {0,0};//координаты процессора
char fname[100];

FILE *out;
FILE *file;

//инициализация MPI
MPI_Init(&argc,&argv);			
MPI_Comm_size(MPI_COMM_WORLD,&Numproc);
MPI_Comm_rank(MPI_COMM_WORLD,&Myid); 

//sprintf(fname,"/tmp/file_%d",Myid);
sprintf(fname,"file_%d",Myid);

MPI_File_open(MPI_COMM_SELF,fname,MPI_MODE_CREATE|MPI_MODE_RDWR,MPI_INFO_NULL,&fh);

if (Myid == 0) file = fopen("OUT_L4.txt","a+");
if (argc>2) 
{ 
I = J = atoi(argv[1]); 
T = atof(argv[2]);
}

if(Myid==0) 
{
printf("T = %4f I = J = %d\n",T,I);
start = MPI_Wtime();//таймер
} 

MPI_Bcast(&T, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&I, 1, MPI_INT, 0, MPI_COMM_WORLD);	
MPI_Bcast(&J, 1, MPI_INT, 0, MPI_COMM_WORLD);	

//параматры сетки
L = 0.01;	
dx = L/(I+1);
dy = L/(J+1);
a_max = .6237301272e-5;
dt = 0.9*0.5/(1.0/dx/dx+1.0/dy/dy)/a_max;
N = (int)(T/dt + 0.5);
dt = T/N;

MPI_Dims_create(Numproc,2,Dims); 

maxi = Dims[0];	
maxj = Dims[1];

MPI_Cart_create(MPI_COMM_WORLD,2,Dims,Periods,1,&COMM);

MPI_Comm_rank(COMM,&gridrank);

MPI_Cart_coords(COMM,gridrank,2,Coords); 
IDi = Coords[0];	
IDj = Coords[1];
//координаты процессоов	
l[1] = Coords[1] - 1; 
l[0] = Coords[0];
r[1] = Coords[1] + 1; 
r[0] = Coords[0];
u[0] = Coords[0] - 1;
u[1] = Coords[1];
d[0] = Coords[0] + 1;
d[1] = Coords[1];

if(Coords[0]==0)
Uid = -1;
else 

MPI_Cart_rank(COMM,u,&Uid);

if(Coords[0]==maxi-1)
Did = -1;
else 		

MPI_Cart_rank(COMM,d,&Did);

if(Coords[1]==0)
Lid = -1;
else 		

MPI_Cart_rank(COMM,l,&Lid);

if(Coords[1]==maxj-1)
Rid = -1;	
else			

MPI_Cart_rank(COMM,r,&Rid);	

Hi = I/maxi;
Hj = J/maxj;
NACHi = Hi*IDi;	 
NACHj = Hj*IDj;	 

U1 = (double*)malloc((Hi+2)*(Hj+2)*sizeof(double));
U2 = (double*)malloc((Hi+2)*(Hj+2)*sizeof(double)); 
Sl = (double*)malloc((Hi+2)*sizeof(double)); 
Sr = (double*)malloc((Hi+2)*sizeof(double));
Sd = (double*)malloc((Hj+2)*sizeof(double)); 
Su = (double*)malloc((Hj+2)*sizeof(double));
Rl = (double*)malloc((Hi+2)*sizeof(double));
Rr = (double*)malloc((Hi+2)*sizeof(double)); 
Rd = (double*)malloc((Hj+2)*sizeof(double)); 
Ru = (double*)malloc((Hj+2)*sizeof(double));

//задаем начальные условия
for (i=0;i<Hi + 2;i++)	
{
for (j=0;j<Hj + 2;j++)
U1[i*(Hj+2) +j] = U_XYO(dx*(i + NACHi),dy*(j + NACHj),L);
}											

//цикл по времени
for (n=0;n<N;n++) 
{
Tau = dt*n; //шаг по времени

//значения на границах
if(IDi == 0) //верх
for(j=0;j<Hj+2;j++)
U1[j] = U_OY(dy*(j + NACHj),Tau,L);	

if(IDi == maxi - 1) //низ
for(j=0;j<Hj+2;j++) 			
U1[(Hi + 1)*(Hj + 2) + j] = U_LY(dy*(j + NACHj),Tau,L); 
if(IDj == 0)//слева
for(i=0;i<Hi+2;i++)				
U1[i*(Hj+2)] = U_XO(dx*(i + NACHi),Tau,L);
if(IDj == maxj - 1)	//справа
for(i=0;i<Hi+2;i++)				
U1[i*(Hj+2) + (Hj + 1)] = U_XL(dx*(i + NACHi),Tau,L); 

funk_vyich();
funk_trans();

if (n>0 && n%1000==0) funk_fwrite();
}

//Tau = dt*N;
//funk_napr();
funk_fwrite();

if(Myid==0) 
{ 
printf("END\nTIME = %4.4lf (sec.)\n",MPI_Wtime() -start);
fprintf(file,"np=%10d | I=J=%10d |T=%4.4f |Time=%2.3f (sec.)\n",IDi*IDj,I,T,MPI_Wtime() -start);
fclose(file);
}

free(U1); free(U2); free(Sl); free(Sr);
free(Sd); free(Su); free(Rl); free(Rr);
free(Rd); free(Ru);

MPI_File_close(&fh);
MPI_Finalize();

return 0;
}

//находит значения по пятиточечной схеме
int funk_vyich()
{
int i,j;
double l,c,r,d,u;
Temp = U1; U1 = U2; U2 = Temp;
for (i=1;i<Hi+1;i++)  
{
for (j=1;j<Hj+1;j++)
{
l = U2[(i-1)*(Hj+2) + j];
r = U2[(i+1)*(Hj+2) + j];
u = U2[i*(Hj+2) + (j+1)];
d = U2[i*(Hj+2) + (j-1)];
c = U2[i*(Hj+2) + j];  
U1[(i)*(Hj+2) + j] = dt*((Lambda((r+c)/2.0)*(r-c) - Lambda( (c+l)/2.0)*(c-l))/(dx*dx) + (Lambda( (u+c)/2.0)*(u-c) - Lambda((c+d)/2.0)*(c-d))/(dy*dy)) /(Ro©*C©)+c;
} 
}
return 1;
}


int funk_trans()
{
int i,j;

MPI_Status D;

if (IDj%2 == 0 && IDj!=maxj-1) //процесор не правый 
{
MPI_Send(U1+((Hj + 2) + Hj),  Hj, MPI_DOUBLE, Rid, gridrank+Rid+7777, COMM);	 
MPI_Recv(U1+((Hj + 2) + Hj + 1), Hj, MPI_DOUBLE, Rid, gridrank+Rid+77777, COMM, &D); 
}

if (IDj%2 != 0 && IDj!=0)//не левый
{
MPI_Recv(U1+(Hj + 2),Hj, MPI_DOUBLE, Lid, gridrank+Lid+7777, COMM, &D); 
MPI_Send(U1+(Hj + 2 + 1),Hj, MPI_DOUBLE, Lid, gridrank+Lid+77777, COMM);	 
}
if (IDj%2 != 0 && IDj!=maxj-1)
{
MPI_Send(U1+(Hj + 2 + Hj), Hj , MPI_DOUBLE, Rid, gridrank+Rid+17777, COMM);	 
MPI_Recv(U1+(Hj + 2 + Hj + 1),Hj, MPI_DOUBLE, Rid, gridrank+Rid+177777, COMM, &D); 
}

if (IDj%2 == 0 && IDj!=0) {
MPI_Recv(U1+(Hj + 2), Hj, MPI_DOUBLE, Lid, gridrank+Lid+17777, COMM, &D); 
MPI_Send(U1+(Hj + 2 + 1), Hj, MPI_DOUBLE, Lid, gridrank+Lid+177777, COMM);	 
}

if (IDi%2 == 0 && IDi!=maxi-1) 
{
MPI_Send(U1+(Hi*(Hj + 2) + 1),	Hi, MPI_DOUBLE, Did, gridrank+Did+71111, COMM);	 
MPI_Recv(U1+((Hi + 1)*(Hj + 2) + 1), Hi, MPI_DOUBLE, Did, gridrank+Did+711111, COMM, &D); 
}

if (IDi%2 != 0 && IDi!=0)
{
MPI_Recv(U1 + 1,Hi, MPI_DOUBLE, Uid, gridrank+Uid+71111, COMM, &D); 
MPI_Send(U1 + (Hj + 2 + 1),Hi, MPI_DOUBLE, Uid, gridrank+Uid+711111, COMM);	 
}

if (IDi%2 != 0 && IDi!=maxi-1) 
{
MPI_Send(U1+(Hi*(Hj + 2) + 1),Hi, MPI_DOUBLE, Did, gridrank+Did+5555, COMM);	 
MPI_Recv(U1+((Hi + 1)*(Hj + 2) + 1),Hi, MPI_DOUBLE, Did, gridrank+Did+55555, COMM, &D); 
}

if (IDi%2 == 0 && IDi!=0) 
{
MPI_Recv(U1+1,Hi, MPI_DOUBLE, Uid, gridrank+Uid+5555, COMM, &D); 
MPI_Send(U1+(Hj + 2 + 1), Hi, MPI_DOUBLE, Uid, gridrank+Uid+55555, COMM);	 
}
return 1;
}

//запись в файл для каждого процесса
int funk_fwrite()
{
int i,j;
int pp=10;	 
MPI_File_write(fh,&IDi,1,MPI_INT,NULL);
MPI_File_write(fh,&IDj,1,MPI_INT,NULL);
for (i=0;i<pp;i++)
for (j=0;j<pp;j++)
MPI_File_write(fh,U1+((1+(i*Hi)/pp)*(Hj + 2)+(1+(j*Hj)/pp)),1,MPI_DOUBLE,NULL);
return 1;
}


//ПРОГРАММА - СБОРЩИК РЕЗУЛЬТАТОВ
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
int n,ic,jc,id,i,j,np,ti=0,tj=0,t,blocks,s;
char fname[100];
double UG[100][100];

FILE *f;

if (argc<3) {np=2;t=1;} 
else {np =atoi(argv[1]);t=atoi(argv[2]);}	
printf("%d files\n",np);
blocks = 10*10*sizeof(double) + 2*sizeof(int);
for (s=0;s<t;s++)
{
printf("reading time step %d\n",s);
ti=0;tj=0;

for (id=0;id<np;id++)
{
sprintf(fname,"file_%d",id);
printf("position %d in <%s> opened, it contains ", blocks,fname);
f=fopen(fname,"r");

fseek(f,s*blocks, SEEK_SET);

fread(&ic,sizeof(int),1,f);
fread(&jc,sizeof(int),1,f);
if (ic>ti) ti=ic;
if (jc>tj) tj=jc;
printf("(%d %d)",ic,jc);
for (i=0;i<10;i++)
for (j=0;j<10;j++) 
{
fread(&(UG[ic*10+i][jc*10+j]),sizeof(double),1,f);
}
fclose(f);
printf(", <%s> closed\n",fname);
}
ti++;tj++;
printf("%d x %d\n",ti,tj);
for (i=0;i<10*ti;i++) 
{
for (j=0;j<10*tj;j++) 
printf("%8.2lf ",UG[i][j]);
printf("\n");
}
}
}
 
Статус
Закрыто для дальнейших ответов.