/* Jonathan Hauenstein - University of Notre Dame Center for Applied Mathematics Minicourse on Parallel Computing April 24, May 1, May 8, 2008 Sample programs are designed for educational use */ #include "trapezoid.h" #include void create_trapInfo(MPI_Datatype *mpi_trapInfo) { // create the MPI datatype mpi_trapInfo MPI_Aint sAdd, add; trapInfo A; // arrays for length, displacement and datatypes int blockLen[3] = {1,1,1}; // 1 element in each block MPI_Datatype types[3] = {MPI_INT, MPI_DOUBLE, MPI_DOUBLE}; MPI_Aint indices[3] = {0,0,0}; // calculate the starting address MPI_Address(&A.n, &sAdd); // calculate the second address and compute the displacement MPI_Address(&A.a, &add); indices[1] = add - sAdd; // calculate the third address and compute the displacement MPI_Address(&A.b, &add); indices[2] = add - sAdd; // build the mpi datatype MPI_Type_struct(3, blockLen, indices, types, mpi_trapInfo); // commit the mpi datatype MPI_Type_commit(mpi_trapInfo); return; } void setup_my_info(trapInfo *my_info, double a, double b, int totalTrap, int my_id, int num_proc) { // setup my_info - if my_id == 0, distribute, otherwise, wait to recv MPI_Datatype mpi_trapInfo; MPI_Status status; // setup mpi_trapInfo create_trapInfo(&mpi_trapInfo); if (my_id == 0) { // split up the trapezoids equally between the other processes int i, trap_per_proc = totalTrap / num_proc; double stepSize = 0; trapInfo send_info; // find the number of trapezoids left over that will be computed on id 0 my_info->n = totalTrap - trap_per_proc * (num_proc - 1); // find the step size and setup the rest of my_info for id 0 stepSize = (b - a) / totalTrap; my_info->a = a; my_info->b = a + my_info->n * stepSize; // initialize send_info for the loop send_info.n = trap_per_proc; send_info.a = my_info->a; send_info.b = my_info->b; // send information out to the other processes for (i = 1; i < num_proc; i++) { // setup send_info send_info.a = send_info.b; send_info.b = send_info.a + send_info.n * stepSize; // send it MPI_Send(&send_info, 1, mpi_trapInfo, i, 0, MPI_COMM_WORLD); } } else { // recv my_info MPI_Recv(my_info, 1, mpi_trapInfo, 0, 0, MPI_COMM_WORLD, &status); } // clear mpi_trapInfo MPI_Type_free(&mpi_trapInfo); return; }