MPI_Allgather 関数と MPI_Alltoall 関数の違いは何ですか? 質問する

MPI_Allgather 関数と MPI_Alltoall 関数の違いは何ですか? 質問する

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

つまり、MPI_Allgather が役立ち、MPI_Alltoall が役立たない例を誰か教えていただけますか? またその逆も教えてください。

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

ありがとう

ベストアンサー1

一枚の写真は千の言葉よりも雄弁なので、ここにいくつかの 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_AlltoallMPI_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 つの必要条件は、両方の場合の送信バッファのサイズが等しい、つまり になることです。これは、つまりプロセスが 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_Alltoallはのアクションをシミュレートすることはできません。MPI_Allgather

おすすめ記事