Question
Can someone run this MPI-parallel code and tell me why it is not running? I cannot seem to figure it out #include #include #include #include
Can someone run this MPI-parallel code and tell me why it is not running? I cannot seem to figure it out
#include
#include
#include
#include
#include
#define WORKTAG 1
#define DIETAG 2
int getMin(int a, int b);
void print(int *arr, int n);
void mainAlgorithm(int *in, int *out, int n);
void copyMatrices(int *dst, int *src, int n);
int* allocateArray(int arraySize);
void runAsSingleTask();
void master();
void processData(int *dst, int *src, int n);
void slave();
#define N 4
int *inputArray = NULL;
int *outputArray = NULL;
int main(int argc, char **argv)
{
int myrank = 0;
if(1)
runAsSingleTask();
else
{
MPI_Init(&argc, &argv); // initialize MPI
MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // process rank, 0 thru N-1
if (myrank == 0)
master();
else
slave();
MPI_Finalize(); // cleanup MPI
}
return 0;
}
void master()
{
int numOfTasks;
int rank = 0;
int work = 0;
int startIndex = 0;
int dataPerTask = 0;
int *tempArray = NULL;
int i = 0;
int k = 0;
MPI_Status status;
MPI_Comm_size( MPI_COMM_WORLD, &numOfTasks); // #processes in application
// check whether the specified number of processors has an integer square root
// for example: if numOfTasks is 4, then the square root of numOfTasks is 2 which is integer
int root = (int)(floor(sqrt(numOfTasks) + 0.5));
if (root*root != numOfTasks)
{
printf("Number of MPI tasks must have an integer square root. ");
MPI_Abort(MPI_COMM_WORLD, 0);
exit(0);
}
// allocate the data arrays
inputArray = allocateArray(N);
outputArray = allocateArray(N);
// calculate the amount of data that each task will receive
dataPerTask = (N*N) / root;
// create the array that will hold the data that will be transferred back and forth between the master and slave tasks
tempArray = (int*) malloc( sizeof(int) * dataPerTask );
// main processing loop
for (k = 0; k < N; ++k)
{
// master task processes its own data chunk
memcpy(tempArray, inputArray + startIndex*sizeof(int), sizeof(int) * dataPerTask); // make a temporary copy of a chunk of the input data
processData(tempArray, inputArray, N); // process the temporary copy
startIndex += dataPerTask; // update the global data index
memcpy(outputArray, tempArray, sizeof(int) * dataPerTask); // copy results into the output array
// seed the slaves
for (i = 1; i < numOfTasks; ++i)
{
memcpy(tempArray, inputArray + startIndex * sizeof(int), sizeof(int) * dataPerTask); // make a temporary copy of a chunk of the input data
MPI_Send(&dataPerTask, 1, MPI_INT, i, 0, MPI_COMM_WORLD); // send the size of the data chunk to the slave task
MPI_Send(tempArray, dataPerTask, MPI_INT, i, WORKTAG, MPI_COMM_WORLD); // send the actual chunk of data to the slave task
MPI_Recv(tempArray, dataPerTask, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // receive results from slave task
memcpy(outputArray + startIndex * sizeof(int), tempArray, sizeof(int) * dataPerTask); // copy results into the output array
startIndex += dataPerTask;
}
copyMatrices(inputArray, outputArray, N);
}
// tell all the slaves to exit
for (i = 1; i < numOfTasks; ++i)
MPI_Send(0, 0, MPI_INT, i, DIETAG, MPI_COMM_WORLD);
free(tempArray);
free(inputArray);
free(outputArray);
}
void slave()
{
MPI_Status status;
int *a = NULL;
int *b = NULL;
int dataPerTask = 0;
MPI_Recv(&dataPerTask, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // get the number of integers in the incoming array
if (status.MPI_TAG == DIETAG) // check the tag of the received message (if the master task sent the DIETAG, then the slave must stop processing and return)
return;
a = (int*)malloc(sizeof(int)*dataPerTask); // array 'a' holds the data received from the master task
b = (int*)malloc(sizeof(int)*dataPerTask); // array 'b' holds the data that is returned to the master task
MPI_Recv(a, dataPerTask, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // get the actual data from the master task
// perform the algorithm-specific computations
processData(b, a, N);
MPI_Send(b, dataPerTask, MPI_INT, 0, 0, MPI_COMM_WORLD);
free(a);
free(b);
}
void processData(int *dst, int *src, int n)
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
dst[i*n + j] = getMin(src[i*n + j], src[i] + src[j]);
}
}
int getMin(int a, int b)
{
if (a < b)
return a;
return b;
}
void print(int *arr, int n)
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%d ", arr[i*n+j]);
printf(" ");
}
printf(" ");
}
void mainAlgorithm(int *in, int *out, int n)
{
int k = 0;
int i = 0;
int j = 0;
for (k = 0; k < n; k++)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
out[i*n+j] = getMin(in[i*n + j], in[i*n + k] + in[k*n + j]);
}
copyMatrices(in, out, n);
}
}
void copyMatrices(int *dst, int *src, int n)
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
dst[i*n + j] = src[i*n + j];
}
}
int* allocateArray(int n)
{
int i = 0;
if (n <= 0)
return NULL;
int *arr = (int*) malloc(sizeof(int)*n*n);
for (i = 0; i < n*n; i++)
arr[i] = 0;
return arr;
}
void runAsSingleTask()
{
int i = 0;
int j = 0;
inputArray = allocateArray(N);
outputArray = allocateArray(N);
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
inputArray[i*N + j] = i * 4 + j;
}
printf("Array A before running the algorithm: ");
print(inputArray, N);
printf("Array B before running the algorithm: ");
print(outputArray, N);
printf("Executing the algorithm with array A as the input array and array B as the output array. ");
mainAlgorithm(inputArray, outputArray, N);
printf("Array A after running the algorithm: ");
print(inputArray, N);
printf("Array B after running the algorithm: ");
print(outputArray, N);
free(inputArray);
free(outputArray);
getchar();
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started