/******************************************************** % % Written by: % -- % John L. Weatherwax 2006-05-29 % % email: wax@alum.mit.edu % % Please send comments and especially bug reports to the % above email address. % %----- An attempt at a MPI implementation of a 2-D version of the Midpoint Method for Parallelization of Particle Simulations by Kevin J. Bowers, Ron O. Dror, and David E. Shaw. */ #include #include #include #include #include "mpi.h" #include "global_grid.h" #include "sim_consts.h" #include "parseInputArgs.h" #include "fillSimConsts.h" #include "doInitialGridConstruction.h" #include "saveParticles.h" #include "determineExportRegion.h" #include "packageParticlesForMPISends.h" #include "exhangeNumberOfParticlesToSend.h" #include "createSpaceForParticlesToReceive.h" #include "exportParticles.h" #include "computeShortRangeForces.h" #include "createSpaceForForcesToReceive.h" #include "exportForces.h" #include "updatePositions.h" #include "determineEvictedParticles.h" #include "packageEvictedForMPISends.h" #include "exhangeNumberOfParticlesToEvict.h" #include "createSpaceForEvictedParticlesToReceive.h" #include "evictParticles.h" #include "updateHomeParticles.h" #include "freeParticleExhangeMemory.h" #include "supplyDebuggingInitialConditions.h" #include "printProcInfo.h" double sim_time,dt=1.0; sim_consts simConsts; proc_info procInfo; extern int main(int argc, char* argv[]){ int NP,Ms,Ns,NbPP,Nts,my_rank; MPI_Status status; int tsi; double start,finish; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &NP); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* Set evil seed (initial seed) */ /*srand((unsigned)0);*/ srand((unsigned)my_rank); /*srand((unsigned)time(NULL));*/ /*srand((unsigned)(my_rank+time(NULL)));*/ if( my_rank==0 ) parseInputArgs(argc,argv,NP,&Ms,&Ns,&NbPP,&Nts); MPI_Bcast(&Ms, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&Ns, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&NbPP, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&Nts, 1, MPI_INT, 0, MPI_COMM_WORLD); /* add timing hooks */ MPI_Barrier(MPI_COMM_WORLD); start = MPI_Wtime(); fillSimConsts(); /* Perform any initial bookkeeping to set up data structures. */ doInitialGridConstruction(NP,my_rank,Ms,Ns,NbPP); sim_time=0.0; /* some simple initial conditions for debugging my code ... */ /*supplyDebuggingInitialConditions();*/ /* save all particles to disk so that we can check algorithm correctness */ saveParticles(my_rank,0); for( tsi=1; tsi <= Nts; tsi++ ){ /*printf("my_rank=%d: performing timestep #%d...\n",my_rank,tsi);*/ /* initialize how many total particles (to zeros) I will send to each of my neighbors */ initializeNumToExport(); /* tag the particles which I will export to my neighbors */ determineExportRegion(); /* print the number of particles I will export to each of my neighbors */ printf("my_rank=%d, should export=(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",my_rank, procInfo.numToExport[0],procInfo.numToExport[1],procInfo.numToExport[2], procInfo.numToExport[3],procInfo.numToExport[4],procInfo.numToExport[5], procInfo.numToExport[6],procInfo.numToExport[7],procInfo.numToExport[8]); /* ---PERFORM PARTICLE EXPORTS--- */ /* create memory to for the particles I will export and copy the particles to export into them */ packageParticlesForMPISends(); /* inform my neighbor of the number of particles I will be sending (just the number of them not the data) */ exhangeNumberOfParticlesToSend(); /* print the number of particles I will be receiving from my neighbors */ printf("my_rank=%d, should receive=(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",my_rank, procInfo.numToReceive[0],procInfo.numToReceive[1],procInfo.numToReceive[2], procInfo.numToReceive[3],procInfo.numToReceive[4],procInfo.numToReceive[5], procInfo.numToReceive[6],procInfo.numToReceive[7],procInfo.numToReceive[8]); /* create space for all the particles I will receive */ createSpaceForParticlesToReceive(); /* perform message passing to exchange all particle data */ exportParticles(); /* ---PARTICLES NOW EXPORTED--- */ /* using all particles I now compute forces */ computeShortRangeForces(tsi); /* create space for the forces I will be receiving from my neighbors, calculated on the particles I exported to them */ createSpaceForForcesToReceive(); /* perform message passing to exhange all force data */ exportForces(); /***** A long range force calculation will go here ... *****/ /* update the positions of each particle */ updatePositions(tsi,dt); /* find any particles that will leave their home in this timestep */ determineEvictedParticles(); /* print the number of particles I will export to each of my neighbors */ printf("my_rank=%d, should evict=(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",my_rank, procInfo.numToEvict[0],procInfo.numToEvict[1],procInfo.numToEvict[2], procInfo.numToEvict[3],procInfo.numToEvict[4],procInfo.numToEvict[5], procInfo.numToEvict[6],procInfo.numToEvict[7],procInfo.numToEvict[8]); /* ---PERFORM PARTICLE EVICTIONS--- */ /* create memory to for the particles I will evict and copy the particles to export into them */ packageEvictedForMPISends(); /* inform my neighbor of the number of particles I will be evicting (just the number of them not the data) */ exhangeNumberOfParticlesToEvict(); /*break; */ /* print the number of particles I will be receiving from my neighbors */ printf("my_rank=%d, should receive refugees=(%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",my_rank, procInfo.numRefugeeToReceive[0],procInfo.numRefugeeToReceive[1],procInfo.numRefugeeToReceive[2], procInfo.numRefugeeToReceive[3],procInfo.numRefugeeToReceive[4],procInfo.numRefugeeToReceive[5], procInfo.numRefugeeToReceive[6],procInfo.numRefugeeToReceive[7],procInfo.numRefugeeToReceive[8]); /* create space for all the evicted particles I will receive */ createSpaceForEvictedParticlesToReceive(); /* export the particles that have moved */ evictParticles(); /* ---PARTICLES NOW EVICTED--- */ /* update the home data structure to account for the evicted particles and the newly received ones */ updateHomeParticles(); /* free all memory used for the above particle exhanges */ freeParticleExhangeMemory(); /* save all particles to disk so that we can check algorithm correctness */ saveParticles(my_rank,tsi); /* update the global simulation time */ sim_time+=dt; /* not needed ... just for debugging ... */ MPI_Barrier(MPI_COMM_WORLD); } /* add timing hooks */ MPI_Barrier(MPI_COMM_WORLD); finish = MPI_Wtime(); if( procInfo.my_rank==0 ){ /* save the file to disk */ FILE *fp; char output[100]; sprintf(output,"ParSimResults/parallel_timing_%d_%d_%d_%d.dat",Ms,Ns,NbPP,Nts); fp = fopen(output, "w"); if( !fp ){ MPI_Abort(MPI_COMM_WORLD,1); } fprintf(fp,"elapsed time = %10.6f seconds\n", finish-start); fclose(fp); } MPI_Finalize(); }