parent
6a7e804a5e
commit
052092ee8a
Binary file not shown.
@ -0,0 +1,6 @@ |
||||
1 1 1 1 |
||||
2 2 2 2 |
||||
3 3 3 3 |
||||
4 4 4 4 |
||||
5 5 5 5 |
||||
6 6 6 6 |
@ -0,0 +1,289 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <mpi.h> |
||||
|
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_BUFFER_SIZE 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
#define INPUTFILE1 "zadanie1.in1" |
||||
#define INPUTFILE2 "zadanie1.in2" |
||||
//#define MIN_PORTION 2
|
||||
|
||||
int maximum(int n, int *arrNumbers); |
||||
int *array_slice(int n, int *arrNumbers, int start, int count); |
||||
void *my_malloc(size_t size); |
||||
void *my_calloc(size_t nitems, size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int numProcesses, numRank; |
||||
//MPI_Status mpiStatus;
|
||||
|
||||
int *arrNumbers; |
||||
int *arrBlockIndices; |
||||
int *arrBlockSizes; |
||||
|
||||
int numBufferSize; |
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
||||
|
||||
if (numRank == 0) { |
||||
int numNumber, numCount = 0; |
||||
// To avoid aggresive buffer growth at the beggining of the sequence
|
||||
numBufferSize = INIT_BUFFER_SIZE; |
||||
// Allocate enough memory for initial buffer
|
||||
arrNumbers = my_malloc(numBufferSize * sizeof(int)); |
||||
//int num[10];
|
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(ptrFile, "%d", &numNumber) == 1) { |
||||
// Incorporate space for storing results received from slaves at the end of array
|
||||
int numBufferUsed = numCount + numProcesses - 1; |
||||
|
||||
if (numBufferSize == numBufferUsed) { |
||||
// Grow buffer exponentially
|
||||
numBufferSize *= GROWTH_FACTOR; |
||||
arrNumbers = my_realloc(arrNumbers, numBufferSize * sizeof(int)); |
||||
}
|
||||
|
||||
arrNumbers[numCount++] = numNumber; |
||||
} |
||||
|
||||
if (numProcesses > numCount / 2) { |
||||
printf("*********************************************************************************\n"); |
||||
printf("The number of processes if greater than number of parallel computations required!\n"); |
||||
printf("*********************************************************************************\n\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
//printf("count: %d, buffer: %d\n", numCount, numBufferSize);
|
||||
|
||||
int numBlockIndex = 0; |
||||
int numRemainder = numCount % numProcesses; |
||||
|
||||
arrBlockIndices = my_malloc(numProcesses * sizeof(int)); |
||||
arrBlockSizes = my_malloc(numProcesses * sizeof(int)); |
||||
|
||||
for (int i = 0; i < numProcesses; i++) { |
||||
arrBlockSizes[i] = numCount / numProcesses; |
||||
if (numRemainder > 0) { |
||||
arrBlockSizes[i]++; |
||||
numRemainder--; |
||||
} |
||||
|
||||
arrBlockIndices[i] = numBlockIndex; |
||||
numBlockIndex += arrBlockSizes[i]; |
||||
} |
||||
|
||||
//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(&numBufferSize, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
int *arrSlice = my_malloc(numBufferSize * sizeof(int)); |
||||
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, numBufferSize, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
int numCount; |
||||
MPI_Recv(&numCount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
//for (int i = 0; i < numCount; i++) {
|
||||
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
|
||||
//}
|
||||
|
||||
int numMaximum = maximum(numCount, 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;
|
||||
} |
||||
|
||||
int *array_slice(int n, int *arrNumbers, int start, int count) { |
||||
int *slice = my_malloc(count * sizeof(int)); |
||||
for (int i = 0; i < count && i < n; i++)
|
||||
slice[i] = arrNumbers[start + i];
|
||||
|
||||
return slice; |
||||
} |
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
void *my_calloc(size_t nitems, size_t size) { |
||||
void *p = calloc(nitems, size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation with initialisation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
//int *numBlockSize = &arrBlockSizes[numRank];
|
||||
//printf("r: %d, nbs %d\n", numRank, *numBlockSize);
|
||||
|
||||
// If there is just the one root process, all the numbers must be passed to the final stage
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//numBlockSize = numProcesses;
|
||||
//int BlS = arrBlockSizes;
|
||||
//MPI_Bcast(arrBlockciwSizes, numProcesses, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
//for (int i = 0; i < numProcesses; i++)
|
||||
//printf("rank %d, nproc %d, abs[%i] = %d\n", numRank, numProcesses, i, arrBlockSizes[i]);
|
||||
//printf("%d %d\n", arrBlockSizes[0], arrBlockSizes[1]);
|
||||
//printf("%d: ", numRank);
|
||||
//for (int i = 0; i < numProcesses; i++) {
|
||||
//printf("%d ", arrBlockSizes[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//int num = numProcesses + 100;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//int *arrSlice = my_malloc(numBlockSize * sizeof(int));
|
||||
//arrSlice[numRank] = numRank * 10 + 5;
|
||||
|
||||
|
||||
//if (numRank == 0) {
|
||||
//printf("root received:\n");
|
||||
//for (int i = 0; i < numBlockSize; i++) {
|
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//print what each process received
|
||||
//printf("%d: ", numRank);
|
||||
for (int i = 0; i < arrBlockSizes[numRank]; i++) { |
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
arrSlice[i] *= 10; |
||||
}
|
||||
//printf("\n");
|
||||
*/ |
||||
|
||||
|
||||
|
||||
|
||||
//printf("size = %d, remainder = %d\n\n", numBlockSize, numRemainder);
|
||||
|
||||
// This is a slave process
|
||||
//else {
|
||||
//int numCount, numValue;
|
||||
//MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &mpiStatus);
|
||||
//MPI_Get_count(&mpiStatus, MPI_INT, &numCount);
|
||||
|
||||
//if (numCount != MPI_UNDEFINED) {
|
||||
//int *arrNumbers = my_malloc(numCount * sizeof(int));
|
||||
|
||||
////printf("address before: %p\n", arrNumbers);
|
||||
//MPI_Recv(arrNumbers, numCount, MPI_INT, 0, 1, MPI_COMM_WORLD, &mpiStatus);
|
||||
////printf("address after: %p\n", arrNumbers);
|
||||
//numValue = maximum(numCount, arrNumbers);
|
||||
//MPI_Send(&numValue, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// If there are no slave processes, just find the maximum of the numbers from the file
|
||||
//int numUse = numCount, numStart = 0;
|
||||
//int numPortion = numCount;
|
||||
|
||||
//if (numProcesses > 1) {
|
||||
|
||||
////int numSlaves = numProcesses - 1;
|
||||
//numPortion = numCount / numProcesses;
|
||||
|
||||
//// Send at least 2 numbers to compare to slave process, no less
|
||||
//numPortion = numPortion >= 2 ? numPortion : 2;
|
||||
|
||||
//// Do the loop for every slave process
|
||||
//for (int numSlave = 1; numProcesses > numSlave; numSlave++) {
|
||||
//printf("> sending %d to %d\n", numPortion, numSlave);
|
||||
//MPI_Send(&arrNumbers[numStart], numPortion, MPI_INT, numSlave, 1, MPI_COMM_WORLD);
|
||||
//numStart += numPortion;
|
||||
//numUse -= numPortion;
|
||||
//}
|
||||
|
||||
|
||||
//}
|
||||
|
||||
//int max = maximum(numUse, &arrNumbers[numStart]);
|
||||
//int max = maximum(numCount, arrNumbers);
|
||||
//printf("processes: %d, buffer: %d, count: %d, portion: %d \n",
|
||||
//numProcesses, numBufferSize, numCount, numPortion);
|
||||
|
||||
//printf("start: %d, use: %d, max: %d\n", numStart, numUse, max);
|
@ -0,0 +1,2 @@ |
||||
1 2 3 |
||||
4 5 6 |
@ -0,0 +1,3 @@ |
||||
7 8 |
||||
9 10 |
||||
11 12 |
@ -0,0 +1,36 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#define MAX_LINE_LENGTH 8192 |
||||
|
||||
#define INPUTFILE1 "zadanie3.in1" |
||||
#define INPUTFILE2 "zadanie3.in2" |
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
int main(void) { |
||||
char strBuffer[MAX_LINE_LENGTH]; |
||||
char *ptrBuffer; |
||||
int numValue; |
||||
|
||||
FILE *ptrFile = my_fopen(INPUTFILE2, "r"); |
||||
|
||||
while (fgets(strBuffer, sizeof strBuffer, ptrFile) != 0) { |
||||
//printf("Line contains ");
|
||||
ptrBuffer = strBuffer; |
||||
while (*ptrBuffer != '\n') { |
||||
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
||||
printf("%d ", numValue); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
return 0; |
||||
} |
Loading…
Reference in new issue