すべてのプロセッサの特定のサブセットのみからデータを収集することを除いて、allgather に似た MPI の関数を探しています。
さらに、プロセッサのランクに依存しない順序でデータを結合したいと考えています。
このような機能はありますか?そうでない場合、どうすればこれを効率的に実装できますか?
ありがとうございました!
すべてのプロセッサの特定のサブセットのみからデータを収集することを除いて、allgather に似た MPI の関数を探しています。
さらに、プロセッサのランクに依存しない順序でデータを結合したいと考えています。
このような機能はありますか?そうでない場合、どうすればこれを効率的に実装できますか?
ありがとうございました!
基本的に、問題には2つの解決策があります。最初の解決策は、データを送信する必要があるノードを配置するコミュニケーターを作成することです。ただし、収集したデータをシャッフルすることはできません。2 番目の解決策は、MPI_Gather の代わりに MPI_Gatherv を使用することです。
MPI_Gatherv は MPI_Gather と同じことを行いますが、各プロセッサから収集する要素の数とそれらを配置する場所を指定します。たとえば、プロセス 0 の 2 つの値、プロセス 1 の 3 つの値、プロセス 2 の値なし、プロセス 3 の 1 つの値を収集したいとします。
次に、次のパラメーターを指定して MPI_Gatherv を呼び出す必要があります (配列を角括弧で囲んでいるため、これは有効なコードではありません。mycount は現在のプロセスが送信する必要がある要素の数であるため、プロセス 0 では 2、プロセス 0 では 3 になります)。プロセス 1,...):
MPI_Gatherv(sendbuffer, mycount, type,
recvbuffer, [2, 3, 0, 1], [0, 2, 5, 5], type,
root, comm)
パラメータ「displs」の 2 番目の配列は、対応するプロセスから受信した要素が保存される recvbuffer 内のオフセットを指定することに注意してください。
ProcID Portion Size
0 [0, 2) 2
1 [2, 5) 3
2 [5, 5) 0
3 [5, 6) 1
たとえば、プロセス 3 からの値が最初にあり、プロセス 0 からの値が最後にあるという意味で、値をプロセスと逆の順序で保存したい場合は、代わりに次のようにする必要があります。
MPI_Gatherv(sendbuffer, mycount, type,
recvbuffer, [2, 3, 0, 1], [4, 1, 1, 0], type,
root, comm)
このように、「職業計画」は次のようになります。
ProcID Portion Size
0 [4, 6) 2
1 [1, 4) 3
2 [1, 1) 0
3 [0, 1) 1
ランダムな分布が必要な場合は、配列「displ」をランダムに生成し、一貫性を保つために(多くの)注意を払う必要があります。
最後に 2 つの注意点として、recvcounts と displs の 2 つの配列はルートにのみ関連することに注意してください。他のノードでは、null ポインターを渡しても安全です。もう 1 つの注意点は、データを送信しないノードでも MPI_Gatherv を呼び出す必要があることです。これらの場合、mycount を 0 に設定する必要があります。送信する値がないノードで MPI_Gatherv を呼び出すことを避けたい場合は、差分コミュニケーターをセットアップしてから MPI_Gatherv を呼び出す必要があります。
MPI 呼び出し自体の中で順序を変更する方法はないと思います (必要に応じて後で自分で簡単に並べ替えることができます) が、最初の問題を解決するのは比較的簡単です。
MPI では、すべての集合呼び出しが MPI_COMM_WORLD (実行の開始時に開始されたすべてのプロセスを含む) で発生する必要はありません。元のプロセス グループの任意のサブセットを含む新しいコミュニケーターを作成できます。これを行うための呼び出しは MPI_COMM_CREATE です。
MPI_COMM_CREATE を使用するには、適切な関数 (MPI_GROUP_EXCL、MPI_GROUP_INCL、MPI_GROUP_INTERSECTION など) を使用して、新しいコミュニケーターに入れたいプロセスの MPI_Group を操作する必要があります。すぐにわからない場合は、通常、これらの種類のことを行う方法を見つけることができるチュートリアルが Web 上にたくさんあります。