/* ----------------------------------------------------------------------
This program tests the use of MPI Collective Communications
subroutines. The structure of the program is:
-- Master node queries for random number seed
-- The seed is sent to all nodes (Lab project)
-- Each node calculates one random number based on the seed
and the rank
-- The node with highest rank calculates the mean value
of the random numbers (Lab project)
-- 4 more random numbers are generated by each node
-- The maximum value and the standard deviation of all
generated random numbers are calculated, and the
results are made available to all nodes (Lab project)
Also provided is a service routine GetStats(rnum,N,data), where
rnum: array of random numbers (INPUT)
N: number of elements in rnum (INPUT)
outd: array of size 2 containing the maximum value and
standard deviation (OUTPUT)
---------------------------------------------------------------------- */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"
int GetStats(float* rnum, int n, float* rval);
void main(int argc, char** argv)
{
int numtasks,taskid, ii;
unsigned int seed;
float randnum[5], sum, meanv, rnum[100], rval[2];
MPI_Status status;
FILE *fp, *GetSeed;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &taskid );
MPI_Comm_size( MPI_COMM_WORLD, &numtasks );
fp = fopen( "c.data", "w" );
if( taskid == 0 ) /* Get random number seed */
{
GetSeed = fopen( "./c.seed", "r" );
fscanf(GetSeed, "%u", &seed);
printf("seed is %u\n", seed);
fclose( GetSeed );
}
/*
================================================
Project: Send seed from task 0 to all nodes.
================================================
*/
/* =======> Put code here */
printf( "\n Task %d after broadcast; seed = %u", taskid, seed );
srand( seed + taskid );
randnum[0] = 100.*(float)rand()/(float)RAND_MAX; /* Get a random number */
/*
==============================================================
Project: Have the node with highest rank calculate the
mean value of the random numbers and store result
in the variable "meanv".
==============================================================
*/
/* =======> Put code here */
printf( "\n Task %d after mean value; random[1] =", taskid );
printf( "%8.3f sum = %8.3f mean = %8.3f", randnum[1], sum, meanv );
/* Highest task writes out mean value */
if( taskid == (numtasks-1) )
fprintf( fp, " For seed = %d mean value = %10.3f\n", seed, meanv );
/* Generate 4 more random numbers */
for( ii=1; ii < 5; ii++ )
randnum[ii] = 100.*(float)rand()/(float)RAND_MAX;
/*
==================================================================
Project: Calculate the maximum value and standard deviation of
all random numbers generated, and make results known
to all nodes.
Method 1: Use GATHER followed by BCAST
Method 2: Use ALLGATHER
==================================================================
*/
/* ------ Method 1 ----------- */
/* =======> Put code here */
printf( "\n Task %d after Method 1, rnum(1:5) =", taskid );
for( ii=1; ii < 5; ii++ )
printf( " %8.3f", rnum[ii] );
if( taskid == (numtasks-1))
fprintf( fp, " (Max, S.D.) = %10.3f%10.3f\n", rval[0], rval[1]);
/* ------ Method 2 ----------- */
/* =======> Put code here */
printf( "\n Task %d after Method 2, rnum(1:5) =", taskid );
for( ii=1; ii < 5; ii++ )
printf( " %8.3f", rnum[ii] );
printf( "\n" );
if( taskid == (numtasks-1))
fprintf( fp," (Max, S.D.) = %10.3f%10.3f\n", rval[0], rval[1]);
fclose( fp );
MPI_Finalize();
}
/* ----------------------------------------------------------------------
Service routine GetStats( rnum, N, data), where
rnum: array of random numbers (INPUT)
N: number of elements in rnum (INPUT)
outd: array of size 2 containing the maximum value and
standard deviation (OUTPUT)
---------------------------------------------------------------------- */
int GetStats(float* rnum, int N, float* outd)
{
float sum, meanv, sdev;
int ii;
sum = 0.;
*outd = 0.;
for( ii = 0 ; ii < N ; ii++ )
{
sum += *(rnum + ii);
if( *(rnum + ii) > *outd )
*outd = *(rnum + ii);
}
meanv = sum/(float)N;
sdev = 0.;
for( ii = 0; ii < N; ii++ )
sdev += (*(rnum + ii) - meanv) * (*(rnum + ii) - meanv);
*(outd + 1) = sqrt( sdev/(float)N );
}