|
|
|
@ -2,112 +2,122 @@ |
|
|
|
|
|
|
|
|
|
#define INPUTFILE "zadanie1.in" |
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
int size, rank, slave, i, n, value, count = 0; |
|
|
|
|
float fvalue; |
|
|
|
|
int maximum1(int n, int **numbers); |
|
|
|
|
//int maximum2(int n, int (*numbers)[n]);
|
|
|
|
|
int *array_slice(int n, int **numbers, int start, int count); |
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
int processes, rank; |
|
|
|
|
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_Comm_size(MPI_COMM_WORLD, &processes); |
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
|
|
|
|
|
|
|
|
|
int i, n, value, count = 0, slaves = processes - 1; |
|
|
|
|
if (processes < 3) { |
|
|
|
|
printf("There must be at least 3 processes to do parallel computing.\n"); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This is the master process
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int portion = count / slaves; |
|
|
|
|
int remainder = count % slaves; |
|
|
|
|
printf("count %d / slaves %d = %d mod %d \n", count, slaves, portion, remainder); |
|
|
|
|
|
|
|
|
|
//printf(" Sending numbers: ");
|
|
|
|
|
//for (i = 0; i < count; i++)
|
|
|
|
|
//printf("%d ", numbers[i]);
|
|
|
|
|
|
|
|
|
|
// Send every slave the portion of the set
|
|
|
|
|
for (i = 1; i < processes; i++) {
|
|
|
|
|
int *slice = array_slice(count, &numbers, (i - 1) * portion, portion); |
|
|
|
|
MPI_Send(slice, portion, MPI_INT, i, 0, MPI_COMM_WORLD); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The address where the modulo elements start
|
|
|
|
|
//int remainder = i * value + (count % processes);
|
|
|
|
|
//MPI_Send(numbers, count, MPI_INT, i, remainder, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
// Receive all the maximums from the slaves
|
|
|
|
|
for (i = 1; i < processes; i++) {
|
|
|
|
|
MPI_Recv(&value, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &status); |
|
|
|
|
printf("Received %d from %d\n", value, i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (remainder > 0) { |
|
|
|
|
int *slice = array_slice(count, &numbers, (i - 1) * portion, remainder); |
|
|
|
|
value = maximum1(remainder, &slice); |
|
|
|
|
printf("Calculated %d from remainder\n", value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// This is a slave process
|
|
|
|
|
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];
|
|
|
|
|
int *numbers = my_malloc(n * sizeof(int *)); |
|
|
|
|
// There is no way, I could find, to use dynamically allocated array...the pointer of numbers
|
|
|
|
|
// array changes after calling MPI_Recv...only fixed array worked here, otherwise exactly two
|
|
|
|
|
// elements are received all the time...meh
|
|
|
|
|
|
|
|
|
|
printf("address before: %p\n", numbers); |
|
|
|
|
MPI_Recv(numbers, n, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); |
|
|
|
|
printf("address after: %p\n", numbers); |
|
|
|
|
//int *numbers = my_malloc(n * sizeof(int *));
|
|
|
|
|
//for (i = 0; i < n; i++)
|
|
|
|
|
//numbers[i] = numberss[i];
|
|
|
|
|
value = maximum1(n, &numbers); |
|
|
|
|
MPI_Send(&value, 1, MPI_INT, 0, rank, MPI_COMM_WORLD); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MPI_Finalize(); |
|
|
|
|
return (0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define MAXIMUM { \ |
|
|
|
|
int value = 0; \
|
|
|
|
|
for (int i = 0; i < n; i++) { \
|
|
|
|
|
if (value < (*numbers)[i]) {\
|
|
|
|
|
value = (*numbers)[i]; \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
return value; \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int maximum1(int n, int **numbers) MAXIMUM; |
|
|
|
|
|
|
|
|
|
//int maximum2(int n, int (*numbers)[n]) MAXIMUM;
|
|
|
|
|
|
|
|
|
|
int *array_slice(int n, int **numbers, int start, int count) { |
|
|
|
|
int *slice = my_malloc(count * sizeof(int *)); |
|
|
|
|
// Make sure that iteration won't try to go outside of numbers array
|
|
|
|
|
for (int i = 0; i < count && i < n; i++)
|
|
|
|
|
slice[i] = (*numbers)[start + i];
|
|
|
|
|
|
|
|
|
|
return slice; |
|
|
|
|
} |
|
|
|
|