Assignments for parallel processing using OpenMPI.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
openmpi-assignments/assignment1.c

108 lines
3.5 KiB

#include "common.h"
#define INPUTFILE "assignment1.in"
int maximum(int n, int *arrNumbers);
int main(int argc, char *argv[]) {
int numProcesses, numRank;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
MPI_Comm_rank(MPI_COMM_WORLD, &numRank);
int *arrNumbers, *arrBlockIndices, *arrBlockSizes;
int sizeBufferTotal, sizeBufferUsed = 0;
if (numRank == 0) {
// To avoid aggresive buffer growth at the beggining of the sequence
sizeBufferTotal = INIT_BUFFER_SIZE;
// Allocate enough memory for initial buffer
arrNumbers = my_malloc(sizeBufferTotal * sizeof(int));
// Open the file with input data
FILE *ptrFile = my_fopen(INPUTFILE, "r");
// Read lines of numbers until an EOF or a character is read
int numNumber;
while (fscanf(ptrFile, "%d", &numNumber) == 1) {
// Grow buffer when needed
arrNumbers = buffer_grow(arrNumbers, sizeBufferUsed, &sizeBufferTotal);
// Store the number in memory
arrNumbers[sizeBufferUsed++] = numNumber;
}
checkParallelWorth(numProcesses, sizeBufferUsed);
int numBlockIndex = 0;
int numRemainder = sizeBufferUsed % numProcesses;
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
for (int i = 0; i < numProcesses; i++) {
arrBlockSizes[i] = sizeBufferUsed / numProcesses;
if (numRemainder > 0) {
arrBlockSizes[i]++;
numRemainder--;
}
arrBlockIndices[i] = numBlockIndex;
numBlockIndex += arrBlockSizes[i];
// Send block size to every process
MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
//for (int i = 0; i < numProcesses; i++) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]);
//}
//for (int i = 0; i < numProcesses; i++) {
//MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
//}
}
MPI_Bcast(&sizeBufferTotal, 1, MPI_INT, 0, MPI_COMM_WORLD);
int *arrSlice = my_malloc(sizeBufferTotal * sizeof(int));
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD);
int numBlockSize;
MPI_Recv(&numBlockSize, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
//for (int i = 0; i < numBlockSize; i++) {
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
//}
int numMaximum = maximum(numBlockSize, arrSlice);
//printf("max in %d is %d\n", numRank, numMaximum);
int *arrMaximums;
if (numRank == 0) {
arrMaximums = my_malloc(numProcesses * sizeof(int));
}
MPI_Gather(&numMaximum, 1, MPI_INT, arrMaximums, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
if (numRank == 0) {
//for (int i = 0; i < numProcesses; i++) {
//printf("arrMaximums[%d] = %d\n", i, arrMaximums[i]);
//}
printf("The maximum from file %s is %d.\n", INPUTFILE, maximum(numProcesses, arrMaximums));
}
MPI_Finalize();
return (0);
}
int maximum(int n, int *arrNumbers) {
int value = INT_MIN;
for (int i = 0; i < n; i++) {
if (value < arrNumbers[i]) {
value = arrNumbers[i];
}
}
return value;
}