什么是收集所选MPI数据类型的一维数组的非均匀块的最佳方法?

时间:2016-06-03 18:00:47

标签: arrays mpi chunks

Pi表示具有等级i的MPI过程 X和Y是包含所选MPI_Datatype的1D向量 [aij]表示可以具有大小为0的子向量。

对于向量X,子向量[aij]中的索引j表示需要向哪个MPI进程[aij]发送。

对于向量Y,子向量[aij]中的索引i表示从哪个MPI进程[aij]接收。

从X构建Y的最佳策略是什么? 示意图如下所示。

P1 X = {[a11],[a12],[a13],...,[a1n]};   Y = {[a11],[a21],[a31],...,[an1]};  
P2 X = {[a21],[a22],[a23],...,[a2n]};   Y = {[a12],[a22],[a32],...,[an2]};  
P3 X = {[a31],[a32],[a33],...,[a3n]};   Y = {[a13],[a23],[a33],...,[an3]};   
...                                                               
Pn X = {[an1],[an2],[an3],...,[ann]};   Y = {[a1n],[a2n],[a3n],...,[ann]};

为方便起见,选择索引编号从一开始。

编辑(根据eduffy和francis的评论):
当虚拟通信拓扑稀疏时,即当大多数索引i,j的大小([aij])= 0时,我正在使用点对点通信来执行此操作。

  1. 确定每个MPI进程将获得的NRECV接收数。这可以通过布尔FLAG =(i!= j)&&(size([aij])!= 0)的MPI_Reduce为每个进程找到。

  2. 如果FLAG为真,每个进程i执行块[aij]的非阻塞发送以处理j。

  3. 每个进程i执行非阻塞探测并从进程j接收非零大小的块[aji]。这些动态接收可以写成NRECV迭代的循环。

  4. 然而,以符合MPI标准的方式实施此策略变得越来越困难。例如,缓冲区一次只能用于一次通信(即使是多次读取的明显无害的情况;来源:Jeff Squyres article)。

    更新:

    我发现MPI_Alltoallv()适合于子矢量[aij]的转置。但是,当通信拓扑很稀疏时,一些文章(在互联网上找到)确实报告了可扩展性问题。最近的MPI标准(超出版本3)包括具有拓扑结构的通信器上的集体通信MPI_Neighbor_alltoallv()

0 个答案:

没有答案