24

MPIのMPI_Allgather関数とMPI_Alltoall関数の主な違いは何ですか?

つまり、MPI_Allgatherが役立つが、MPI_Alltoallが役に立たない例を誰かに教えてもらえますか?およびその逆。

主な違いがわかりませんか?どちらの場合も、すべてのプロセスがsend_cnt要素をコミュニケーターに参加している他のすべてのプロセスに送信して受信しているように見えますか?

ありがとうございました

4

3 に答える 3

75

写真には1000を超える単語が含まれているため、ここにいくつかの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,#,@,%

これは通常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,&,*

(各要素がそれを送信するランクによって色付けされていると見栄えが良くなりますが...)

MPI_Alltoall結合されたものとして機能しMPI_ScatterますMPI_Gather-各プロセスの送信バッファーはのように分割されMPI_Scatter、チャンクの各列はそれぞれのプロセスによって収集されます。そのランクはチャンク列の数と一致します。MPI_Alltoallデータのチャンクに作用するグローバルな転置操作と見なすこともできます。

2つの操作が交換可能である場合はありますか?この質問に正しく答えるには、送信バッファ内のデータと受信バッファ内のデータのサイズを分析する必要があります。

operation      send buf size      recv buf size
---------      -------------      -------------
MPI_Allgather  sendcnt            n_procs * sendcnt
MPI_Alltoall   n_procs * sendcnt  n_procs * sendcnt

受信バッファサイズは実際n_procs * recvcntにはですが、MPIは、送信される基本要素の数が受信される基本要素の数と等しくなければならないことを義務付けています。したがって、の送信部分と受信部分の両方で同じMPIデータ型が使用される場合、はとMPI_All...等しくrecvcntなければなりませんsendcnt

受信したデータのサイズが同じ場合、各プロセスによって送信されるデータの量が異なることはすぐにわかります。2つの操作が等しくなるために必要な条件は、両方の場合に送信されるバッファーのサイズが等しいことです。つまり、プロセスが1つしかない場合、またはデータが送信されていない場合にn_procs * sendcnt == sendcntのみ可能です。まったく。したがって、両方の操作が実際に交換可能であるという実際的に実行可能なケースはありません。ただし、送信バッファで同じデータを何度も繰り返すことでシミュレートできます(Tyler Gillがすでに指摘しているように)。1要素の送信バッファを使用した場合のアクションは次のとおりです。n_procs == 1sendcnt == 0MPI_AllgatherMPI_Alltoalln_procsMPI_Allgather

rank    send buf                        recv buf
----    --------                        --------
 0      a             MPI_Allgather     a,A,#
 1      A            ---------------->  a,A,#
 2      #                               a,A,#

そしてここで同じように実装されていMPI_Alltoallます:

rank    send buf                        recv buf
----    --------                        --------
 0      a,a,a          MPI_Alltoall     a,A,#
 1      A,A,A        ---------------->  a,A,#
 2      #,#,#                           a,A,#

逆は不可能です。一般的なケースでは、MPI_Alltoallwithのアクションをシミュレートすることはできません。MPI_Allgather

于 2013-02-24T13:27:00.680 に答える
18

これらの2つのスクリーンショットには、簡単な説明があります。

MPI_Allgatherv

MPI_Allgatherv

MPI_Alltoallv

MPI_Alltoallv

これはMPI_AllgathervとMPI_Alltoallvの比較ですが、MPI_AllgatherがMPI_Alltoallとどのように異なるかについても説明しています。

于 2015-12-06T02:49:02.943 に答える
4

これらの2つの方法は確かに非常に似ていますが、2つの方法には1つの決定的な違いがあるようです。

MPI_Allgatherは、受信バッファーにまったく同じデータを持つ各プロセスで終了し、各プロセスは配列全体に単一の値を提供します。たとえば、一連のプロセスのそれぞれが、状態に関する単一の値を他のすべての人と共有する必要がある場合、それぞれが単一の値を提供します。これらの値はすべての人に送信されるため、すべての人が同じ構造のコピーを持ちます。

MPI_Alltoallは、同じ値を他のプロセスに送信しません。各プロセスは、他のプロセスと共有する必要がある単一の値を提供する代わりに、他のプロセスに与える1つの値を指定します。つまり、n個のプロセスでは、それぞれが共有するn個の値を指定する必要があります。次に、プロセッサjごとに、そのk番目の値が受信バッファ内のk番目のインデックスを処理するために送信されます。これは、各プロセスに他のプロセスごとに1つの固有のメッセージがある場合に役立ちます。

最後に、allgatherとalltoallを実行した結果は、各プロセスが送信バッファーを同じ値で満たした場合でも同じになります。唯一の違いは、allgatherの方がはるかに効率的である可能性が高いということです。

于 2013-02-24T07:34:47.157 に答える