MPIのMPI_Allgather関数とMPI_Alltoall関数の主な違いは何ですか?
つまり、MPI_Allgatherが役立つが、MPI_Alltoallが役に立たない例を誰かに教えてもらえますか?およびその逆。
主な違いがわかりませんか?どちらの場合も、すべてのプロセスがsend_cnt要素をコミュニケーターに参加している他のすべてのプロセスに送信して受信しているように見えますか?
ありがとうございました
MPIのMPI_Allgather関数とMPI_Alltoall関数の主な違いは何ですか?
つまり、MPI_Allgatherが役立つが、MPI_Alltoallが役に立たない例を誰かに教えてもらえますか?およびその逆。
主な違いがわかりませんか?どちらの場合も、すべてのプロセスがsend_cnt要素をコミュニケーターに参加している他のすべてのプロセスに送信して受信しているように見えますか?
ありがとうございました
写真には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 == 1
sendcnt == 0
MPI_Allgather
MPI_Alltoall
n_procs
MPI_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
withのアクションをシミュレートすることはできません。MPI_Allgather
これらの2つの方法は確かに非常に似ていますが、2つの方法には1つの決定的な違いがあるようです。
MPI_Allgatherは、受信バッファーにまったく同じデータを持つ各プロセスで終了し、各プロセスは配列全体に単一の値を提供します。たとえば、一連のプロセスのそれぞれが、状態に関する単一の値を他のすべての人と共有する必要がある場合、それぞれが単一の値を提供します。これらの値はすべての人に送信されるため、すべての人が同じ構造のコピーを持ちます。
MPI_Alltoallは、同じ値を他のプロセスに送信しません。各プロセスは、他のプロセスと共有する必要がある単一の値を提供する代わりに、他のプロセスに与える1つの値を指定します。つまり、n個のプロセスでは、それぞれが共有するn個の値を指定する必要があります。次に、プロセッサjごとに、そのk番目の値が受信バッファ内のk番目のインデックスを処理するために送信されます。これは、各プロセスに他のプロセスごとに1つの固有のメッセージがある場合に役立ちます。
最後に、allgatherとalltoallを実行した結果は、各プロセスが送信バッファーを同じ値で満たした場合でも同じになります。唯一の違いは、allgatherの方がはるかに効率的である可能性が高いということです。