MPI_Allgather和MPI_Alltoall函数之间的区别?

Kra*_*mar 24 mpi

MPI中的MPI_Allgather和MPI_Alltoall函数之间的主要区别是什么?

我的意思是,有人可以给我一些例子,其中MPI_Allgather会有所帮助而MPI_Alltoall不会吗?反之亦然.

我无法理解主要区别?看起来在这两种情况下,所有进程都会将send_cnt元素发送给参与通信器的每个其他进程并接收它们?

谢谢

Hri*_*iev 67

一张图片说的超过千字,所以这里有几张ASCII艺术图片:

rank    send buf                        recv buf
----    --------                        --------
 0      a,b,c         MPI_Allgather     a,b,c,A,B,C,#,@,%
 1      A,B,C        ---------------->  a,b,c,A,B,C,#,@,%
 2      #,@,%                           a,b,c,A,B,C,#,@,%
Run Code Online (Sandbox Code Playgroud)

这只是常规的MPI_Gather,只有在这种情况下,所有进程都接收数据块,即操作是无根的.

rank    send buf                        recv buf
----    --------                        --------
 0      a,b,c          MPI_Alltoall     a,A,#
 1      A,B,C        ---------------->  b,B,@
 2      #,@,%                           c,C,%

(a more elaborate case with two elements per process)

rank    send buf                        recv buf
----    --------                        --------
 0      a,b,c,d,e,f    MPI_Alltoall     a,b,A,B,#,@
 1      A,B,C,D,E,F  ---------------->  c,d,C,D,%,$
 2      #,@,%,$,&,*                     e,f,E,F,&,*
Run Code Online (Sandbox Code Playgroud)

(如果每个元素都被发送它的等级着色,那么看起来会更好......)

MPI_Alltoall可以作为组合MPI_ScatterMPI_Gather-在每个过程中的发送缓冲器在拆分像MPI_Scatter,然后组块中的每一列由相应的过程,其秩的块列的数目相匹配聚集.MPI_Alltoall也可以看作是一个全局转置操作,作用于数据块.

有两种操作可以互换的情况吗?要正确回答这个问题,必须简单地分析发送缓冲区中数据的大小和接收缓冲区中数据的大小:

operation      send buf size      recv buf size
---------      -------------      -------------
MPI_Allgather  sendcnt            n_procs * sendcnt
MPI_Alltoall   n_procs * sendcnt  n_procs * sendcnt
Run Code Online (Sandbox Code Playgroud)

接收缓冲区大小实际上是n_procs * recvcnt,但MPI要求发送的基本元素的数量应该等于接收的基本元素的数量,因此如果在发送和接收部分中使用相同的MPI数据类型MPI_All...,则recvcnt必须等于sendcnt.

很明显,对于相同大小的接收数据,每个进程发送的数据量是不同的.为了使两个操作相等,一个必要条件是两种情况下发送的缓冲区的大小相等,即n_procs * sendcnt == sendcnt,只有当n_procs == 1只有一个进程,或者如果sendcnt == 0没有数据被发送时才可能一点都不 因此,在两种操作都可以互换的情况下,没有实际可行的情况.但可以模拟MPI_AllgatherMPI_Alltoall通过重复n_procs在发送缓冲区倍相同的数据(如已经由泰勒吉尔说明).以下是MPI_Allgather使用单元素发送缓冲区的操作:

rank    send buf                        recv buf
----    --------                        --------
 0      a             MPI_Allgather     a,A,#
 1      A            ---------------->  a,A,#
 2      #                               a,A,#
Run Code Online (Sandbox Code Playgroud)

这里同样实现MPI_Alltoall:

rank    send buf                        recv buf
----    --------                        --------
 0      a,a,a          MPI_Alltoall     a,A,#
 1      A,A,A        ---------------->  a,A,#
 2      #,#,#                           a,A,#
Run Code Online (Sandbox Code Playgroud)

反过来是不可能的 - 在一般情况下无法模拟MPI_Alltoallwith 的动作MPI_Allgather.

  • 一个非常好的答案.特别是插图和图片,这个概念非常清晰.谢谢Hristo Iliev (3认同)

Ton*_*hou 11

这两个截图有一个快速解释:

MPI_Allgatherv

MPI_Allgatherv

MPI_Alltoallv

MPI_Alltoallv

虽然这是MPI_Allgatherv和MPI_Alltoallv之间的比较,但它也解释了MPI_Allgather与MPI_Alltoall的不同之处.