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.
108 lines
3.5 KiB
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;
|
|
}
|
|
|
|
|
|
|