# include # include # include # include int main ( int argc, char *argv[] ); void timestamp ( ); /******************************************************************************/ int main ( int argc, char *argv[] ) /******************************************************************************/ /* Purpose: MAIN is the main program for SUM. Discussion: SUM is an example of using the MPI message passing interface library. Licensing: This code is distributed under the GNU LGPL license. Modified: 01 May 2003 Author: John Burkardt Reference: Forrest Hoffman, Message Passing with MPI and PVM, LINUX Magazine, Volume 4, Number 4, April 2002, pages 38-41, 63. William Gropp, Ewing Lusk, Anthony Skjellum, Using MPI: Portable Parallel Programming with the Message-Passing Interface, Second Edition, MIT Press, 1999, ISBN: 0262571323. */ { # define N 100 double array[N]; int i; int ierr; int master = 0; int my_id; int numprocs; double PI = 3.141592653589793238462643; double seed; MPI_Status status; double sum; double sum_all; /* Initialize MPI. */ ierr = MPI_Init ( &argc, &argv ); if ( ierr != 0 ) { printf ( "\n" ); printf ( "SUM_MPI - Fatal error!\n" ); printf ( " MPI_Init returns nonzero IERR.\n" ); exit ( 1 ); } /* Get the number of processes. */ MPI_Comm_size ( MPI_COMM_WORLD, &numprocs ); /* Determine the rank of this process. */ MPI_Comm_rank ( MPI_COMM_WORLD, &my_id ); /* Say hello. */ if ( my_id == master ) { timestamp ( ); printf ( "\n" ); printf ( "SUM - Master process:\n" ); printf ( " C version\n" ); printf ( "\n" ); printf ( " An MPI example program.\n" ); printf ( " The master process computes some coefficients,\n" ); printf ( " sends them to each worker process, which sums them.\n" ); printf ( "\n" ); printf ( " Compiled on %s at %s.\n", __DATE__, __TIME__ ); printf ( "\n" ); printf ( " The number of processes available is %d.\n", numprocs ); } /* The master process initializes the array. */ if ( my_id == master ) { seed = 1.2345; for ( i = 0; i < N; i++ ) { array[i] = ( double ) i * seed * PI; } } /* The master process broadcasts the computed initial values to all the other processes. */ MPI_Bcast ( array, N, MPI_DOUBLE, master, MPI_COMM_WORLD ); /* Each process adds up its entries. */ sum = 0.0; for ( i = 0; i < N; i++ ) { sum = sum + array[i] * ( double ) my_id; } printf ( "\n" ); printf ( "SUM - Process %d:\n", my_id ); printf ( " My contribution to the sum is %f\n", sum ); /* Each worker process sends its sum back to the master process. */ if ( my_id != master ) { MPI_Send ( &sum, 1, MPI_DOUBLE, master, 1, MPI_COMM_WORLD ); } else { sum_all = sum; for ( i = 1; i < numprocs; i++ ) { MPI_Recv ( &sum, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &status ); sum_all = sum_all + sum; } } if ( my_id == master ) { printf ( "\n"); printf ( "SUM - Master process:\n"); printf ( " The total sum is %.16f\n", sum_all ); } /* Terminate MPI. */ MPI_Finalize ( ); /* Terminate. */ if ( my_id == master ) { printf ( "\n"); printf ( "SUM - Master process:\n"); printf ( " Normal end of execution.\n"); printf ( "\n" ); timestamp ( ); } return 0; # undef N } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: TIMESTAMP prints the current YMDHMS date as a time stamp. Example: 31 May 2001 09:45:54 AM Licensing: This code is distributed under the GNU LGPL license. Modified: 24 September 2003 Author: John Burkardt Parameters: None */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }