0

2 つの配列 (それぞれ長さ n) をルート プロセス (ランク = 0) の受信バッファーに結合して、長さ 2*n の配列、つまりすべての値を含む単一の配列を形成しようとしています。

簡潔にするために、私のコードは次のようになります。

#define ROOT 0

int myFunction(int* rBuf, int n) {
  int* sBuf = malloc(n*sizeof(int));

  // Do work, calculate offset, count etc.

  MPI_Reduce(sBuf, rBuf+offset[rank], counts[rank], 
             MPI_INT, MPI_SUM, ROOT, MPI_COMM_WORLD);
}
// where offset[rank] is amount to offset where it is to be received
// offset[0] = 0, offset[1] = n
// counts contains the length of arrays on each process

ただし、rBuf をチェックすると、オフセットなしで rBuf に縮小されます。次に例を示します。

// Rank 0: sBuf = {3, 2}
// Rank 1: sBuf = {5, 1}
// Should be rBuf = {3, 2, 5, 1}    
rBuf = {8, 3, 0, 0}

追加情報:

  • rBuf は、削減前に値が 0 で正しいサイズに初期化されます
  • すべてのプロセスにはオフセット配列があります
  • その時点で MPI_Reduce を使用した理由は、rBuf が 0 に設定されている場合、MPI_SUM で削減すると必要な答えが得られるためです。

ドキュメント、オンラインのチュートリアル/ガイド、そしてもちろんSOを調べましたが、何が間違っているのかまだわかりません。

答えとして、私は特に探しています:

  1. これは MPI_Reduce を使用して技術的に可能ですか?
  2. 私の MPI_Reduce 呼び出しは正しいですか? (ポインタ演算のエラー?)
  3. MPI を使用した実行可能/適切なプラクティスはありますか、それともより良いアプローチですか?

ありがとう

4

2 に答える 2

2

収集 (および分散) については、この回答で詳しく説明しています。

ReduceGatherは関連していますが、異なる操作です。MPI_Reduceこれらのベクトルを呼び出したとき

// Rank 0: sBuf = {3, 2}
// Rank 1: sBuf = {5, 1}

Reduce はまさに正しいことを行いました。さまざまな を取り、sBufそれらを追加して (データに対して操作を実行するように指示したためMPI_SUM)、 を与え{8,3} == {3,2} + {5,1}、結果をルート プロセッサの受信バッファーに入れます。(後で全員に答えてもらいたい場合は、MPI_Allreduce()代わりに使用してください。) ただし、Reduce への呼び出しに注意してください。

 MPI_Reduce(sBuf, rBuf+offset[rank], counts[rank], 
             MPI_INT, MPI_SUM, ROOT, MPI_COMM_WORLD);

実際には有効ではありません。Reduce の場合、全員が同じカウントで呼び出しを行う必要があります。そして、rBuf重要なのはルート プロセス上のものだけで、この場合はランク 0 です。

一方、Gather もすべてのデータを収集しますが、合計、積、xor などの操作でデータを折りたたむ代わりに、結果を連結します。

于 2013-04-12T11:58:06.507 に答える
0

だから私は MPI_Gatherv を試してみましたが、それは問題を修正したようで、配列の数とサイズがはるかに大きいことを確認しました。

これが私がしたことです:

MPI_Gatherv(sBuf, counts[rank], MPI_INT, c, counts, offset, MPI_INT, 
            ROOT, MPI_COMM_WORLD);

MPI_Gather も試しましたが、うまくいきませんでした (実際には、reduce 呼び出しに同様の方法でオフセットを渡しても、実際の効果はありませんでした)。

このことから、私の特定の質問に関する私の理解は次のとおりです。

  1. これは不可能です/MPI_Reduce の意図した使用例ではありません
  2. したがって、reduce 呼び出しは正しくありません。呼び出しにオフセットを含めても効果はありません
  3. 正しいアプローチは、MPI_Gatherv を使用することです。これは、このライブラリ呼び出しが具体的に対処するものであるためです (受信バッファーの変位)。

より経験豊富な MPI ユーザーが参加したい場合は、素晴らしいことです。

ありがとう

于 2013-04-12T07:50:58.600 に答える