Code:
#include <stdio.h>
#include <mpi.h>
#include "math.h"
int main(int argc, char* argv[])
{
int mypid, nprocs;
int N, flag, index;
//N is used for the total number of elements in the dynamically allocated array
int temp = 0;
int sum = 0;
int modulus, numSum;
int max, max_id, min, min_id, diff;
int tempmax, tempmax_id, tempmin, tempmin_id, tempdiff;
int i;
FILE *input = NULL; //setup for using files
int *data = NULL; //used to create the dynamically allocated array
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &mypid);
MPI_Status status;
if( mypid == 0 )
{
input = fopen("test.txt", "r");
//opens the file input.txt if it is in the root directory
if( input == NULL )
//if there is no such file
{
printf("Cannot open file [%s] \n", "input");
flag = 1;
}
if( fscanf(input, "%d", &N) != 1 )
//if the first thing is not a number
{
printf("Wrong format \n");
flag = 1;
}
}
MPI_Bcast(&flag, 1, MPI_INT, 0, MPI_COMM_WORLD);
if(flag == 1)
//something failed, all processors terminate
{
MPI_Finalize();
return 0;
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
data = calloc(N, sizeof(int));
//defines the dynamic arry to size N
if( data == NULL )
//the length of data is 0
{
printf("mem allocation error \n");
MPI_Finalize();
free(data);
flag = 1;
return 0;
}
if(mypid == 0)
{
for(i = 0; i < N; ++i)
{
if(fscanf(input, "%d", data + i) != 1) //scan in numbers
{
printf("Not enough numbers as specified. \n");
free(data);
flag = 1;
return 0;
}
}
}
//this reads in the numbers and gives an error if there are not enough as specified
MPI_Bcast(&flag, 1, MPI_INT, 0, MPI_COMM_WORLD);
if( flag == 1)
//terminates the other processors
{
MPI_Finalize();
free(data);
return 0;
}
MPI_Bcast(data, N, MPI_INT, 0, MPI_COMM_WORLD);
max=data[mypid];
min=data[mypid];
max_id=mypid;
min_id=mypid;
diff=0;
tempmax=data[mypid];
tempmin=data[mypid];
tempmax_id=mypid;
tempmin_id=mypid;
tempdiff=0;
for( i=0; i<(log(nprocs)/log(2)); i++ )
{
if( mypid % (int)pow(2, i) == 0 )
{
if( mypid % (int)pow(2, i + 1) == 0 ) //join the work
{
MPI_Recv(&tempmax, 1, MPI_INT, (mypid+(int)pow(2,i)), 0, MPI_COMM_WORLD, &status);
MPI_Recv(&tempmax_id, 1, MPI_INT, (mypid+(int)pow(2,i)), 1, MPI_COMM_WORLD, &status);
MPI_Recv(&tempmin, 1, MPI_INT, (mypid+(int)pow(2,i)), 2, MPI_COMM_WORLD, &status);
MPI_Recv(&tempmin_id, 1, MPI_INT, (mypid+(int)pow(2,i)), 3, MPI_COMM_WORLD, &status);
MPI_Recv(&tempdiff, 1, MPI_INT, (mypid+(int)pow(2,i)), 4, MPI_COMM_WORLD, &status);
if((diff < 0)&&(tempdiff < 0))
{
max=0;
max_id=0;
if (min>tempmin)
{
min=tempmin;
min_id=tempmin_id;
}
diff=0;
tempmax=max;
tempmax_id=max_id;
tempmin=min;
tempmin_id=min_id;
tempdiff=diff;
}
else
{
if((diff <= 0))
{
if (max<tempmax)
{
max=tempmax;
max_id=tempmax_id;
}
else if (max==tempmax)
{
max=tempmax;
max_id=tempmax_id;
}
if (min>tempmin)
{
min=tempmin;
min_id=tempmin_id;
}
if (max_id<min_id)
{
diff=(max-min)*-1;
}
else
{
diff=max-min;
}
}
else
{
if (max<tempmax)
{
max=tempmax;
max_id=tempmax_id;
}
if (max_id<min_id)
{
diff=(max-min)*-1;
}
else
{
diff=max-min;
}
}
tempmax=max;
tempmax_id=max_id;
tempmin=min;
tempmin_id=min_id;
tempdiff=diff;
}
// printf("P%d max=%d max_id=%d min=%d min_id=%d diff=%d on i=%d\n", mypid,max,max_id,min,min_id,diff,i);
}
else if( mypid % (int)pow(2, i + 1) != 0 )
{
MPI_Send(&tempmax, 1, MPI_INT, (mypid-(int)pow(2,i)), 0, MPI_COMM_WORLD);
MPI_Send(&tempmax_id, 1, MPI_INT, (mypid-(int)pow(2,i)), 1, MPI_COMM_WORLD);
MPI_Send(&tempmin_id, 1, MPI_INT, (mypid-(int)pow(2,i)), 3, MPI_COMM_WORLD);
MPI_Send(&tempmin, 1, MPI_INT, (mypid-(int)pow(2,i)), 2, MPI_COMM_WORLD);
MPI_Send(&tempdiff, 1, MPI_INT, (mypid-(int)pow(2,i)), 4, MPI_COMM_WORLD);
}
}
}
if (mypid==0)
{
printf("The best day to buy the stock is day %d for %d and sell on day %d for %d making %d\n", min_id+1, min, max_id+1, max, diff);
}
if( input != NULL )
{
fclose(input);
}
//closes the file
free(data);
MPI_Finalize();
return 0;
}