zadanie1 working flawlessly with dynamic memory

master
Peter Babič 9 years ago
parent 3c8a2664fb
commit 6a7e804a5e
  1. BIN
      atter
  2. BIN
      bcast
  3. 28
      bcast.c
  4. BIN
      dyn2
  5. 34
      dyn2.c
  6. BIN
      dynamic
  7. 51
      dynamic.c
  8. BIN
      readdyn
  9. 84
      readdyn.c
  10. BIN
      readfile
  11. 6
      readfile.c
  12. 2
      run
  13. 131
      zadanie1.c
  14. BIN
      zadanie11
  15. 227
      zadanie11.c
  16. BIN
      zadanie111
  17. 288
      zadanie111.c
  18. 289
      zadanie2.c

BIN
atter

Binary file not shown.

BIN
bcast

Binary file not shown.

@ -0,0 +1,28 @@
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int rank;
int *buf;
const int root=0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == root) {
buf = (int *)malloc(2*sizeof(int));
buf[0] = 0;
buf[1] = 1;
}
//printf("[%d]: Before Bcast, buf is %d\n", rank, buf);
/* everyone calls bcast, data is taken from root and ends up in everyone's buf */
MPI_Bcast(buf, 2, MPI_INT, root, MPI_COMM_WORLD);
printf("[%d]: %d %d\n", rank, buf[0], buf[1]);
MPI_Finalize();
return 0;
}

BIN
dyn2

Binary file not shown.

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char** argv) {
int n, i, *ptr, rank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
n = 4;
ptr = (int*)malloc(n * sizeof(int)); //memory allocated using malloc
if(ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
if (rank == 0) {
for(i = 0; i < n; i++) {
ptr[i] = i * 10;
}
}
MPI_Bcast(ptr, n, MPI_INT, 0, MPI_COMM_WORLD);
for(i = 0; i < n; i++) {
printf("%d: i[%d] = %d\n", rank, i, ptr[i]);
}
free(ptr);
MPI_Finalize();
return 0;
}

Binary file not shown.

@ -0,0 +1,51 @@
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int rank;
int rows = 4, columns = 4;
int **array;
const int root=0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == root) {
array = (int**) malloc(rows * sizeof(int*));
if (array == NULL) exit (-1);
array[0] = (int*) malloc (rows * columns * sizeof(int));
if (array[0] == NULL) exit (-1);
for (int i = 1; i < rows; i++)
array[i] = array[0] + i * columns;
//array[0] = 0;
//array[1] = 1;
}
//printf("[%d]: Before Bcast, array is %d\n", rank, array);
/* everyone calls bcast, data is taken from root and ends up in everyone's array */
MPI_Bcast(array[0], rows * columns, MPI_INT, root, MPI_COMM_WORLD);
//MPI_Bcast(array, 2, MPI_INT, root, MPI_COMM_WORLD);
//printf("[%d]: %d %d\n", rank, array[0], array[1]);
MPI_Finalize();
return 0;
//int **array;
//array = (int**) malloc (rows * sizeof(int*));
//if (array == NULL) exit (-1);
//array[0] = (int*) malloc (rows * columns * sizeof(int));
//if (array[0] == NULL) exit (-1);
//for (i=1; i<rows; i++)
//array[i] = array[0] + i * columns;
}

Binary file not shown.

@ -0,0 +1,84 @@
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define INPUTFILE "sample1_e.in"
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
#define INIT_COUNT 8
// Optimal exponential buffer growth factor, 2 is sometimes used to
#define GROWTH_FACTOR 1.5
void *my_malloc(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 i = 0, rank, number, *numbers, count = 0, max = INIT_COUNT;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0) {
count = 0;
// Allocate enough memory for INIT_COUNT numbers
numbers = my_malloc(max * sizeof(int));
FILE *file = my_fopen(INPUTFILE, "r");
// Read lines of numbers until an EOF or a character is read
while (fscanf(file, "%d", &number) == 1) {
// Buffer space check
if (max == count) {
// Grow buffer exponentially
max *= GROWTH_FACTOR;
numbers = my_realloc(numbers, max * sizeof(int));
}
// Store the read number to the array in memory
numbers[count++] = number;
}
}
MPI_Bcast(&count, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(numbers, count, MPI_INT, 0, MPI_COMM_WORLD);
//printf("count: %d, max: %d\n", count, max);
for (i = 0; i < count; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
MPI_Finalize();
return 0;
}
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_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;
}

Binary file not shown.

@ -15,16 +15,16 @@ int main(int argc, char *argv[]){
int number, count = 0, max = INIT_COUNT;
// Allocate enough memory for INIT_COUNT numbers
int *numbers = my_malloc(max * sizeof(int *));
int *numbers = my_malloc(max * sizeof(int));
FILE *file = my_fopen(INPUTFILE, "r");
// Read lines of numbers until an EOF or a character is read
while (fscanf(file, "%hd", &number) == 1) {
while (fscanf(file, "%d", &number) == 1) {
// Buffer space check
if (max == count) {
// Grow buffer exponentially
max *= GROWTH_FACTOR;
numbers = my_realloc(numbers, max * sizeof(int *));
numbers = my_realloc(numbers, max * sizeof(int));
}
// Store the read number to the array in memory

2
run

@ -2,5 +2,5 @@
#mpicc -Wall -Wno-unused-variable "$1.c" "library.c" -o "$1"
#mpicc -Wall "$1.c" "library.c" -o "$1"
mpicc -Wall "$1.c" -o "$1"
mpicc -Wall -g -O0 "$1.c" -o "$1"
mpirun -v -np "$2" "$1"

@ -46,51 +46,50 @@ int main(int argc, char *argv[]) {
if (numProcesses > 1) {
//int numSlaves = numProcesses - 1;
numPortion = numCount / numProcesses;
//int numSlaves = numProcesses - 1;
numPortion = numCount / numProcesses;
// Send at least 2 numbers to compare to slave process, no less
numPortion = numPortion >= 2 ? numPortion : 2;
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;
}
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;
}
for (int
}
//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);
}
// 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);
}
}
//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);
}
// 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);
}
}
MPI_Finalize();
return (0);
MPI_Finalize();
return (0);
}
int maximum(int n, int *arrNumbers) {
@ -113,8 +112,8 @@ int *array_slice(int n, int *arrNumbers, int start, int count) {
/*int portion = count / slaves;
int slaves = numProcesses - 1;
/*int portion = count / slaves;
int slaves = numProcesses - 1;
// If there is a remainder, we need to dedicate a slave to it
if (numRemainder < 2)
@ -137,40 +136,40 @@ int *array_slice(int n, int *arrNumbers, int start, int count) {
printf("count: %d, slaves: %d, portion: %d, mod: %d \n", count, slaves, numPortion, numRemainder);
// Send every slave the portion of the set
for (i = 0; i < slaves; i++) {
int *slice = array_slice(count, arrNumbers, i * numPortion, numPortion);
MPI_Send(slice, numPortion, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
}
// Send every slave the portion of the set
for (i = 0; i < slaves; i++) {
int *slice = array_slice(count, arrNumbers, i * numPortion, numPortion);
MPI_Send(slice, numPortion, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
}
i++;
int *slice = array_slice(count, arrNumbers, i * numPortion, numRemainder);
MPI_Send(slice, numRemainder, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
i++;
int *slice = array_slice(count, arrNumbers, i * numPortion, numRemainder);
MPI_Send(slice, numRemainder, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
int *maximums = my_malloc((i + 1) * sizeof(int));
int *maximums = my_malloc((i + 1) * sizeof(int));
// Receive all the maximums from the slaves
for (i = 0; i < slaves; i++) {
MPI_Recv(&value, 1, MPI_INT, i + 1, 1, MPI_COMM_WORLD, &mpiStatus);
maximums[i] = value;
//printf("i = %d, received %d from %d\n", i, value, i+1);
}
//printf("i = %d, received %d from %d\n", i, value, i+1);
}
if (remainder > 1) {
int *slice = array_slice(count, arrNumbers, i * numPortion, remainder);
maximums[i] = maximum(remainder, slice);
}
else if (remainder == 1) {
maximums[i] = arrNumbers[count - 1];
}
if (remainder > 1) {
int *slice = array_slice(count, arrNumbers, i * numPortion, remainder);
maximums[i] = maximum(remainder, slice);
}
else if (remainder == 1) {
maximums[i] = arrNumbers[count - 1];
}
printf("Maximum of arrNumbers");
for (n = 0; n < count; n++)
printf(" %d", arrNumbers[n]);
printf("Maximum is %d\n", maximum(i + 1, maximums));
printf("Maximum of arrNumbers");
for (n = 0; n < count; n++)
printf(" %d", arrNumbers[n]);
printf("Maximum is %d\n", maximum(i + 1, maximums));
printf("i: %d, count: %d, max: %d\n", i, COUNT(maximums), maximum(i + 1, &maximums));
printf("arrNumbers: ");
for (n = 0; n <= i; n++)
printf("%d ", maximums[n]);
printf("\n");*/
printf("i: %d, count: %d, max: %d\n", i, COUNT(maximums), maximum(i + 1, &maximums));
printf("arrNumbers: ");
for (n = 0; n <= i; n++)
printf("%d ", maximums[n]);
printf("\n");*/

Binary file not shown.

@ -19,90 +19,103 @@ FILE *my_fopen(const char *filename, const char *mode);
int main(int argc, char *argv[]) {
int numProcesses, numRank;
MPI_Status mpiStatus;
//MPI_Status mpiStatus;
int *arrNumbers = NULL;
int *arrBlockIndices = NULL;
int *arrBlockSizes = NULL;
// The address of this need not change
static int numBlockSize = 0;
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
int 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;
}
//printf("count: %d, buffer: %d\n", numCount, numBufferSize);
int numNumber, numCount = 0;
// To avoid aggresive buffer growth at the beggining of the sequence
int numBufferSize = INIT_BUFFER_SIZE;
// Allocate enough memory for initial buffer
int *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;
}
//printf("count: %d, buffer: %d\n", numCount, numBufferSize);
int numBlockIndex = 0;
int numRemainder = numCount % numProcesses;
int numBlockIndex = 0;
//int numBlockSize = numCount / numProcesses;
int numRemainder = numCount % numProcesses;
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
int *arrBlockIndices = my_malloc(numProcesses * sizeof(int));
int *arrBlockSizes = my_malloc(numProcesses * sizeof(int));
for (int ii = 0; ii < numProcesses; ii++) {
arrBlockSizes[ii] = numCount / numProcesses;
if (numRemainder > 0) {
arrBlockSizes[ii]++;
numRemainder--;
}
for (int ii; ii < numProcesses; ii++) {
arrBlockSizes[ii] = numCount / numProcesses;
if (numRemainder > 0) {
arrBlockSizes[ii]++;
numRemainder--;
arrBlockIndices[ii] = numBlockIndex;
numBlockIndex += arrBlockSizes[ii];
}
arrBlockIndices[ii] = numBlockIndex;
numBlockIndex += arrBlockSizes[ii];
}
if (numRank == 0) {
for (int jj = 0; jj < numProcesses; jj++) {
printf("size[%d] = %d\tindex[%d] = %d\n", jj, arrBlockSizes[jj], jj, arrBlockIndices[jj]);
}
numBlockSize = arrBlockSizes[0];
}
int arrMaximums[100];
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, &arrMaximums, 100, MPI_INT, 0, MPI_COMM_WORLD);
// print what each process received
printf("%d: ", numRank);
for (int i = 0; i < arrBlockSizes[numRank]; i++) {
printf("m[%d] = %d\t", i, arrMaximums[i]);
}
printf("\n");
MPI_Gatherv(&arrMaximums, 100, MPI_INT, arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, 0, MPI_COMM_WORLD);
//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);
//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;
MPI_Bcast(&arrBlockSizes, 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]);
//int *arrMaximums = my_malloc(numBlockSize[numRank] * sizeof(int));
int *arrMaximums = my_malloc(numBlockSize * sizeof(int));
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, &arrMaximums, numBlockSize, MPI_INT, 0, MPI_COMM_WORLD);
//print what each process received
//for (int i = 0; i < numRank; i++) {
//printf("rank %d, nproc %d, m[%d] = %d\t", numRank, numProcesses, i, arrMaximums[i]);
//arrMaximums[i] *= 10;
//printf("\n");
//}
//int *arrMaximums = my_malloc(numBlockSize * sizeof(int));
//arrMaximums[numRank] = numRank * 10 + 5;
//MPI_Gatherv(arrMaximums, 1, MPI_INT, arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, 0, MPI_COMM_WORLD);
//if (numRank == 0) {
//printf("root received:\n");
//for (int i = 0; i < numBlockSize; i++) {
//printf("m[%d] = %d\t", i, arrMaximums[i]);
//}
//printf("\n");
//} */
//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);
//}
//}
MPI_Finalize();
return (0);
@ -156,33 +169,69 @@ FILE *my_fopen(const char *filename, const char *mode) {
}
/*
//print what each process received
//printf("%d: ", numRank);
for (int i = 0; i < arrBlockSizes[numRank]; i++) {
//printf("m[%d] = %d\t", i, arrMaximums[i]);
arrMaximums[i] *= 10;
}
//printf("\n");
*/
// 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;
//printf("size = %d, remainder = %d\n\n", numBlockSize, numRemainder);
//// 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;
//}
// 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);
//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);
//printf("start: %d, use: %d, max: %d\n", numStart, numUse, max);

Binary file not shown.

@ -0,0 +1,288 @@
#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 INPUTFILE "zadanie1.in"
//#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,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);
Loading…
Cancel
Save