Lab03_mpi Compiling: mpicc -o hello hello.c 1. Running: mpirun -np 2 hello File /usr/lib/mpich/share/machines.LINUX on yapok should look like: yapok hydra ... 2. Running from yapok: ./hello -p4pg processors File processors on your directory on yapok should look like: yapok 0 hydra 1 /home/scicomp/your_username/mpi/hello ... ***************************************************************************** 1. Exercise - Getting Started Objective: Learn how to login, write, compile, and run a simple MPI program. -Run the ``Hello world'' programs. -Try two or more different processes. -Try two or more different parallel computers. -What does the output look like? -Try to improve your program to give you the information on the outputting process (rank and processor name). Code: #include "mpi.h" #include int main( int argc, char *argv[] ) { char name[100]; int len; MPI_Init( &argc, &argv ); // MPI_Get_processor_name(name, &len); // printf( "Hello, world from %s!\n", name ); printf( "Hello, world!\n" ); MPI_Finalize(); return 0; } ***************************************************************************** 2. Exercise - Analysing Status Objective: translate Fortran code to C, understand what Status mean. -Translate, compile and run the Fortran example. -Explain how the program works. -Interprete results. Code: program main include 'mpif.h' integer rank, size, to, from, tag, count, i, ierr integer src, dest integer st_source, st_tag, st_count integer status(MPI_STATUS_SIZE) double precision data(100) call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, rank, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, size, ierr ) print *, 'Process ', rank, ' of ', size, ' is alive' dest = size - 1 src = 0 C if (rank .eq. src) then to = dest count = 10 tag = 2001 do 10 i=1, 10 10 data(i) = i call MPI_SEND( data, count, MPI_DOUBLE_PRECISION, to, + tag, MPI_COMM_WORLD, ierr ) else if (rank .eq. dest) then tag = MPI_ANY_TAG count = 10 from = MPI_ANY_SOURCE call MPI_RECV(data, count, MPI_DOUBLE_PRECISION, from, + tag, MPI_COMM_WORLD, status, ierr ) call MPI_GET_COUNT( status, MPI_DOUBLE_PRECISION, + st_count, ierr ) st_source = status(MPI_SOURCE) st_tag = status(MPI_TAG) C print *, 'Status info: source = ', st_source, + ' tag = ', st_tag, ' count = ', st_count print *, rank, ' received', (data(i),i=1,10) endif call MPI_FINALIZE( ierr ) end ***************************************************************************** 3. Exercise - PI Collective communication Objective: Experiment with send/receive and Bcast/Reduce -Study and Run the program for PI. -Explanation on how the algorithm works: This exercise presents a simple program to determine the value of pi. The algorithm suggested here is chosen for its simplicity. The method evaluates the integral of 4/(1+x*x) between -1/2 and 1/2. The method is simple: the integral is approximated by a sum of n intervals; the approximation to the integral in each interval is (1/n)*4/(1+x*x). The master process (rank 0) asks the user for the number of intervals; the master should then broadcast this number to all of the other processes. Each process then adds up every n'th interval (x = -1/2+rank/n, -1/2+rank/n+size/n,...). Finally, the sums computed by each process are added together using a reduction. -Write new versions that replace the calls to MPI_Bcast and MPI_Reduce with MPI_Send and MPI_Recv. Test this program. -The MPI broadcast and reduce operations use at most log(p) send and receive operations on each process where p is the size of MPI_COMM_WORLD. How many operations do your versions use? Code: #include "mpi.h" #include int main(argc,argv) int argc; char *argv[]; { int done = 0, n, myid, numprocs, i, rc; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x, a; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); while (!done) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); } MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); if (n == 0) break; h = 1.0 / (double) n; sum = 0.0; for (i = myid + 1; i <= n; i += numprocs) { x = h * ((double)i - 0.5); sum += 4.0 / (1.0 + x*x); } mypi = h * sum; MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (myid == 0) printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); } MPI_Finalize(); } ***************************************************************************** 4. Exercise - MPI Exercises - open page: http://www-unix.mcs.anl.gov/mpi/tutorial/mpiexmpl/ and run start the excercises: 1. Getting started with "Hello World” 2. Sharing data; Using MPI datatypes to share data 3. Sending in a ring (broadcast by ring) 4. Finding PI using MPI collective operations 5. Fairness in message passing and related exercise: Implementing Fairness using Waitsome 6. A simple Jacobi iteration 7. Master/slave programs and related exercise: Simple I/O server in MPI.