MPI_Gather并行编程中的问题

时间:2010-12-19 13:43:34

标签: parallel-processing mpi

我是插入并行编程的新手。根据我的理解,我尝试自己编码。然后我发现,我在MPI_Gather中不理解。我们先看一下代码然后再解释一下。

#include "mpi.h"
#include <stdio.h>
int main (int argc, char *argv[]) {
int size;
int rank;
int a[12];
int i;
int start,end;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        a[i] = 100;
    }
}

start = 12/size*rank;
end = 12/size*(rank+1);
for(i=start;i<end;i++)
{
    a[i] = rank;
    printf("rank %d set a[%d] equal to %d\n",rank,i,rank);
}
MPI_Gather(&a[start],12/size*rank,MPI_INT,a,12/size*rank,MPI_INT,0,MPI_COMM_WORLD);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        printf("%d    %d\n",i,a[i]);
    }
}
MPI_Finalize();
return 0;
}

对于这段代码,我的目标是收集在每个进程中生成的子数组中的值,并将其保存在数组a中。然后让进程0打印它。

首先,我将数组中的所有值初始化为100

然后,我计算每个过程的起始索引和结束索引(在这种情况下,过程的数量多为12的倍数)

接下来,我将值赋给等于它的数组

接下来,我收集它

最后,我将它打印在屏幕上

这是尺寸= 3

的3个过程的输出

等级2设定[8]等于2

等级2设定[9]等于2

等级2设定[10]等于2

等级2设定[11]等于2

等级1将a [4]设为等于1

等级1设置[5]等于1

等级1设定[6]等于1

等级1设定[7]等于1

rank 0将a [0]设为0

等级0设定[1]等于0

等级0将a [2]设为等于0

等级0设定[3]等于0

0 0

1 0

2 0

3 0

4 100

5 100

6 100

7 100

8 100

9 100

10 100

11 100

如您所见,聚集只收集第一长度的数据,我该如何修复它。

提前谢谢。

2 个答案:

答案 0 :(得分:7)

恭喜你,你第一次尝试就差不多了。

您需要将MPI_Gather行更改为

MPI_Gather(&a[start],12/size,MPI_INT,a,12/size,MPI_INT,0,MPI_COMM_WORLD);

MPI_Gather的签名是

#include "mpi.h"
int MPI_Gather ( void *sendbuf, int sendcnt, MPI_Datatype sendtype, 
                void *recvbuf, int recvcount, MPI_Datatype recvtype, 
                int root, MPI_Comm comm )

所以你有sendbufsendtyperecvbufrecvtyperootcomm正确无误;问题是重要的。您不想发送12/size*rankstart,整数;您希望发送12/size或仅end-start个整数,并从每个进程中接收这些整数。

MPI_Gather要求每个进程都发送相同数量的信息(如果没有,则要使用MPI_Gatherv())。在你的情况下,第一个进程被告知发送0,第二个发送4,第三个发送8;标准没有说明在这种情况下该做什么,看起来最终没有发送任何东西。 (或者当然没有收到;你的根进程0被告知发送0个整数,所以它可能预计会有0个intg来自其他任务)。所以你剩下的就是在聚集之前0级的成绩; 100除了它自己的值,它们都是0。

通过更正聚集,您应该得到正确的结果:

rank 0 set a[0] equal to 0
rank 0 set a[1] equal to 0
rank 0 set a[2] equal to 0
rank 0 set a[3] equal to 0
rank 1 set a[4] equal to 1
rank 1 set a[5] equal to 1
rank 1 set a[6] equal to 1
rank 1 set a[7] equal to 1
rank 2 set a[8] equal to 2
rank 2 set a[9] equal to 2
rank 2 set a[10] equal to 2
rank 2 set a[11] equal to 2
0    0
1    0
2    0
3    0
4    1
5    1
6    1
7    1
8    2
9    2
10    2
11    2

答案 1 :(得分:0)

Plz,试试那个代码!

#include "mpi.h"
#include <stdio.h>
int main (int argc, char *argv[]) {
int size;
int rank;
int a[12] , b[12];
int i;
int start,end;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        a[i] = 100;
    }
}

start = 12/size*rank;
end = 12/size*(rank+1);
for(i=start;i<end;i++)
{
    a[i] = rank;
    printf("rank %d set a[%d] equal to %d\n",rank,i,rank);
}
MPI_Gather(&a[start],12/size,MPI_INT,b,12/size,MPI_INT,0,MPI_COMM_WORLD);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        printf("%d    %d\n",i,b[i]);
    }
}
MPI_Finalize();
return 0;
}