// Main function int main(int argc, char** argv){ int n;// Number of total particles struct Particle *locals, *refs;// Array of local particles char *file_name;// File name // checking the number of parameters if(argc < 2){ printf("ERROR: Not enough parameters\n"); printf("Usage: %s <number of particles> [<file>]\n", argv[0]); exit(1); } // getting number of particles n = atoi(argv[1]); srand(CONSTANT); // acquiring memory for particle arrays locals = (struct Particle *) malloc(n * sizeof(struct Particle)); // checking for file information if(argc == 3){ read_file(locals,n,argv[2]); refs = (struct Particle *) malloc(n * sizeof(struct Particle)); //read_ref(refs,n,"test_results_1.txt"); } else { // random initialization of local particle array for(int j = 0; j < n; j++){ locals[j].x = random_value(POSITION); locals[j].y = random_value(POSITION); locals[j].mass = MASS; locals[j].fx = 0.0; locals[j].fy = 0.0; } } // starting timer timerStart(); // particle interaction compute_self_interaction(locals,n); // stopping timer double duration = timerStop(); // printing information on particles if(argc == 3) { /*bool Right = CheckResult(locals,refs,n); if(Right){ printf("Result correct!\n"); }else{ printf("Results are wrong!\n"); }*/ print_particles(locals,n); } printf("n=%d\tDuration: %f seconds\n", n,duration); //printf("Duration: %f seconds\n", duration); free(refs); }
// Main function int main(int argc, char** argv){ int myRank;// Rank of process int p;// Number of processes int n;// Number of total particles int previous;// Previous rank in the ring int next;// Next rank in the ring int tag = TAG;// Tag for message int number;// Number of local particles int count_mpi; struct Particle *globals;// Array of all particles in the system struct Particle *locals;// Array of local particles struct Particle *remotes;// Array of foreign particles char *file_name;// File name MPI_Status status;// Return status for receive int j, rounds, initiator, sender; double start_time, end_time; // checking the number of parameters if(argc < 2){ printf("ERROR: Not enough parameters\n"); printf("Usage: %s <number of particles> [<file>]\n", argv[0]); exit(1); } // getting number of particles n = atoi(argv[1]); // initializing MPI structures and checking p is odd MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myRank); MPI_Comm_size(MPI_COMM_WORLD, &p); if(p % 2 == 0){ p = p - 1; if(myRank == p){ MPI_Finalize(); return 0; } } srand(myRank+myRank*CONSTANT); // acquiring memory for particle arrays //**changed to make it right******* number = ceil(1.0 * n / p); locals = (struct Particle *) calloc(number , sizeof(struct Particle)); remotes = (struct Particle *) calloc(number , sizeof(struct Particle)); // checking for file information if(argc == 3){ if(myRank == 0){ globals = (struct Particle *) calloc((ceil((double)n/p))*p , sizeof(struct Particle)); // YOUR CODE GOES HERE (reading particles from file) read_file(globals, n, argv[2]); } // To send/recv (or scatter/gather) you will need to learn how to // transfer structs of floats, treat it as a contiguous block of // floats. Here is an example: // MPI_Send(locals, // number * (sizeof (struct Particle)) / sizeof(float), // MPI_FLOAT, // next_rank, // tag, // MPI_COMM_WORLD) // MPI_Recv(remotes, // number * (sizeof (struct Particle)) / sizeof(float), // MPI_FLOAT, // previous_rank, // tag, // MPI_COMM_WORLD, // &status); // hint: because your nodes need to both send and receive you // might consider asyncronous send/recv. // YOUR CODE GOES HERE (distributing particles among processors) count_mpi = number * (sizeof(struct Particle)) /sizeof(float); MPI_Scatter(globals, count_mpi, MPI_FLOAT, locals, count_mpi, MPI_FLOAT, 0, MPI_COMM_WORLD); } else { // random initialization of local particle array for(j = 0; j < number; j++){ locals[j].x = random_value(POSITION); locals[j].y = random_value(POSITION); locals[j].fx = 0.0; locals[j].fy = 0.0; locals[j].mass = MASS; } } // starting timer if(myRank == 0){ start_time = MPI_Wtime(); } // YOUR CODE GOES HERE (ring algorithm) MPI_Request request_send[4]; int nextRank = (myRank + 1) % p; int prevRank = (myRank - 1 + p) % p; MPI_Isend(locals, count_mpi, MPI_FLOAT, nextRank, tag, MPI_COMM_WORLD, &request_send[0]); MPI_Recv(remotes, count_mpi, MPI_FLOAT, prevRank, tag, MPI_COMM_WORLD, &status); compute_interaction(locals, remotes, number); MPI_Isend(remotes, count_mpi, MPI_FLOAT, nextRank, tag, MPI_COMM_WORLD, &request_send[1]); for(int i=1; i<(p-1)/2; i++){ MPI_Recv(remotes, count_mpi, MPI_FLOAT, prevRank, tag, MPI_COMM_WORLD, &status); compute_interaction(locals, remotes, number); MPI_Isend(remotes, count_mpi, MPI_FLOAT, nextRank, tag, MPI_COMM_WORLD, &request_send[2]); } int OG_rank = ((myRank - (p-1)/2 + p) % p); //maybe call get_OG_rank function here and not sure where to increment rank_count int final_rank = ((myRank + (p-1)/2 + p) % p); //send remote back to original process MPI_Isend(remotes, count_mpi, MPI_FLOAT, OG_rank, tag, MPI_COMM_WORLD, &request_send[3]); MPI_Recv(remotes, count_mpi, MPI_FLOAT, final_rank, tag, MPI_COMM_WORLD, &status); merge(locals, remotes, number); compute_self_interaction(locals, number); //not sure about second parameter ****** //Step 8 of algo MPI_Barrier(MPI_COMM_WORLD); //*********************************double check this**** // stopping timer if(myRank == 0){ end_time = MPI_Wtime(); printf("Duration: %f seconds\n", (end_time-start_time)); } // printing information on particles if(argc == 3){ // YOUR CODE GOES HERE (collect particles at rank 0) count_mpi = number * (sizeof(struct Particle)) /sizeof(float); MPI_Gather(locals, count_mpi, MPI_FLOAT, globals, count_mpi, MPI_FLOAT, 0, MPI_COMM_WORLD); if(myRank == 0) { print_particles(globals,n); } } // finalizing MPI structures MPI_Finalize(); }