我是新来的mpi
,我想写一个微型C
计算百分比的程序比数字用户输入。
百分比比率由该表达式计算
`δi = ((xi – xmin ) / (xmax – xmin )) * 100`.
用户输入的数字存储在固定大小的数组中,data[100]
并分散在所有进程中(该程序仅适用于四个进程)。我面临的问题是,尽管所有过程都具有数据,但是该划分无法正常工作。例如,如果用户输入数字,{1, 2, 3, 4}
则根据数学表达式的预期百分比是,{0, 33.3, 66.6, 100}
但是我得到了{0,0,100,100}
。这就是我所拥有的。
#include <stdio.h>
#include "mpi.h"
int main(int argc, char** argv){
int my_rank;
int total_processes;
int root = 0;
int data[100];
int loc_data[100];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &total_processes);
int input_size = 0;
if (my_rank == 0){
printf("Input how many numbers: ");
scanf("%d", &input_size);
printf("Input the elements of the array: ");
for(int i=0; i<input_size; i++){
scanf("%d", &data[i]);
}
}
MPI_Bcast(&input_size, 1, MPI_INT, root, MPI_COMM_WORLD);
int loc_num = input_size/total_processes;
MPI_Scatter(&data, loc_num, MPI_INT, loc_data, loc_num, MPI_INT, root, MPI_COMM_WORLD);
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);
float loc_delta[100];
int x = 0;
int y = 0;
float p = 0;
for(int j = 0; j< loc_num; j++){
x = loc_data[j] - global_min;
y = global_max - global_min;
}
MPI_Bcast(&y, 1, MPI_INT, root, MPI_COMM_WORLD);
for(int j = 0; j< loc_num ; j++){
p = (x / y) * 100;
printf("p= %f \n", p);
loc_delta[j] = p;
}
float final_delta[100];
MPI_Gather(&loc_delta, 1, MPI_FLOAT, final_delta, 1, MPI_FLOAT, root, MPI_COMM_WORLD);
if(my_rank == 0){
printf("max number: %d\n", global_max);
printf("min number: %d\n", global_min);
for(int i = 0; i<input_size; i++)
printf("delta[%d]: %.2f | ", i+1, final_delta[i]);
}
printf("\n");
MPI_Finalize();
return 0;
}
您的代码有几个问题,其中一些在注释中指出,其他则没有。
第一:
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);
不幸,
MPI不能获取数组中所有元素的最小值,您必须手动执行此操作。(来源)
因此,你需要先计算min
和max
每个进程的阵列中,然后就可以降低其他进程中的最小值和最大值的结果。由于所有进程都应具有min
andmax
数组,而不是MPI_Reduce,因此应使用MPI_Allreduce。您的代码如下所示:
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);
这个:
for(int j = 0; j< loc_num; j++){
x = loc_data[j] - global_min;
y = global_max - global_min;
}
除非假定loc_num = 1,否则应覆盖相同的x和y,否则不应覆盖。此外,您不应调用MPI_Bcast(&y, 1, MPI_INT, root, MPI_COMM_WORLD);
,而是希望所有过程首先根据以下公式并行计算其工作:
δi = ((xi – xmin ) / (xmax – xmin )) * 100.
然后将这些流程完成的工作发送给主流程。因此,每个流程都应在输入索引中应用该公式,将其存储在数组中,然后将其发送回主流程。像这样:
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);
请注意,我正在强制(((float) (loc_data[j] - global_min) / y) * 100.0);
浮动。否则,C将返回结果的int表示形式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句