并行数组元素的总和?
Sum of the element of an array in parallel?
我正在尝试编写一个 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, 2, MPI_INT, 0, 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, MPI_INT, &sub_sums, 1, MPI_INT, 0,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):
您注意到根等级(即等级= 0)也接收了部分数据。
The problem is one of the processes receives two elements but the
other one receives random numbers.
MPI_Scatter(number, 2, MPI_INT, &number1, 2, MPI_INT, 0, MPI_COMM_WORLD);
因此您已将输入硬编码如下 number{1,3,5,9}
(只有 4 个元素);在 MPI_Scatter
调用期间发生的是 process 0
将从数组 number
中获取第一个和第二个元素(即 {1, 3}
),而 process 1
得到另外两个元素(即 {5, 9}
),而 process 2
将得到一些随机值,因此:
I'm process 2 , I received the array : 1494772352 32767
你得到
数组之和为:14
因为数组 sub_sums
将由 process 0
和 process 1
执行总和,因为你排除了它,它是零,而 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, 2, MPI_INT, &number1, 2, MPI_INT, 0, MPI_COMM_WORLD);
printf("I'm process %d , I received the array : ",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_INT, MPI_SUM,0,MPI_COMM_WORLD);
if(world_rank == 0)
printf("\nthe sum of array is: %d\n",sum);
MPI_Finalize();
return 0;
}
输入 : {1,3,5,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
我正在尝试编写一个 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, 2, MPI_INT, 0, 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, MPI_INT, &sub_sums, 1, MPI_INT, 0,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):
您注意到根等级(即等级= 0)也接收了部分数据。
The problem is one of the processes receives two elements but the other one receives random numbers.
MPI_Scatter(number, 2, MPI_INT, &number1, 2, MPI_INT, 0, MPI_COMM_WORLD);
因此您已将输入硬编码如下 number{1,3,5,9}
(只有 4 个元素);在 MPI_Scatter
调用期间发生的是 process 0
将从数组 number
中获取第一个和第二个元素(即 {1, 3}
),而 process 1
得到另外两个元素(即 {5, 9}
),而 process 2
将得到一些随机值,因此:
I'm process 2 , I received the array : 1494772352 32767
你得到
数组之和为:14
因为数组 sub_sums
将由 process 0
和 process 1
执行总和,因为你排除了它,它是零,而 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, 2, MPI_INT, &number1, 2, MPI_INT, 0, MPI_COMM_WORLD);
printf("I'm process %d , I received the array : ",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_INT, MPI_SUM,0,MPI_COMM_WORLD);
if(world_rank == 0)
printf("\nthe sum of array is: %d\n",sum);
MPI_Finalize();
return 0;
}
输入 : {1,3,5,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