C programs for 22S:295, Oct.4, 2007 /* template.c -- template for C program using MPI */ #include #include "mpi.h" main(int argc, char* argv[]) { int my_rank; /* rank of process */ int p; /* number of processes */ /* Start up MPI; must precede any calls to MPI funcs */ MPI_Init(&argc, &argv); /* Find out process rank */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* Find out number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &p); /* code to do work, using MPI */ /* Shut down MPI; no more MPI funcs afterward */ MPI_Finalize(); } /* main */ ------------------------------------------------------------------------ /* ping.c -- illustrates: blocking send and receive /* SPMD /* MPI_Status structure /* from LLNL tutorial */ #include "mpi.h" #include int main(argc,argv) int argc; char *argv[]; { int numtasks, rank, dest, source, rc, count, tag=1; char inmsg, outmsg='x'; MPI_Status Stat; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { dest = 1; source = 1; rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat); } else if (rank == 1) { dest = 0; source = 0; rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat); rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); } rc = MPI_Get_count(&Stat, MPI_CHAR, &count); printf("Task %d: Received %d char(s) from task %d with tag %d \n", rank, count, Stat.MPI_SOURCE, Stat.MPI_TAG); MPI_Finalize(); } --------------------------------------------------------------------------- /* greetingsm.c -- greetings program * * Send a message from all processes with rank != 0 to process 0. * Process 0 prints the messages received. * * Input: none. * Output: contents of messages received by process 0. * * See Chapter 3, pp. 41 & ff in PPMPI. * Modified by MKC. */ #include #include #include "mpi.h" main(int argc, char* argv[]) { int rc ; /* code returned by MPI_Init */ int my_rank; /* rank of process */ int p; /* number of processes */ int source; /* rank of sender */ int dest; /* rank of receiver */ int tag = 0; /* tag for messages */ int namelen ; /* length of processor name */ char processor_name[MPI_MAX_PROCESSOR_NAME] ; char message[MPI_MAX_PROCESSOR_NAME + 60]; /* storage for message */ MPI_Status status; /* return status for */ /* receive */ /* Start up MPI */ /* MPI_Init(&argc, &argv); */ rc = MPI_Init(&argc,&argv); if (rc != MPI_SUCCESS) { printf ("Error starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } /* Find out process rank */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* Find out number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &p); /* Find out processor name and namelength */ MPI_Get_processor_name( processor_name, &namelen ) ; if (my_rank != 0) { /* Create message */ sprintf(message, "Greetings from process %d on %s!", my_rank, processor_name ); dest = 0; /* Use strlen+1 so that '\0' gets transmitted */ MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); } else { /* my_rank == 0 */ for (source = 1; source < p; source++) { MPI_Recv(message, sizeof( message ), MPI_CHAR, source, tag, MPI_COMM_WORLD, &status); printf("%s\n", message); } } /* Shut down MPI */ MPI_Finalize(); } /* main */ --------------------------------------------------------------------------- /* scatterrows.c */ /* from LLNL tutorial */ #include "mpi.h" #include #define SIZE 4 int main(argc,argv) int argc; char *argv[]; { int numtasks, rank, sendcount, recvcount, source; float sendbuf[SIZE][SIZE] = { {1.0, 2.0, 3.0, 4.0}, {5.0, 6.0, 7.0, 8.0}, {9.0, 10.0, 11.0, 12.0}, {13.0, 14.0, 15.0, 16.0} }; float recvbuf[SIZE]; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); if (numtasks == SIZE) { source = 1; sendcount = SIZE; recvcount = SIZE; MPI_Scatter(sendbuf,sendcount,MPI_FLOAT,recvbuf,recvcount, MPI_FLOAT,source,MPI_COMM_WORLD); printf("rank= %d Results: %f %f %f %f\n",rank,recvbuf[0], recvbuf[1],recvbuf[2],recvbuf[3]); } else printf("Must specify %d processors. Terminating.\n",SIZE); MPI_Finalize(); } -------------------------------------------------------------- /* reduce.c -- Parallel Trapezoidal Rule. Uses 3 calls to MPI_Bcast to * distribute input. Also uses MPI_Reduce to compute final sum. * * Input: * a, b: limits of integration. * n: number of trapezoids. * Output: Estimate of the integral from a to b of f(x) * using the trapezoidal rule and n trapezoids. * * Notes: * 1. f(x) is hardwired. * 2. the number of processes (p) should evenly divide * the number of trapezoids (n). * * See Chap. 5, pp. 73 & ff. in PPMPI. */ #include /* We'll be using MPI routines, definitions, etc. */ #include "mpi.h" main(int argc, char** argv) { int my_rank; /* My process rank */ int p; /* The number of processes */ float a; /* Left endpoint */ float b; /* Right endpoint */ int n; /* Number of trapezoids */ float h; /* Trapezoid base length */ float local_a; /* Left endpoint my process */ float local_b; /* Right endpoint my process */ int local_n; /* Number of trapezoids for */ /* my calculation */ float integral; /* Integral over my interval */ float total; /* Total integral */ int source; /* Process sending integral */ int dest = 0; /* All messages go to 0 */ int tag = 0; MPI_Status status; void Get_data2(float* a_ptr, float* b_ptr, int* n_ptr, int my_rank); float Trap(float local_a, float local_b, int local_n, float h); /* Calculate local integral */ /* Let the system do what it needs to start up MPI */ MPI_Init(&argc, &argv); /* Get my process rank */ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /* Find out how many processes are being used */ MPI_Comm_size(MPI_COMM_WORLD, &p); Get_data2(&a, &b, &n, my_rank); h = (b-a)/n; /* h is the same for all processes */ local_n = n/p; /* So is the number of trapezoids */ /* Length of each process' interval of * integration = local_n*h. So my interval * starts at: */ local_a = a + my_rank*local_n*h; local_b = local_a + local_n*h; integral = Trap(local_a, local_b, local_n, h); /* Add up the integrals calculated by each process */ MPI_Reduce(&integral, &total, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD); /* Print the result */ if (my_rank == 0) { printf("With n = %d trapezoids, our estimate\n", n); printf("of the integral from %f to %f = %f\n", a, b, total); } /* Shut down MPI */ MPI_Finalize(); } /* main */ /********************************************************************/ /* Function Get_data2 * Reads in the user input a, b, and n. * Input parameters: * 1. int my_rank: rank of current process. * 2. int p: number of processes. * Output parameters: * 1. float* a_ptr: pointer to left endpoint a. * 2. float* b_ptr: pointer to right endpoint b. * 3. int* n_ptr: pointer to number of trapezoids. * Algorithm: * 1. Process 0 prompts user for input and * reads in the values. * 2. Process 0 sends input values to other * processes using three calls to MPI_Bcast. */ void Get_data2( float* a_ptr /* out */, float* b_ptr /* out */, int* n_ptr /* out */, int my_rank /* in */) { if (my_rank == 0) { printf("Enter a, b, and n\n"); scanf("%f %f %d", a_ptr, b_ptr, n_ptr); } MPI_Bcast(a_ptr, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(b_ptr, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(n_ptr, 1, MPI_INT, 0, MPI_COMM_WORLD); } /* Get_data2 */ /********************************************************************/ float Trap( float local_a /* in */, float local_b /* in */, int local_n /* in */, float h /* in */) { float integral; /* Store result in integral */ float x; int i; float f(float x); /* function we're integrating */ integral = (f(local_a) + f(local_b))/2.0; x = local_a; for (i = 1; i <= local_n-1; i++) { x = x + h; integral = integral + f(x); } integral = integral*h; return integral; } /* Trap */ /********************************************************************/ float f(float x) { float return_val; /* Calculate f(x). */ /* Store calculation in return_val. */ return_val = x*x; return return_val; } /* f */