gpt4 book ai didi

c - MPI_Reduce 没有按预期工作

转载 作者:行者123 更新时间:2023-12-04 05:21:14 29 4
gpt4 key购买 nike

我对 MPI 很陌生,我正在尝试使用 MPI_Reduce 来查找整数数组的最大值。我有一个整数数组 arr尺寸arraysize ,这是我的代码:

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 作业的等级中。源缓冲区和目标缓冲区都应该是大小为 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_0arr 的副本排名 0, arr_1arr 的副本排名 1,以此类推。
MPI_Bcast的组合,然后用 MPI_MAX 减少由于 arr 的所有副本,什么都不做在广播和逐元素应用后将具有相同的值 max减少只会产生相同的值。更糟糕的是,我认为 result在您的代码中是一个标量整数变量,因此 MPI_Reduce会覆盖 arraysize-1过去的元素 result并且很可能会破坏堆栈帧,覆盖 my_process_id 的值排名 0所以它不会是 0不再(因此没有打印任何内容)和崩溃排名 0之后。当然,这完全取决于局部变量在堆栈中的排列方式——其影响可能没有我描述的那么严重。

如果你想找到一个数组的最大值,你应该首先使用 MPI_Scatter 分配它。 ,然后使用 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);

关于c - MPI_Reduce 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13666002/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com