如何使用 MPI 发送整数数组并计算它们的阶乘?

How to send an integer array Using MPI and calculate factorial of them?

考虑进程 0 有一个整数数组,我们应该在其中计算所有的阶乘 数组中的元素。修改程序以将数组发送到计算所有的进程 1 阶乘和 return 要处理 0 的结果。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <mpi.h>
    int main (int argc, char ** argv)
    {
        int rank, size,code,tag=100;
        int a[10]={1,2,3,4,5,6,7,8,9,10};
        int count,fact = 1,i,j,k;
        MPI_Init (&argc, &argv);    /* starts MPI */
        MPI_Comm_rank (MPI_COMM_WORLD, &rank);  /* get current process id */
      
        if (rank == 0) {
           for ( i = 0; i < 9; ++i)
           {
              code=MPI_Send(&a[i],1, MPI_INTEGER,1,tag, MPI_COMM_WORLD);
              code=MPI_Recv(&fact,1, MPI_INTEGER,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
               printf("Process %d,Result=%d\n",rank,fact);
           }
        } 
       else if (rank == 1) 
       {
          for (int j = 0; j < 9; ++j)
          {
             code=MPI_Recv(&a[j],1, MPI_INTEGER,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
             count = j;
             for ( k = 0; k < count; ++k)
             {
                  fact = fact*(j+1);
                  code=MPI_Send(&fact,1, MPI_INTEGER,0,tag, MPI_COMM_WORLD);
             }
        }  
     }
      
    
      MPI_Comm_size (MPI_COMM_WORLD, &size);    /* get number of processes */
     
      MPI_Finalize();
     
     
      return 0;
    }

您的代码存在一些问题,即 MPI_INTEGER 不是有效的 MPI C data type(尽管它在 MPI fortran 中有效),MPI_INT 是。此外,您计算阶乘的方式是假设来自 process 0 的元素始终是来自 1 to N 的连续自然数。您不应该这样假设,也不需要单独发送每个元素,而是执行以下操作:

进程 0:

  1. 用值创建数组以计算它的阶乘;
  2. 创建一个数组来存储将由 process 1 发送的阶乘;
  3. 将整个数组(在 1. 中创建)发送到 process 1;
  4. 等待调用MPI_recv)等待来自进程1的结果。

进程 1:

  1. 创建一个数组来存储将由 process 0;
  2. 发送的值
  3. 等待调用MPI_recv)来自process 0的值;
  4. 创建一个数组来存储阶乘;
  5. 计算阶乘;
  6. 将它们存储在为此目的创建的数组中;
  7. 将包含阶乘的数组发送到 process 0

代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char ** argv){
    int rank, size,tag=100;
    MPI_Init (&argc, &argv);  /* starts MPI */
    MPI_Comm_rank (MPI_COMM_WORLD, &rank);    /* get current process id */
  
    if (rank == 0)
    {
        int a[10]={1,2,3,4,5,6,7,8,9,10}; // the array with the values to calculate the factorial
        int fact[10] = {0}; // the array to store the results
        MPI_Send(a, 10, MPI_INT,1,tag, MPI_COMM_WORLD); // the values 
        MPI_Recv(fact, 10, MPI_INT,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE); // wait for the result 
        for(int i = 0; i < 10; i++) // print the results;
           printf("Process %d,Result=%d\n",rank, fact[i]);
    } 
    else if (rank == 1) 
    { 
       int a[10] = {0};
       int fact[10] = {0};
       MPI_Recv(a, 10, MPI_INT,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
       for(int i = 0; i < 10; i++){
           int f = 1;
           for (int k = 1; k <= a[i]; ++k) // Calculate the factorials 
                f *= k; 
           fact[i] = f;
       }
       MPI_Send(fact,10, MPI_INT,0,tag, MPI_COMM_WORLD); // send the factorials to process 0
    }
    MPI_Comm_size (MPI_COMM_WORLD, &size);    /* get number of processes */
    MPI_Finalize();
    return 0;
}

输入: {1,2,3,4,5,6,7,8,9,10}

输出

Process 0,Result=1
Process 0,Result=2
Process 0,Result=6
Process 0,Result=24
Process 0,Result=120
Process 0,Result=720
Process 0,Result=5040
Process 0,Result=40320
Process 0,Result=362880
Process 0,Result=3628800