MPI_Allgather和MPI_Alltoall函数之间的区别?

MPI_Allgather和MPI_Alltoall函数之间的区别?,mpi,Mpi,MPI中的MPI_Allgather和MPI_Alltoall函数之间的主要区别是什么 我的意思是,有人能给我举个例子,说明MPI_Allgather会有帮助,而MPI_Alltoall不会有帮助吗?反之亦然 我无法理解主要的区别?在这两种情况下,所有进程都会向参与通信器的每个其他进程发送并接收元素 谢谢虽然这两种方法确实非常相似,但它们之间似乎有一个关键的区别 MPI_Allgather结束时,每个进程的接收缓冲区中都有完全相同的数据,每个进程为整个数组贡献一个值。例如,如果一组进程中的每个进

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

我的意思是,有人能给我举个例子,说明MPI_Allgather会有帮助,而MPI_Alltoall不会有帮助吗?反之亦然

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


谢谢

虽然这两种方法确实非常相似,但它们之间似乎有一个关键的区别

MPI_Allgather结束时,每个进程的接收缓冲区中都有完全相同的数据,每个进程为整个数组贡献一个值。例如,如果一组进程中的每个进程都需要与其他所有进程共享有关其状态的某个值,则每个进程都将提供其单个值。然后将这些值发送给每个人,这样每个人都会有一个相同结构的副本

MPI_Alltoall不会将相同的值发送给其他进程。每个进程都指定一个值给其他进程,而不是提供一个应与其他进程共享的值。换句话说,对于n个进程,每个进程必须指定n个要共享的值。然后,对于每个处理器j,其第k个值将被发送到接收缓冲器中处理k的第j个索引。如果每个进程对每个进程都有一条唯一的消息,那么这将非常有用


最后请注意,如果每个进程使用相同的值填充其发送缓冲区,则运行allgather和alltoall的结果将是相同的。唯一的区别是allgather的效率可能要高得多。

一张图片可以表达上千字,因此这里有几张ASCII艺术图片:

rank send buf recv buf
----    --------                        --------
0 a、b、c MPI所有集合a、b、c、a、b、c、#、@、%
1 A,B,C------------------->A,B,C,A,B,C,#,@,%
2、@、%a、b、c、a、b、c、@、%
这只是常规的
MPI\u聚集
,只有在这种情况下,所有进程都接收数据块,即操作是无根的

rank send buf recv buf
----    --------                        --------
0 a,b,c所有a,a#
1 A,B,C-------->B,B@
2、@、%c、c、%
(一个更详细的案例,每个流程有两个要素)
秩发送buf recv buf
----    --------                        --------
0 a,b,c,d,e,f MPI所有a,b,a,b,#@
1 A,B,C,D,E,F-------->C,D,C,D,%$
2#,@,%,$,&*e,f,e,f,&*
(如果每个元素都由发送它的级别着色,看起来会更好,但是…)

MPI\u Alltoall
作为组合
MPI\u Scatter
MPI\u collect
工作-每个进程中的发送缓冲区像在
MPI\u Scatter
中一样被拆分,然后由相应的进程收集块的每一列,其排名与块列的编号匹配
MPI_Alltoall
也可以看作是一个全局换位操作,作用于数据块

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

操作发送buf大小recv buf大小
---------      -------------      -------------
MPI_Allgather sendcnt n_进程*sendcnt
MPI_全部到所有n_进程*发送n_进程*发送
接收缓冲区大小实际上是
n_procs*recvcnt
,但MPI要求发送的基本元素数量应等于接收的基本元素数量,因此如果在
MPI\u All…
的发送和接收部分使用相同的MPI数据类型,然后,
recvcnt
必须等于
sendcnt

很明显,对于相同大小的接收数据,每个进程发送的数据量是不同的。要使这两个操作相等,一个必要条件是两种情况下发送的缓冲区的大小相等,即
n_-procs*sendcnt==sendcnt
,这仅在
n_-procs==1
,即只有一个进程,或者
sendcnt==0
,即根本没有发送数据时才可能。因此,在实际可行的情况下,这两种操作实际上是可互换的。但是,通过重复发送缓冲区中相同数据的
n\u过程
,可以用
MPI\u Alltoall
模拟
MPI\u Allgather
(Tyler Gill已经指出)。以下是带有一个元素发送缓冲区的
MPI\u Allgather
的操作:

rank send buf recv buf
----    --------                        --------
0 a MPI\u所有集合a、a、#
1 A------------------->A,A#
2#a,a,#
在这里,使用
MPI\u Alltoall实现同样的功能:

rank send buf recv buf
----    --------                        --------
0 a,a,a MPI所有a,a#
A,A,A------------------->A,A#
二,一,一,#

相反是不可能的-在一般情况下,无法使用
MPI\u Allgather
模拟
MPI\u Alltoall
的操作。

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

MPI_Allgatherv

MPI_Alltoallv

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