C 为什么MPI_Alltoallv函数接口强制数据只属于一个数组?
假设我有3个进程,每个进程都希望向进程0、1和2发送3个数组C 为什么MPI_Alltoallv函数接口强制数据只属于一个数组?,c,mpi,C,Mpi,假设我有3个进程,每个进程都希望向进程0、1和2发送3个数组a0、a1、a2。 给定MPI\u Alltoallv接口,即 int MPI_Alltoallv(const void *sendbuf, const int *sendcounts, const int *sdispls, MPI_Datatype sendtype, void *recvbuf, const int *recvcounts, const int *rdispls, M
a0、a1、a2
。
给定MPI\u Alltoallv
接口,即
int MPI_Alltoallv(const void *sendbuf, const int *sendcounts, const int *sdispls, MPI_Datatype sendtype,
void *recvbuf, const int *recvcounts, const int *rdispls, MPI_Datatype recvtype,
MPI_Comm comm)
接口强制将a0、a1、a2的内容连接到sendbuf
数组中(可能以非连续方式)。但是这对于实现MPI\u Alltoallv
真的是必要的吗?我认为sendbuf最终必须重新划分为a0、a1、a2
,因为最终,接收过程是不同的。(这同样适用于recvbuf
)
为什么界面不符合以下要求:
int MPI_Alltoallv(const void **sendbuf, const int *sendcounts, MPI_Datatype sendtype,
void **recvbuf, const int *recvcounts, MPI_Datatype recvtype,
MPI_Comm comm)
我应该在哪里,例如,int*sendbuf[3]={a0,a1,a2}
?(接收阵列也是如此)
MPI接口是因为:
表演?(见下文)
Fortran兼容性
还有别的吗
这些原因是否也适用于MPI\u Neighbor\u alltoall\u v
我是唯一一个对这种“在连接的数组中复制,然后MPI将拆分它,然后您将收到另一个连接的数组,您可能需要立即再次拆分”感到恼火的人吗
=======================================
性能:经过一些研究
sdispls
,它是不受保证的
int my\u Alltoallv(const void**sendbuf,const int*scounts,MPI\u数据类型stype,
void**recvbuf,const int*rcounts,MPI_数据类型rtype,
MPI_通信(通信){
国际大学排名;
MPI_通信大小(通信和n_等级);
int*sdispls=(*)malloc(n_秩*sizeof(int);
int*rdispls=(*)malloc(n_秩*sizeof(int);
对于(int i=0;i)您对MPI标准应该是什么的评论最好直接发送到MPI论坛(请参阅上的说明)。同时,您可以使用MPI\u Alltoallw()
和MPI\u BOTTOM
@GillesGouaillardet“您对MPI标准应该是什么的评论”嗯,我不知道标准应该是什么,这就是为什么我想这么理解它。糟糕,我假设你认为标准应该不那么烦人。@GillesGouaillardet我认为根据C,对不同数组使用MPI\u Alltoallw()
是未定义的行为。中给出的等效操作需要sdispls[I]
其中sdispls[i]
将是例如a[i]-MPI\u BOTTOM
,不在同一数组中的两个指针的差异。这是未定义的行为(但可以肯定的是,它通常做正确的事情…更糟糕的是:D)。MPI\u Get\u地址(a[i],&sdispls[i])
。请随意解释为什么这是未定义的行为。
int my_Alltoallv(const void **sendbuf, const int *scounts, MPI_Datatype stype,
void **recvbuf, const int *rcounts, MPI_Datatype rtype,
MPI_Comm comm) {
int n_rank;
MPI_Comm_size(comm,&n_rank);
int* sdispls = (*)malloc(n_rank*sizeof(int);
int* rdispls = (*)malloc(n_rank*sizeof(int);
for (int i=0; i<n_rank; ++i) {
MPI_Aint sdispls_i;
MPI_Aint rdispls_i;
MPI_Get_address(sendbuf[i],&sdispls_i);
MPI_Get_address(recvbuf[i],&rdispls_i);
sdispls[i] = sdispls_i; // Warning: narrowing from MPI_Aint to int
rdispls[i] = rdispls_i; // Warning: narrowing from MPI_Aint to int
}
return MPI_Alltoallv(MPI_BOTTOM, scounts, sdispls, stype, // is MPI_BOTTOM+sdispls[i] == sendbuf[i] regarding C and MPI ?
MPI_BOTTOM, rcounts, rdispls, rtype, // is MPI_BOTTOM+rdispls[i] == recvbuf[i] regarding C and MPI ?
comm);
}