如何解决并行数组元素的总和?
我正在尝试编写一个 MPI 程序来计算整数数组的总和。
为此,我使用 MPI_Scatter
将数组块发送到其他进程,然后使用 MPI_Gather 获取根进程(进程 0)每个块的总和。
问题是其中一个进程接收两个元素,而另一个进程接收随机数。我正在用 3 个进程运行我的代码。
这是我所拥有的:
#include <stdio.h>
#include <mpi.h>
int main(int argc,char *argv[]){
MPI_Init(NULL,NULL); // Initialize the MPI environment
int world_rank;
int world_size;
MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);
MPI_Comm_size(MPI_COMM_WORLD,&world_size);
int number1[2]; //buffer for processes
int sub_sum = 0;
int sub_sums[2];
int sum;
int number[4];
if(world_rank == 0){
number[0]=1;
number[1]=3;
number[2]=5;
number[3]=9;
}
//All processes
MPI_Scatter(number,2,MPI_INT,&number1,MPI_COMM_WORLD);
if(world_rank!=0){
printf("I'm process %d,I received the array : ",world_rank);
for(int i=0 ; i<2 ; i++){
printf("%d ",number1[i]);
sub_sum = sub_sum + number1[i];
}
printf("\n");
}
MPI_Gather(&sub_sum,1,&sub_sums,MPI_COMM_WORLD);
if(world_rank == 0){
sum=0;
for(int i=0; i<2;i++){
sum+= sub_sums[i];
}
printf("\nthe sum of array is: %d\n",sum);
}
MPI_Finalize();
return 0;
}
结果:
I'm process 1,I received the array : 5 9
I'm process 2,I received the array : 1494772352 32767
the sum of array is: 14
解决方法
您似乎误解了 MPI 的工作原理;您的代码是硬编码的,只有两个进程才能(正确)工作。但是,您尝试使用 3 个进程运行代码,错误地假设 MPI_Scatter
调用期间根等级只会将数据发送到其他进程。如果您查看以下图片(取自 source):
您注意到根排名(即 rank = 0)也接收部分数据。
问题是其中一个进程接收了两个元素,但是 另一个接收随机数。
MPI_Scatter(number,2,MPI_INT,&number1,MPI_COMM_WORLD);
因此,您对输入进行了硬编码,如下所示 number{1,3,5,9}
(只有 4 个元素);在 MPI_Scatter
调用期间发生的是 process 0
将从数组 number
中获取第一个和第二个元素(ie, {1,3}
),而 process 1
获得其他两个元素(ie, {5,9}
),而 process 2
将获得一些随机值,因此:
我正在处理 2 ,我收到了数组:1494772352 32767
你得到
数组的总和为:14
因为数组 sub_sums
将具有由 process 0
执行的总和,因为您排除了它为零,而 process 1
为 3 + 9。因此,0 + 14 = 14
。
要解决此问题,您需要从以下位置删除 if(world_rank!=0)
:
if(world_rank!=0){
printf("I'm process %d,I received the array : ",world_rank);
for(int i=0 ; i<2 ; i++){
printf("%d ",number1[i]);
sub_sum = sub_sum + number1[i];
}
printf("\n");
}
并且只用 2 个进程运行你的代码。
对于最后一步而不是 MPI_Gather
,您可以使用 MPI_Reduce 并行执行求和并直接在根秩上收集值。因此,您无需在根等级上手动执行求和。
运行示例:
int main(int argc,char *argv[]){
MPI_Init(NULL,NULL); // Initialize the MPI environment
int world_rank;
int world_size;
MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);
MPI_Comm_size(MPI_COMM_WORLD,&world_size);
int number1[2];
int number[4];
if(world_rank == 0){
number[0]=1;
number[1]=3;
number[2]=5;
number[3]=9;
}
//All processes
MPI_Scatter(number,MPI_COMM_WORLD);
printf("I'm process %d,world_rank);
int sub_sum = 0;
for(int i=0 ; i<2 ; i++){
printf("%d ",number1[i]);
sub_sum = sub_sum + number1[i];
}
printf("\n");
int sum = 0;
MPI_Reduce(&sub_sum,&sum,1,MPI_SUM,MPI_COMM_WORLD);
if(world_rank == 0)
printf("\nthe sum of array is: %d\n",sum);
MPI_Finalize();
return 0;
}
输入:{1,9} 运行 2 个进程
输出
I'm process 0,I received the array : 1 3
I'm process 1,I received the array : 5 9
the sum of array is: 18
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。