MPI_Reduce无法按预期工作

我是MPI的新手,我正在尝试使用MPI_Reduce来查找整数数组的最大值。 我有一个大小为arraysize的整数数组arr ,这是我的代码:

 MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &number_of_processes); MPI_Comm_rank(MPI_COMM_WORLD, &my_process_id); MPI_Bcast(arr, arraysize, MPI_INT, 0, MPI_COMM_WORLD); MPI_Reduce(arr, &result, arraysize, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); if(!my_process_id){ printf("%d", result); } MPI_Finalize(); 

我的程序编译并运行8个进程,没有任何问题,但是,屏幕上没有任何内容。 出于调试目的,我将条件更改为if(my_process_id) (不带! )并运行。 然后我得到一个奇怪的输出,例如00030000 ,其中3可能在这个列表中的任何地方都是不确定的。 3是我的数组的第一个值(但不是最大值)。 我一般都知道并行编程(不是专家,但我通常知道我在做什么)但我对MPI很新,我可能会犯一个明显的错误。 我在网上看到的所有教程都有类似于我的代码示例,我不知道我做错了什么。

谢谢,

能够。

MPI_Reduce完全按照预期的方式工作。 你是那种不按照它应该使用的方式使用它的人。

MPI_Reduce执行数据的MPI_Reduce 元素减少,分布在MPI作业的等级中。 源缓冲区和目标缓冲区都应该是大小为arraysize数组,例如:

 int arr[arraysize]; int result[arraysize]; // Fill local arr with meaningful data ... // Perform reduction MPI_Reduce(arr, result, arraysize, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); 

MPI_Reduce作用如下:

 result[0] = max(arr_0[0], arr_1[0], ..., arr_(N-1)[0]); result[1] = max(arr_0[1], arr_1[1], ..., arr_(N-1)[1]); ... result[arraysize-1] = max(arr_0[arraysize-1], ..., arr_(N-1)[arraysize-1]); 

其中arr_0是等级0中arr的副本, arr_1是等级1中arr的副本,依此类推。

MPI_Bcast的组合,随后是MPI_Bcast的减少确实没有什么,因为arr所有副本在广播之后将具有相同的值,并且元素max减少的应用将简单地产生相同的值。 更糟糕的是,我认为你的代码中的result是一个标量整数变量,因此MPI_Reduce会覆盖过去的result arraysize-1元素,很可能会破坏堆栈帧,覆盖排名0my_process_id的值,所以它不再是0 (因此没有打印任何内容)并且之后崩溃等级0 。 当然,这一切都取决于局部变量在堆栈中是如何排列的 – 其含义可能不像我所描述的那样严重。

如果您想要找到数组的最大值,您应该首先使用MPI_Scatter分发它,然后使用MPI_Reduce执行MPI_Reduce元素减少,然后对结果执行另一个减少:

 int elements_per_proc = arraysize/number_of_processes; int arr[arraysize]; int subarr[elements_per_proc]; int partres[elements_per_proc]; // Distribute the array MPI_Scatter(arr, elements_per_proc, MPI_INT, subarr, elements_per_proc, MPI_INT, 0, MPI_COMM_WORLD); // Perform element-wise max reduction MPI_Reduce(subarr, partres, elements_per_proc, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); // Take the highest of the partial max values result = partres[0]; for (int i = 1; i < elements_per_proc; i++) if (partres[i] > result) result = partres[i]; 

现在,您拥有result最大元素的值。

甚至更好:

 int localmax; // Distribute the array MPI_Scatter(arr, elements_per_proc, MPI_INT, subarr, elements_per_proc, MPI_INT, 0, MPI_COMM_WORLD); // Find the maximum element of the local subarray localmax = subarr[0]; for (int i = 1; i < elements_per_proc; i++) if (subarr[i] > localmax) localmax = subarr[i]; // Perform global max reduction MPI_Reduce(&localmax, &result, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);