MPI_Gatherv:创建和收集可变大小(MPI + C)的数组 [英] MPI_Gatherv: create and collect arrays of variable size (MPI+C)

查看:775
本文介绍了MPI_Gatherv:创建和收集可变大小(MPI + C)的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是MPI的新手,我试图并行管理大小不同的数组,然后将它们传递到主线程,但到目前为止没有成功.

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.

我了解到

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

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

而不是像这样的东西

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

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

那是为什么?

更有趣的是,似乎丢失的元素存储在rbuf的第11和第12个元素中,即使这些元素本来就不应该存在.

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.

推荐答案

您的程序即将运行.如果您更改以下行:

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

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

对此:

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

您将获得预期的输出.变量displs是接收缓冲区中的偏移量,用于放置来自进程i的数据.

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

这篇关于MPI_Gatherv:创建和收集可变大小(MPI + C)的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆