我正在做一项大学作业,其中有一个问题要用单列策略做矩阵向量乘法,基本上每个进程都得到矩阵的一列--让我们称之为A --因为矩阵向量定义,每个进程都得到向量的一个元素--让我们称之为x -,下面是我的函数:
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是向量,size是A的维数,A的维数等于x的大小,对于这个问题,rank是进程的秩。
上面的函数工作得很好,并产生了预期的结果。但是,现在我将x和A分散到两个消息中,我想(如果可能的话)将它们分散到一个消息中,是的,我知道第一个散射是异步的,但仍然是一个消息。
我已经考虑过派生类型,特别是MPI_Type_create_struct,但是当我有一个结构数组(而不是这样的结构)时,它可以工作。
我还研究过MPI_Scatterv,它也适用于一个数组,我研究了MPI_Pack,它似乎最接近于我想要的东西,但我不知道如何将它与Scatter放在一起,不过我知道如何将它与Send放在一起。
我知道MPI-2RMA和MPI-3共享内存,但我想知道是否有一种方法,在消息传递风格。
那么如何做到这一点(如果可能的话)?
通过解释每一列上的函数被乘以x[i],其中i是col数,然后对得到的列进行求和,如果您进行数学运算,就会发现结果确实是A*x :)。
发布于 2017-05-12 21:13:38
您(或MPI)需要将矩阵的每一列和相关值x放入一个连续的内存块中。无论您是自己还是通过MPI_Pack(),这都不重要。下面是手动执行此操作的一个示例,但它使用MPI_Pack()的结构相同:
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
发布于 2021-07-21 19:31:47
您使用MPI_Type_create_struct的方法是正确的,但是您需要一个处理绝对内存地址的方法:MPI_Type_create_hindexed。
但是,考虑到I变体可以重叠和流水线等等,这是一个足够有效的解决方案。
https://stackoverflow.com/questions/43944097
复制相似问题