首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在MPI中将两个数组分散在一个消息中

如何在MPI中将两个数组分散在一个消息中
EN

Stack Overflow用户
提问于 2017-05-12 18:13:41
回答 2查看 821关注 0票数 0

我正在做一项大学作业,其中有一个问题要用单列策略做矩阵向量乘法,基本上每个进程都得到矩阵的一列--让我们称之为A --因为矩阵向量定义,每个进程都得到向量的一个元素--让我们称之为x -,下面是我的函数:

代码语言:javascript
复制
double *mpiSingleColumn(const double *A,const double *x,const int size,const int rank){
    double *col=calloc(size,sizeof(double)),xi=0.0,*cols=calloc(size,sizeof(double)),*y=NULL;
    MPI_Request request;
    MPI_Iscatter(x,1,MPI_DOUBLE,&xi,1,MPI_DOUBLE,0,MPI_COMM_WORLD,&request);
    MPI_Datatype vectype,resizedvectype;
    MPI_Type_vector(size,1,size,MPI_DOUBLE,&vectype);
    MPI_Type_commit(&vectype);
    MPI_Type_create_resized(vectype,0,sizeof(double),&resizedvectype);
    MPI_Type_commit(&resizedvectype);
    MPI_Scatter(A,1,resizedvectype,col,size,MPI_DOUBLE,0,MPI_COMM_WORLD);
    MPI_Type_free(&vectype);
    MPI_Type_free(&resizedvectype);
    MPI_Wait(&request,MPI_STATUS_IGNORE);
    for(int i=0;i<size;i++)
        cols[i]=xi*col[i];
    free(col);
    if(rank==0)
        y=calloc(size,sizeof(double));
    MPI_Reduce(cols,y,size,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
    free(cols);
    return y;
}

A是矩阵,x是向量,sizeA的维数,A的维数等于x的大小,对于这个问题,rank是进程的秩。

上面的函数工作得很好,并产生了预期的结果。但是,现在我将xA分散到两个消息中,我想(如果可能的话)将它们分散到一个消息中,是的,我知道第一个散射是异步的,但仍然是一个消息。

我已经考虑过派生类型,特别是MPI_Type_create_struct,但是当我有一个结构数组(而不是这样的结构)时,它可以工作。

我还研究过MPI_Scatterv,它也适用于一个数组,我研究了MPI_Pack,它似乎最接近于我想要的东西,但我不知道如何将它与Scatter放在一起,不过我知道如何将它与Send放在一起。

我知道MPI-2RMA和MPI-3共享内存,但我想知道是否有一种方法,在消息传递风格。

那么如何做到这一点(如果可能的话)?

通过解释每一列上的函数被乘以x[i],其中i是col数,然后对得到的列进行求和,如果您进行数学运算,就会发现结果确实是A*x :)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-12 21:13:38

您(或MPI)需要将矩阵的每一列和相关值x放入一个连续的内存块中。无论您是自己还是通过MPI_Pack(),这都不重要。下面是手动执行此操作的一个示例,但它使用MPI_Pack()的结构相同:

代码语言:javascript
复制
int i;
double * buf;
double * extendedCol;
if (rank == 0) {
  buf = malloc(sizeof(*buf)*(size+1));
  // this will need to change if you don't have 1 process per column
  for (i = 0; i < size; ++i) {
    memcpy(buf+(i*(size+1)), A+(i*size),(size+1)*sizeof(*buf));
  }
}

extendedCol=malloc((size+1)*sizeof(*extendedCol));

MPI_Scatter(buf,1,resizedvectype,extendedCol,size+1,MPI_DOUBLE,0,MPI_COMM_WORLD);

for(i=0;i<size;i++) {
  cols[i]=extendedCol[size]*extendedCol[i];
}

注意,许多MPI程序的内存是有限的,所以这种内存洗牌通常不是一个选择/好主意。但是,由于您已经将所有的A存储在一个进程中,我们将假设内存不是一个问题(如果您需要将数据读入已经交织的数据结构中,或者使用这两条消息)。

编辑: Fix col -> extendedCol

票数 -1
EN

Stack Overflow用户

发布于 2021-07-21 19:31:47

您使用MPI_Type_create_struct的方法是正确的,但是您需要一个处理绝对内存地址的方法:MPI_Type_create_hindexed

但是,考虑到I变体可以重叠和流水线等等,这是一个足够有效的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43944097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档