/******************************************************************************* Erik Erhardt Math 471 Testing MPI_Isend and MPI_Irecv on frontend: make nbody mpirun -np 4 ./nbody on backend (many nodes): qsub -I -l nodes=7,walltime=900 mpirun -np 28 -machinefile $PBS_NODEFILE ./nbody qsub -I -l nodes=3,walltime=900 mpirun -np 12 -machinefile $PBS_NODEFILE ./nbody *******************************************************************************/ /******************************************************************************* Times: h=0.001 t=0.000000, H_rel_error= 0.000000 t=0.200000, H_rel_error=-0.000012 t=0.400000, H_rel_error=-0.000021 t=0.600000, H_rel_error=-0.000027 time=2282.582404, time_per_step=3.797974 h=0.0007 t=0.000000, H_rel_error= 0.000000 t=0.200200, H_rel_error=-0.000006 t=0.400400, H_rel_error=-0.000009 t=0.600600, H_rel_error=-0.000011 time=3262.199582, time_per_step=3.797671 *******************************************************************************/ #include #include // 400 or 5600 #define NBODY 5600 double PI; double t, x[NBODY*2]; double xprime[NBODY*2], x_rhs_temp[NBODY*2]; double dx_r[NBODY], dy_r[NBODY]; // ring double h, t0, tfinal, time_per_step; int n; int sw_method, sw_output, sw_scalability, sw_scale_iter=0; double delta; int Nl, tag=0; // Nl=number of points per proc int lower, upper; int rank, nprocs; int main(int argc, char *argv[]){ int i, j; double time1, time2, timetotal; // time the run int junk; MPI_Init(&argc,&argv); // initialize MPI MPI_Comm_rank(MPI_COMM_WORLD, &rank); // my rank number MPI_Comm_size(MPI_COMM_WORLD, &nprocs); // number of processes Nl=NBODY/nprocs; // number per process if (rank==0) printf("NBODY=%d, Nl=%d\n", NBODY, Nl); junk = init(); /*******/ // initialize values if ( sw_scalability==1) { if (rank==0) printf("Scalability time trial using nprocs=%d, sw_scale_iter=%d\n", nprocs, sw_scale_iter); } time1 = MPI_Wtime(); // first time t1 if (sw_method==0){ junk = rk2_fluid(); } // allgather time step if (sw_method==1){ junk = rk2_ring_fluid(); } // ring time step time2 = MPI_Wtime(); // first time t1 timetotal = time2 - time1; // total time is difference if (sw_scale_iter > 0) n=sw_scale_iter; time_per_step = timetotal/n; if (rank==0) printf("time=%f, time_per_step=%f\n", timetotal, time_per_step); MPI_Finalize(); } /* init *****************************************/ int init(){ double Gamma, alpha; int j; lower = rank*Nl; upper = (rank+1)*Nl; // printf("rank=%d, lower=%d, upper=%d\n",rank,lower,upper); PI=4*atan( (double)1 ); // known value of pi sw_method = 1; // 0 all_gather, 1 ring sw_output = 1; // 0 no output, 1 output to screen and file sw_scalability = 0; if ( sw_scalability==1) { sw_output = 0; sw_scale_iter = 20; } //Warm-up init NBODY=400 /* h=0.1; t0=0.0; tfinal=4.0; n = ceil((tfinal-t0)/h)+1; // number of timesteps delta=0.25; alpha = 0.01; */ // Project init NBODY=5600 h=0.0007; t0=0.0; tfinal=0.6; n = ceil((tfinal-t0)/h)+1; // number of timesteps delta=0.04; alpha = 0.15; // for(j=0; j= 0.2 && t < 0.2+h) || (t >= 0.4 && t < 0.4+h) || (i == n-1) ) { // H energy ************************** PI2=pow(PI,2);delta2=pow(delta,2); H_sum=0; H_final=0; for (j1=lower; j1= 20) {i=n+1;} } // finish i loop if(sw_output==1){ if(i==1) printf("i=%d\n",i);} /* send results to all processes ***************/ for (j=lower; jnprocs-1) sendto=0; // send to next recvfrom = rank-1; if(recvfrom<0) recvfrom=nprocs-1; // recv from previous // printf("rank=%d, sendto=%d, recvfrom=%d\n", rank, sendto, recvfrom); // for(j=0;j<2*NBODY;j++){x[j]=rank;} //testing for (j=lower; j= 0.2 && t < 0.2+h) || (t >= 0.4 && t < 0.4+h) || (i == n-1) ) { // // H energy ************************** // PI2=pow(PI,2);delta2=pow(delta,2); // H_sum=0; H_final=0; // for (j1=0; j10){ // THIS CODE IS THE RING METHOD for (j=0; j<2*Nl; j++) {x_rem_tosend[j]=x_rem[j];} // local values to send ierr1 = MPI_Irecv(&x_rem, 2*Nl, MPI_DOUBLE, recvfrom, tag, MPI_COMM_WORLD, &rreq);if (ierr1 != MPI_SUCCESS) printf("MPI_Irecv ERROR status %d.\n", ierr1); ierr2 = MPI_Isend(&x_rem_tosend, 2*Nl, MPI_DOUBLE, sendto, tag, MPI_COMM_WORLD, &sreq);if (ierr2 != MPI_SUCCESS) printf("MPI_Isend ERROR status %d.\n", ierr2); ierr3 = MPI_Wait(&rreq, &status); if (ierr3 != MPI_SUCCESS) printf("MPI_Wait ERROR status %d.\n", ierr3); // } for (j=0; j0){ // THIS CODE IS THE RING METHOD for (j=0; j<2*Nl; j++) {x_rem_tosend[j]=x_rem[j];} // local values to send ierr1 = MPI_Irecv(&x_rem, 2*Nl, MPI_DOUBLE, recvfrom, tag, MPI_COMM_WORLD, &rreq);if (ierr1 != MPI_SUCCESS) printf("MPI_Irecv ERROR status %d.\n", ierr1); ierr2 = MPI_Isend(&x_rem_tosend, 2*Nl, MPI_DOUBLE, sendto, tag, MPI_COMM_WORLD, &sreq);if (ierr2 != MPI_SUCCESS) printf("MPI_Isend ERROR status %d.\n", ierr2); ierr3 = MPI_Wait(&rreq, &status); if (ierr3 != MPI_SUCCESS) printf("MPI_Wait ERROR status %d.\n", ierr3); //} for (j=0; j= 20) {i=n+1;} } // finish i loop //for (j=0; j