parent
e5c9fe7c0e
commit
51efa347c7
@ -0,0 +1,166 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <mpi.h> |
||||
#include <stdbool.h> |
||||
#include <limits.h> |
||||
|
||||
#define INPUTFILE "zadanie1.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 |
||||
|
||||
// Macro for counting the lenght of an array
|
||||
#define COUNT(x) ((int) (sizeof(x) / sizeof(x[0]))) |
||||
|
||||
|
||||
void *my_malloc(size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
bool is_mpi_defined(int n); |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int size, rank, slave, i, n, value, count = 0; |
||||
float fvalue; |
||||
|
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
|
||||
if (size == 4) { |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if (rank == 0) { |
||||
|
||||
int number, max = INIT_COUNT; |
||||
// Allocate enough memory for INIT_COUNT numbers
|
||||
int *numbers = my_malloc(max * sizeof(int *)); |
||||
//int num[10];
|
||||
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; |
||||
} |
||||
|
||||
//printf(" Sending numbers: ");
|
||||
//for (i = 0; i < count; i++)
|
||||
//printf("%d ", numbers[i]);
|
||||
|
||||
|
||||
//printf("\n -----------------------------");
|
||||
for (slave = 1; slave < size; slave++) { |
||||
//printf("\n from master %d to slave %d", rank, slave);
|
||||
MPI_Send(numbers, count, MPI_INT, slave, 1, MPI_COMM_WORLD); |
||||
} |
||||
printf("\n\n Receiving the results from slaves"); |
||||
printf("\n ---------------------------------"); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 11, MPI_COMM_WORLD, &status); |
||||
printf("\n Minimum %4d from slave 1", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 2, 21, MPI_COMM_WORLD, &status); |
||||
printf("\n Sum\t %4d from slave 2", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 12, MPI_COMM_WORLD, &status); |
||||
printf("\n Maximum %4d from slave 1", value); |
||||
MPI_Recv(&fvalue, 1, MPI_FLOAT, 2, 22, MPI_COMM_WORLD, &status); |
||||
printf("\n Average %4.2f from slave 2", fvalue); |
||||
MPI_Recv(&fvalue, 1, MPI_FLOAT, 3, 31, MPI_COMM_WORLD, &status); |
||||
printf("\n H. mean %4.2f from slave 3\n", fvalue);
|
||||
}
|
||||
else { |
||||
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); |
||||
MPI_Get_count(&status, MPI_INT, &n); |
||||
|
||||
is_mpi_defined(n); |
||||
int numbers[n]; |
||||
count = COUNT(numbers);
|
||||
|
||||
if (rank == 1) { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
//MPI_Recv(numbers, n, MPI_INT, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status);
|
||||
value = INT_MAX; |
||||
for (i = 0; i < count; i++) { |
||||
if (value > numbers[i]) { |
||||
value = numbers[i]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 11, MPI_COMM_WORLD); |
||||
value = 0; |
||||
for (i = 0; i < count; i++) { |
||||
if (value < numbers[i]) { |
||||
value = numbers[i]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 12, MPI_COMM_WORLD); |
||||
}
|
||||
else if (rank == 2) { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
value = 0; |
||||
for (i = 0; i < count; i++) { |
||||
value = value + numbers[i]; |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 21, MPI_COMM_WORLD); |
||||
fvalue = (float) value / count; |
||||
MPI_Send(&fvalue, 1, MPI_FLOAT, 0, 22, MPI_COMM_WORLD); |
||||
} |
||||
else { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
fvalue = 0.0; |
||||
for (i = 0; i < count; i++) { |
||||
fvalue += 1.0 / numbers[i]; |
||||
} |
||||
fvalue = (float) count / fvalue; |
||||
MPI_Send(&fvalue, 1, MPI_FLOAT, 0, 31, MPI_COMM_WORLD);
|
||||
} |
||||
} |
||||
} |
||||
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; |
||||
} |
||||
|
||||
bool is_mpi_defined(int n) { |
||||
if (n == MPI_UNDEFINED) { |
||||
printf("MPI encountered undefined integer and terminated."); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return true; |
||||
} |
||||
|
Loading…
Reference in new issue