MPI_Gatherv: create and collect arrays of variable size (MPI+C)

╄→гoц情女王★ 提交于 2019-12-24 08:12:34

问题


I am new to MPI and I am trying to manage arrays of different size in parallel and then pass them to the main thread, unsuccessfully so far.

I have learned that

MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
        void *recvbuf, const int *recvcounts, const int *displs,
        MPI_Datatype recvtype, int root, MPI_Comm comm)

is the way to go in this case.

Here is my sample code, which doesn't work because of memory issues (I think).

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

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

MPI_Init(&argc, &argv);
int world_size,*sendarray;
int rank, *rbuf=NULL, count;
int *displs=NULL,i,*rcounts=NULL;

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);

if(rank==0){
    rbuf = malloc(10*sizeof(int));
    displs = malloc(world_size*sizeof(int));
    rcounts=malloc(world_size*sizeof(int));
    rcounts[0]=1;
    rcounts[1]=3;
    rcounts[2]=6;

    displs[0]=1;
    displs[1]=3;
    displs[2]=6;

    sendarray=malloc(1*sizeof(int));
    for(int i=0;i<1;i++)sendarray[i]=1;
    count=1;
}

if(rank==1){
    sendarray=malloc(3*sizeof(int));
    for(int i=0;i<3;i++)sendarray[i]=2;
    count=3;
}

if(rank==2){
    sendarray=malloc(6*sizeof(int));
    for(int i=0;i<6;i++)sendarray[i]=3;
    count=6;
}
MPI_Barrier(MPI_COMM_WORLD);


MPI_Gatherv(sendarray, count, MPI_INT, rbuf, rcounts,
            displs, MPI_INT, 0, MPI_COMM_WORLD);

if(rank==0){
    int SIZE=10;
    for(int i=0;i<SIZE;i++)printf("(%d) %d ",i, rbuf[i]);

    free(rbuf);
    free(displs);
    free(rcounts);
}

if(rank!=0)free(sendarray);
MPI_Finalize();

}

Specifically, when I run it, I get

(0) 0 (1) 1 (2) 0 (3) 2 (4) 2 (5) 2 (6) 3 (7) 3 (8) 3 (9) 3

Instead of something like this

(0) 1 (1) 2 (2) 2 (3) 2 (4) 3 (5) 3 (6) 3 (7) 3 (8) 3 (9) 3

Why is that?

What is even more interesting, is that it seems like missing elements are stored in 11th and 12th element of the rbuf, even though those are supposed to not even exist at the first place.


回答1:


Your program is very close to working. If you change these lines:

displs[0]=1;
displs[1]=3;
displs[2]=6;

to this:

displs[0]=0;
displs[1]=displs[0]+rcounts[0];
displs[2]=displs[1]+rcounts[1];

you will get the expected output. The variable displs is the offset into the receiving buffer to place the data from process i.



来源:https://stackoverflow.com/questions/50514981/mpi-gatherv-create-and-collect-arrays-of-variable-size-mpic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!