C语言中使用MPI添加数组

Adding an array using MPI in C language

我对 MPI 编程还很陌生。在下面的代码中,我尝试使用流程 1 添加前 3 个元素,使用流程 2 添加最后 3 个元素。结果应显示前三个元素为 Sum is 11,后三个元素为 Sum is 18。我看到我的问题的原因是在第 2 级(进程 2)它读取 arr[3] 作为数组的第一个元素。我真的很迷惑为什么它不能在第 2 位正确读取数组的第 3 个元素

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
        MPI_Init(&argc, &argv);
        int world_rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
        int world_size;
        MPI_Comm_size(MPI_COMM_WORLD, &world_size);
        int tag2 = 1;
        int tag1 = 2;       
        int arr[7] = { 6,2,3,9,4,5};

        printf ("\n--Current Rank: %d\n", world_rank);
        int index;
        int source = 0;
        int dest;
        if (world_rank == 0)
        {
            printf("* Rank 0 excecuting");
            index = 0;
            dest = 1;
            MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
            MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD); 

            index = 3;
            dest = 2;
            MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
            MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);
        }
        else 
        {
            int sum = 0;
            int i;
            MPI_Recv(&index, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            printf("At Rank: %d index is: %d\n", world_rank, index);
            for(i = index; i<=index+2; i++)
            {   
                printf("i: %d and arr[i]: %d\n", i, arr[i]);
                sum = arr[i]+sum;
            }
            printf("\n Sum is: %d and arr[3]: %d\n", sum, arr[3]);
        }       

        MPI_Finalize();
}

使用命令得到的结果:mpirun -np 3 test1

--Current Rank: 0

--Current Rank: 1
At Rank: 1 index is: 0
i: 0 and arr[i]: 6
i: 1 and arr[i]: 2
i: 2 and arr[i]: 3

 Sum is: 11 and arr[3]: 9 //here it shows the correct value of 3rd array element

--Current Rank: 2
At Rank: 2 index is: 3
i: 3 and arr[i]: 6 //Error happens here
i: 4 and arr[i]: 4
i: 5 and arr[i]: 5

 Sum is: 15 and arr[3]: 6 //Show the wrong array value for 3rd element
* Rank 0 excecuting

嗯,代码按照您的要求执行...

        index = 3;
        dest = 2;
        MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
        MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);

也许你想要更多:

        index = 3;
        dest = 2;
        MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
        MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD);

而其他索引是 "valid" 的事实是因为初始分配...

这段代码还有一些问题:

  1. int arr[7] = { 6,2,3,9,4,5};:也许更确切地说 int arr[] = {6,2,3,9,4,5};

  2. MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD); 应该是 MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD); 虽然我不太确定这是你打算做的。

  3. MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);:这个20是从哪里来的?不应该是3吗?

希望这对你有意义。

我是 MPI 新手。但这就是我对 MPI 的了解。如果我错了请纠正我。

  • 通常排名为 0 的进程从其他进程接收消息并打印结果或者它会进行必要的计算(在这种情况下添加它接收到的两个值)

  • 所有其他进程完成他们的工作并将其发送给进程 0。

  • 在这种情况下不需要标签,因为这只涉及简单的计算。

所以这个解决方案可以像这样简化。

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]){

        int world_rank,world_size, i;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &world_size);  

        int arr[6] = {6,2,3,9,4,5};

        printf ("Current Rank: %d\n", world_rank);

        int total = 0;

        if(world_rank != 0){//if the rank is not 0, calculate the partial sum
            int tempTotal = 0;

            for(i = 0; i < 3; i++){
                tempTotal += arr[(world_rank -1)* 3 + i];
            }

            printf("* Rank %d sending value %d\n",world_rank, tempTotal);
            MPI_Send(&tempTotal, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);//send the partial sum to process 0
            printf("* Rank %d value sent\n", world_rank);

        }else{
            printf("RANK 0 receiving values:\n");

            int temp;

            for(i = 1; i < world_size; i++){
                MPI_Recv(&temp, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);//receive partial sums from other processes

                printf("Received value %d from rank %d\n", temp, i);

                total += temp;//add the partial sum to total
            }

            printf("Sum of the array = %d\n", total);//after all partial sums arrive, print the total
        }       
        MPI_Finalize();
}

要运行代码:

mpicc mpi.c -o mpi
mpirun -np 3 ./mpi

希望对您有所帮助。