【问题标题】:Sum of the element of an array in parallel?并行数组元素的总和?
【发布时间】:2021-01-18 15:06:52
【问题描述】:

我正在尝试编写一个 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

【问题讨论】:

    标签: c performance parallel-processing mpi openmpi


    【解决方案1】:

    您似乎误解了 MPI 的工作原理;您的代码经过硬编码,可以(正确)仅使用两个进程。但是,您尝试使用 3 个进程运行代码,并错误地假设在 MPI_Scatter 调用期间根级别只会将数据发送到其他进程。如果你看下图(取自source):

    您注意到根等级(等级 = 0)也接收部分数据。

    问题是其中一个进程接收两个元素,但 另一个接收随机数。

    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 将获得一些随机值,因此:

    我是进程 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, 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
    

    如果您真的只想让进程 1 和 2 接收数据并执行求和,我建议查看例程 MPI_SendMPI_Recv

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-20
      • 2017-07-02
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      • 2019-04-21
      • 1970-01-01
      • 2016-07-22
      相关资源
      最近更新 更多