与MPI并行的数组的总和?

以利亚以利亚

我正在尝试编写一个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调用过程进程只会将数据发送到其他进程。如果您看下面的图片(从来源获取):

在此处输入图片说明

您会注意到进程(即, rank = 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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档