There are several issues with your code.
First:
int global_max = 0;
int global_min = 0;
MPI_Reduce(&loc_data, &global_max, 1, MPI_INT, MPI_MAX, root, MPI_COMM_WORLD);
MPI_Reduce(&loc_data, &global_min, 1, MPI_INT, MPI_MIN, root, MPI_COMM_WORLD);
unfortunately,
MPI does not get the minimum of all elements in the array, you have to
do that manually. (source)
Therefore, one needs to first calculate the min
and the max
within each process' array, and then one can reduce those min
and max
results among the other processes. Since, all processes should have the min
and max
of that array, instead of MPI_Reduce, you should use MPI_Allreduce. And your code would look like the following:
int local_max = loc_data[0];
int local_min = loc_data[0];
for(int i = 1; i < loc_num; i++){
local_max = (local_max > loc_data[i]) ? local_max : loc_data[i];
local_min = (local_min < loc_data[i]) ? local_min : loc_data[i];
}
int global_max = local_max;
int global_min = local_min;
MPI_Allreduce(&local_max, &global_max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
Unless you are assuming that loc_num=1
, which you should not, this code
for(int j = 0; j< loc_num; j++){
x = loc_data[j] - global_min;
y = global_max - global_min;
}
overrides the same x
and y
. Moreover, you should not call MPI_Bcast(&y, 1, MPI_INT, root, MPI_COMM_WORLD);
, you want for all the processes to first calculate in parallel their work based on the formula:
δi = ((xi – xmin ) / (xmax – xmin )) * 100.
and only then send their work back to the master process. So each process should apply that formula to their input indices, stored the results in an array and send it back to the master process. Like so:
float loc_delta[100];
float y = global_max - global_min;
for(int j = 0; j< loc_num; j++){
loc_delta[j] = (((float) (loc_data[j] - global_min) / y) * 100.0);
}
float final_delta[100];
MPI_Gather(&loc_delta, loc_num, MPI_FLOAT, final_delta, loc_num, MPI_FLOAT, root, MPI_COMM_WORLD);
Notice that I am casting (((float) (loc_data[j] - global_min) / y) * 100.0);
to float. Otherwise, C
would return an int
representation of the result.