/******************************************************************************* Erik Erhardt Math 471 Project 3 heat.c on frontend: make heat mpirun -np 25 ./heat 1 400 5 5 mpirun -np 16 ./heat 2 400 4 4 on backend (many nodes): qsub -I -l nodes=2,walltime=900 mpirun -np 4 -machinefile $PBS_NODEFILE ./heat 2 100 2 2 qsub -I -l nodes=4,walltime=900 mpirun -np 16 -machinefile $PBS_NODEFILE ./heat 2 200 4 4 qsub -I -l nodes=7,walltime=900 mpirun -np 25 -machinefile $PBS_NODEFILE ./heat 2 200 5 5 qsub -I -l nodes=1,walltime=900 mpirun -np 1 ./heat 1 100 1 1 %%%%%%%%%%%%%%%% part 1 laplace mpirun -np 1 ./heat 1 100 1 1 mpirun -np 1 ./heat 1 200 1 1 mpirun -np 1 ./heat 1 400 1 1 mpirun -np 1 ./heat 1 800 1 1 mpirun -np 25 ./heat 1 100 5 5 mpirun -np 25 ./heat 1 200 5 5 mpirun -np 25 ./heat 1 400 5 5 mpirun -np 25 ./heat 1 800 5 5 mpirun -np 25 ./heat 1 100 1 25 mpirun -np 25 ./heat 1 200 1 25 mpirun -np 25 ./heat 1 400 1 25 mpirun -np 25 ./heat 1 800 1 25 1x1 5x5 1x25 100x100 0.0015910596 0.0015910596 0.0015910596 200x200 0.0004018149 0.0004018149 0.0004018149 400x400 0.0001009606 0.0001009606 0.0001009606 800x800 0.0000253035 0.0000253035 0.0000253035 %%%%%%%%%%%%%%%% part 2 scalability qsub -I -l nodes=7,walltime=900 mpirun -np 1 -machinefile $PBS_NODEFILE ./heat 3 200 1 1 mpirun -np 4 -machinefile $PBS_NODEFILE ./heat 3 200 2 2 mpirun -np 16 -machinefile $PBS_NODEFILE ./heat 3 200 4 4 mpirun -np 25 -machinefile $PBS_NODEFILE ./heat 3 200 5 5 mpirun -np 1 -machinefile $PBS_NODEFILE ./heat 3 200 1 1 mpirun -np 4 -machinefile $PBS_NODEFILE ./heat 3 200 1 4 mpirun -np 16 -machinefile $PBS_NODEFILE ./heat 3 200 1 16 mpirun -np 25 -machinefile $PBS_NODEFILE ./heat 3 200 1 25 %%%%%%%%%%%%%%%% part 2 contour qsub -I -l nodes=7,walltime=900 mpirun -np 25 -machinefile $PBS_NODEFILE ./heat 2 800 5 5 qsub -I -l nodes=1,walltime=900 mpirun -np 1 ./heat 2 100 1 1 *******************************************************************************/ #include #include #include #define MAX_DIM 800 int rank, rank_x, rank_y, rank_down, rank_up, rank_left, rank_right; int nprocs, nprocsx, nprocsy; int nxg, nyg, nx, ny, n; double length_x, length_y, delta_x, delta_y; double PI, h, t0, tfinal, t, time_per_step; int junk, error_flag=0, sw_method; double U[MAX_DIM+2][MAX_DIM+2], Ue[MAX_DIM+2][MAX_DIM+2], lu[MAX_DIM+2][MAX_DIM+2]; // this is our data matrix /******************************************************************************/ int main(int argc, char *argv[]){ int i, j, it; double time1, time2, timetotal, timesofar, timetogo; // time the run 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 time1 = MPI_Wtime(); // first time t1 junk = init(argc, &*argv); /*******/ // initialize values if(sw_method==2){ for (it=0; it<=n+1; it++){ if(it % ((n-1)/100) == 0) { // output grid to a file double x_out[nx]; double y_out[ny]; double u_out[nx][ny]; for (i=0; i= pow(delta_x,2)/8){if(rank==0){printf("ERROR: h >= pow(delta_x,2)/8 (%e >= %e ), EXIT\n", h, pow(delta_x,2)/8);} error_flag++;} if(error_flag>0){if(rank==0) printf("Errors = %d\n EXITING\n", error_flag); exit(0);} junk = init_local_ranks(); junk = init_block_data(); return 0; } int init_local_ranks(){ // if(rank==0) printf("nprocs x y %d %d %d\n", nprocs, nprocsx, nprocsy); // x, y rank location of current process rank_x = rank % nprocsx; // rank in x direction (mod) rank_y = rank / nprocsx; // rank in y direction (int division) /* Ranks (blocks) go in this order 6 7 8 3 4 5 0 1 2 */ // ranks of neighboring processors rank_down = (rank_y-1)*nprocsx + rank_x ; if(rank_y == 0 ) rank_down = -1; rank_up = (rank_y+1)*nprocsx + rank_x ; if(rank_y == nprocsy-1) rank_up = -1; rank_left = rank_y *nprocsx + rank_x-1; if(rank_x == 0 ) rank_left = -1; rank_right = rank_y *nprocsx + rank_x+1; if(rank_x == nprocsx-1) rank_right = -1; //printf("Ranks: me, x, y, up, down, left, right: %d %d %d %d %d %d %d \n", rank, rank_x, rank_y, rank_up, rank_down, rank_left, rank_right); return 0; } int init_block_data(){ int i, j; double b, initx[nx+2], inity[nx+2], pi2; /* Data goes in this order per block (border is ghost cells): 0 1 2 3 4 ... nx+1 1 2 ... ... ny+1 */ for (i=0; i= '0' && *digit <='9') { result = (result * 10) + (*digit - '0'); digit++; } //--- Check that there were no non-digits at end. if (*digit != 0) {return -1;} return result; } /* output data from M471 heat equation problem input: nx number of interior points, x direction ny number of interior points, y direction x[nx] x coordinates of interior points y[ny] y coordinates of interior points u[nx][ny] solution at interiod points time Note: the inputs to this routine are vectors which only contain interior points - no ghost points. But this routine only accepts arrays of size u[nx][ny]. For example, if you are following the convention I used in class, the u array will be something like: u[nx+2][ny+2]. where the interior points are: u[2:nx+1][2:ny+1] and the ghost cells are u[1][:],u[nx+2][:], etc... so when calling this routine, in C you should first create new arrays: then copy the *interior* data only into these arrays, and then call this routine: double xoutput[nx],youtput[ny],uoutput[nx][ny] for (i=0; i