我想从double数组中收集数据并同时组织它们。假设我们有2个MPI排名:
if(rank == 0)
P = {0,1,4,5,8,9};
else
P = {2,3,6,7,10,11};
我如何收集P
中的信息并按顺序找到它们,即:主文件中的P
应包含P= [0 1 2....9 10 11]
我可以按原样收集P
,然后在root
中对其进行重新组织,但是随着P
的增加,此方法效率不高。我尝试过创建一个MPI_Type_vector
,但我还没有成功。有什么想法吗?
答案 0 :(得分:2)
这取决于“按顺序”你的意思。如果您的意思是,如上例所示,每个向量由数据块组成,并且您希望这些块以固定的已知顺序交错,是的,您当然可以这样做。 (这个问题也可以解释为询问你是否可以作为聚集的一部分进行分类;这是相当困难的。)
你有正确的方法;您希望按原样发送数据,但是将数据接收到由处理器分解的指定块中。在这里,您想要接收的数据类型如下所示:
MPI_Datatype vectype;
MPI_Type_vector(NBLOCKS, BLOCKSIZE, size*BLOCKSIZE, MPI_CHAR, &vectype);
也就是说,对于给定处理器的输入,您将接收到NBLOCKS
块大小为BLOCKSIZE
的块,每个块都被块大小的许多处理器隔开。事实上,你可以接受这种类型;但是,要收集到该类型,您需要设置范围,以便将每个处理器的数据收集到正确的位置:
MPI_Datatype gathertype;
MPI_Type_create_resized(vectype, 0, BLOCKSIZE*sizeof(char), &gathertype);
MPI_Type_commit(&gathertype);
调整大小的原因在例如this answer中给出,也可能在本网站的其他地方给出。
将它们放在一起作为示例代码给出了以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
const int BLOCKSIZE=2; /* each block of data is 2 items */
const int NBLOCKS =3; /* each task has 3 such blocks */
char locdata[NBLOCKS*BLOCKSIZE];
for (int i=0; i<NBLOCKS*BLOCKSIZE; i++)
locdata[i] = 'A' + (char)rank; /* rank 0 = 'AAA..A'; rank 1 = 'BBB..B', etc */
MPI_Datatype vectype, gathertype;
MPI_Type_vector(NBLOCKS, BLOCKSIZE, size*BLOCKSIZE, MPI_CHAR, &vectype);
MPI_Type_create_resized(vectype, 0, BLOCKSIZE*sizeof(char), &gathertype);
MPI_Type_commit(&gathertype);
char *globaldata = NULL;
if (rank == 0) globaldata = malloc((NBLOCKS*BLOCKSIZE*size+1)*sizeof(char));
MPI_Gather(locdata, BLOCKSIZE*NBLOCKS, MPI_CHAR,
globaldata, 1, gathertype,
0, MPI_COMM_WORLD);
if (rank == 0) {
globaldata[NBLOCKS*BLOCKSIZE*size] = '\0';
printf("Assembled data:\n");
printf("<%s>\n", globaldata);
free(globaldata);
}
MPI_Type_free(&gathertype);
MPI_Finalize();
return 0;
}
跑步给出:
$ mpirun -np 3 ./vector
Assembled data:
<AABBCCAABBCCAABBCC>
$ mpirun -np 7 ./vector
Assembled data:
<AABBCCDDEEFFGGAABBCCDDEEFFGGAABBCCDDEEFFGG>