|
|
|
@ -2,8 +2,8 @@ |
|
|
|
|
|
|
|
|
|
#define INPUTFILE "zadanie1.in" |
|
|
|
|
|
|
|
|
|
int maximum(int n, int **numbers); |
|
|
|
|
int *array_slice(int n, int **numbers, int start, int count); |
|
|
|
|
int maximum(int n, int *numbers); |
|
|
|
|
int *array_slice(int n, int *numbers, int start, int count); |
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
int processes, rank; |
|
|
|
@ -13,7 +13,9 @@ int main(int argc, char *argv[]) { |
|
|
|
|
MPI_Comm_size(MPI_COMM_WORLD, &processes); |
|
|
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
|
|
|
|
|
|
|
|
|
int i, n, value, count = 0, slaves = processes - 1; |
|
|
|
|
int i, n, value, count = 0; |
|
|
|
|
// We must subtract one process for a root and one for a remainder
|
|
|
|
|
//int slaves = processes - 2;
|
|
|
|
|
if (processes < 3) { |
|
|
|
|
printf("There must be at least 3 processes to do parallel computing.\n"); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
@ -24,7 +26,7 @@ int main(int argc, char *argv[]) { |
|
|
|
|
|
|
|
|
|
int number, max = INIT_COUNT; |
|
|
|
|
// Allocate enough memory for INIT_COUNT numbers
|
|
|
|
|
int *numbers = my_malloc(max * sizeof(int *)); |
|
|
|
|
int *numbers = my_malloc(max * sizeof(int)); |
|
|
|
|
//int num[10];
|
|
|
|
|
FILE *file = my_fopen(INPUTFILE, "r"); |
|
|
|
|
|
|
|
|
@ -34,52 +36,70 @@ int main(int argc, char *argv[]) { |
|
|
|
|
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, if in usable range
|
|
|
|
|
//if (number <= INT_MAX && number >= INT_MIN)
|
|
|
|
|
numbers[count++] = number; |
|
|
|
|
numbers[count++] = number; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//int portion = count / slaves;
|
|
|
|
|
int slaves = processes - 1; |
|
|
|
|
int portion = count / slaves; |
|
|
|
|
int remainder = count % slaves; |
|
|
|
|
|
|
|
|
|
if (portion < 2) { |
|
|
|
|
printf("Please deacrease the number of processes.\n"); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
// If there is a remainder, we need to dedicate a slave to it
|
|
|
|
|
if (remainder < 2)
|
|
|
|
|
slaves--; |
|
|
|
|
|
|
|
|
|
//printf("count %d / slaves %d = %d mod %d \n", count, slaves, portion, remainder);
|
|
|
|
|
portion = count / slaves; |
|
|
|
|
remainder = count % slaves; |
|
|
|
|
|
|
|
|
|
// Send every slave the portion of the set
|
|
|
|
|
for (i = 0; i < slaves; i++) {
|
|
|
|
|
int *slice = array_slice(count, &numbers, i * portion, portion); |
|
|
|
|
MPI_Send(slice, portion, MPI_INT, i + 1, 1, MPI_COMM_WORLD); |
|
|
|
|
} |
|
|
|
|
//switch (remainder) {
|
|
|
|
|
//case 0:
|
|
|
|
|
//portion = count / slaves;
|
|
|
|
|
//break;
|
|
|
|
|
//case 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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, &status); |
|
|
|
|
maximums[i] = value; |
|
|
|
|
//printf("i = %d, received %d from %d\n", i, value, i+1);
|
|
|
|
|
} |
|
|
|
|
//if (portion < 2) {
|
|
|
|
|
//printf("please deacrease the number of processes.\n");
|
|
|
|
|
//exit(exit_failure);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
if (remainder > 1) { |
|
|
|
|
int *slice = array_slice(count, &numbers, i * portion, remainder); |
|
|
|
|
maximums[i] = maximum(remainder, &slice); |
|
|
|
|
//printf("i = %d, max of remainders is %d\n", i, maximums[i]);
|
|
|
|
|
} |
|
|
|
|
else if (remainder == 1) { |
|
|
|
|
maximums[i] = numbers[count - 1]; |
|
|
|
|
//printf("i = %d, only remainder is %d\n", i, maximums[i]);
|
|
|
|
|
} |
|
|
|
|
printf("count: %d, slaves: %d, portion: %d, mod: %d \n", count, slaves, portion, remainder); |
|
|
|
|
|
|
|
|
|
//// Send every slave the portion of the set
|
|
|
|
|
//for (i = 0; i < slaves; i++) {
|
|
|
|
|
//int *slice = array_slice(count, numbers, i * portion, portion);
|
|
|
|
|
//MPI_Send(slice, portion, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//i++;
|
|
|
|
|
//int *slice = array_slice(count, numbers, i * portion, remainder);
|
|
|
|
|
//MPI_Send(slice, remainder, MPI_INT, i + 1, 1, MPI_COMM_WORLD);
|
|
|
|
|
|
|
|
|
|
//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, &status);
|
|
|
|
|
//maximums[i] = value;
|
|
|
|
|
////printf("i = %d, received %d from %d\n", i, value, i+1);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (remainder > 1) {
|
|
|
|
|
//int *slice = array_slice(count, numbers, i * portion, remainder);
|
|
|
|
|
//maximums[i] = maximum(remainder, slice);
|
|
|
|
|
//}
|
|
|
|
|
//else if (remainder == 1) {
|
|
|
|
|
//maximums[i] = numbers[count - 1];
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
printf("Maximum of numbers"); |
|
|
|
|
for (n = 0; n < count; n++) |
|
|
|
|
printf(" %d", numbers[n]); |
|
|
|
|
printf(" is %d\n", maximum(i + 1, &maximums)); |
|
|
|
|
//printf("Maximum of numbers");
|
|
|
|
|
//for (n = 0; n < count; n++)
|
|
|
|
|
//printf(" %d", numbers[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("numbers: ");
|
|
|
|
@ -90,38 +110,38 @@ int main(int argc, char *argv[]) { |
|
|
|
|
}
|
|
|
|
|
// 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); |
|
|
|
|
|
|
|
|
|
if (n != MPI_UNDEFINED && n >= 2) { |
|
|
|
|
int *numbers = my_malloc(n * sizeof(int *)); |
|
|
|
|
|
|
|
|
|
//printf("address before: %p\n", numbers);
|
|
|
|
|
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
|
|
|
|
//printf("address after: %p\n", numbers);
|
|
|
|
|
value = maximum(n, &numbers); |
|
|
|
|
MPI_Send(&value, 1, MPI_INT, 0, 1, MPI_COMM_WORLD); |
|
|
|
|
} |
|
|
|
|
//MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
|
|
|
|
|
//MPI_Get_count(&status, MPI_INT, &n);
|
|
|
|
|
|
|
|
|
|
//if (n != MPI_UNDEFINED && n >= 2) {
|
|
|
|
|
//int *numbers = my_malloc(n * sizeof(int));
|
|
|
|
|
|
|
|
|
|
////printf("address before: %p\n", numbers);
|
|
|
|
|
//MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
|
|
|
|
|
////printf("address after: %p\n", numbers);
|
|
|
|
|
//value = maximum(n, numbers);
|
|
|
|
|
//MPI_Send(&value, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
|
|
|
|
|
//}
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MPI_Finalize(); |
|
|
|
|
return (0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int maximum(int n, int **numbers) { |
|
|
|
|
int maximum(int n, int *numbers) { |
|
|
|
|
int value = 0;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
if (value < (*numbers)[i]) { |
|
|
|
|
value = (*numbers)[i];
|
|
|
|
|
if (value < numbers[i]) { |
|
|
|
|
value = numbers[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int *array_slice(int n, int **numbers, int start, int count) { |
|
|
|
|
int *slice = my_malloc(count * sizeof(int *)); |
|
|
|
|
int *array_slice(int n, int *numbers, int start, int count) { |
|
|
|
|
int *slice = my_malloc(count * sizeof(int)); |
|
|
|
|
for (int i = 0; i < count && i < n; i++)
|
|
|
|
|
slice[i] = (*numbers)[start + i];
|
|
|
|
|
slice[i] = numbers[start + i];
|
|
|
|
|
|
|
|
|
|
return slice; |
|
|
|
|
} |
|
|
|
|