我正在做一个大学作业,其中有一个问题是使用单列策略进行矩阵 vector 乘法,基本上每个进程都会得到矩阵的一列 - 我们称之为A
- ,由于矩阵 vector 定义,每个进程都会获取 vector 的一个元素 - 让我们称之为 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
是 vector ,size
是 A
的维度,等于x
的大小,对于此问题等于进程数,rank
是进程的排名。
上面的函数完美运行并产生了预期的结果。但是,现在我将 x
和 A
分散在两条消息中,我想(如果可能的话)将它们分散在一条消息中,是的,我知道第一个分散是异步的,但它仍然是一条消息。
我考虑过派生类型,特别是MPI_Type_create_struct
,但是当我有一个我没有的结构数组时,它就可以工作。
我还研究了MPI_Scatterv
,它也适用于一个数组,我研究了MPI_Pack
,它似乎最接近我想要的,但我不'不知道如何将其与 Scatter
放在一起,但我知道如何将其与 Send
放在一起。
我知道 MPI-2 RMA 和 MPI-3 共享内存,但我想知道是否有办法以消息传递方式做到这一点。
那么如何做到这一点(如果可能的话)?
顺便解释一下上面的函数,每列都会乘以 x[i]
,其中 i
是列号,然后将结果列相加,如果您进行数学计算,您会发现结果确实是 A*x
:) 。
最佳答案
您使用 MPI_Type_create_struct
的方法是正确的,但您需要一个处理绝对内存地址的方法:MPI_Type_create_hindexed
。
但是,考虑到 I
变体可以重叠和管道化等,这是一个足够高效的解决方案。
关于c - 如何在 MPI 中的一条消息中分散两个数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43944097/