Information Technology Reference
In-Depth Information
u_prev = (double * )malloc((n_p+2) * sizeof(double));
u = (double * )malloc((n_p+2) * sizeof(double));
for (i=0; i<=n_p+1; i++) / * enforce initial condition * /
u_prev[i] = I((i_start_p+i) * dx);
left_neighbor_id = (my_id==0) ? MPI_PROC_NULL : my_id-1;
right_neighbor_id = (my_id==P-1) ? MPI_PROC_NULL : my_id+1;
t=0.;
for (k=1; k<=m; k++) { / * time integration loop * /
for (i=1; i<=n_p; i++) / * computing local inner points * /
u[i] = u_prev[i]+alpha * (u_prev[i-1]-2 * u_prev[i]+u_prev[i+1])
+dt * f((i_start_p+i) * dx,t);
if (my_id==0)
/ * left physical boundary condition * /
u[0] = D0(t+dt);
if (my_id==P-1) / * right physical boundary condition * /
u[n_p+1] = u_prev[n_p+1]
+2 * alpha * (u_prev[n_p]-u_prev[n_p+1]+N1(t) * dx)
+dt * f(1,t);
MPI_Sendrecv(&(u[1]),1,MPI_DOUBLE,left_neighbor_id,100,
&(u[n_p+1]),1,MPI_DOUBLE,right_neighbor_id,100,
MPI_COMM_WORLD,&status);
MPI_Sendrecv(&(u[n_p]),1,MPI_DOUBLE,right_neighbor_id,200,
&(u[0]),1,MPI_DOUBLE,left_neighbor_id,200,
MPI_COMM_WORLD,&status);
for (i=0; i<=n_p+1; i++)/ * date copy before next time step * /
u_prev[i] = u[i];
t+=dt;
}
MPI_Finalize();
return 0;
}
We can see that the above code uses a slightly modified Algorithm 10.1 ,in
that two calls to the MPI Sendrecv function replace two pairs of MPI Send and
MPI Recv . The modified code is thus more compact. A more important motivation
for the modification is to avoid potential communication deadlocks , which will arise
if a pair of neighboring processes both start with MPI Recv before calling the match-
ing MPI Send command. These two MPI processes will be blocked, i.e., none will
be able to return from its MPI Recv call, which relies on its neighbor to have issued
the MPI Send call. A bullet-proof sequence of MPI Send and MPI Recv calls is that
process A calls MPI Send and MPI Recv , whereas process B calls MPI Recv and
MPI Send .
 
Search WWH ::




Custom Search