2011-06-26 14 views
2

私はコンピュータプログラミングのクラスで約1日間MPIで作業していましたが、今はプログラムを書く必要があります。私はプロセスを2つの環にまとめるプログラムを書くことになっています。MPIのダブルリング、最大、最小、平均

最初の呼び出しはプロセス0から始まり、次の偶数プロセスにメッセージを送信し、最後のプロセスはそのメッセージをプロセス0に戻します。たとえば、0→2→4→6 - > 8 - > 0(ただし、8の代わりに32までになります)。次のリングは同じですが、プロセス1で始まり、前のオフプロセスに送信してから1に戻ります。たとえば、1 - > 9 - > 7 - > 5 - > 3 - > 1です。

また、非常に大きな整数値の配列の最大値、最小値、平均値を見つけるはずです。私は配列を各プロセスに分割し、各プロセスが部分的な答えを計算させ、そして誰もが完了した後にプロセス0で答えを減らす必要があります。

最後に、私はプロセスに散在しており、各プロセスは各レターがセクションにどれだけ出現するかを数えなければなりません。その部分は本当に私には意味をなさない。しかし、私たちはちょうど非常に基本的なことを学んだので、すごいものはありません!これまで私がこれまで持っていたことは、いくつかのことを思い出させるためにいくつかコメントしましたので、必要ならば無視してください。 として両方は、メッセージの送信先です(混乱されようとしている、

dest = rank + 2; 
if (rank == size - 1) 
    dest = 0; 
source = rank - 2; 
if (rank == 0) 
    source = size - 1; 
私は dest考える

source、名など:

#include <iostream> 
#include "mpi.h" 

using namespace std; 
// compile: mpicxx program.cpp 
// run: mpirun -np 4 ./a.out 
int main(int argc, char *argv[]) 
{ 
int rank;  // unique number associated with each core 
int size;  // total number of cores 
char message[80]; 
char recvd[80]; 
int prev_node, next_node; 
int tag; 
MPI_Status status; 
// start MPI interface 
MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

sprintf(message, "Heeeelp! from %d", rank); 

MPI_Barrier(MPI_COMM_WORLD); 
next_node = (rank + 2) % size; 
prev_node = (size + rank - 2) % size; 


tag = 0; 
if (rank % 2) { 
    MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
    MPI_Recv(&recvd, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
} else { 
    MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
    MPI_Recv(&recvd, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
} 

cout << "* Rank " << rank << ": " << recvd << endl; 

//max 
int large_array[100]; 

rank == 0; 
int max = 0; 

MPI_Scatter(&large_array, 1, MPI_INT, large_array, 1, MPI_INT, 0, MPI_COMM_WORLD); 
MPI_Reduce(&message, max, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); 


MPI_Finalize(); 

return 0; 

}

+1

あなたは何かに固執していますか? – sarnold

+0

私はちょうど正直にそれを本当に理解していない。以下の答えは大いに役立ちましたが、私はまだそれを0から2に戻さないようにしています。0に戻ってください.1から2まで0を得ます。プログラムを読んでください。 –

答えて

4

は、私はこれについて、小さな提案を持っています、rankの値に応じて)。 %演算子を使用すると、明瞭度の向上に役立つかもしれない:

next_node = (rank + 2) % size; 
prev_node = (size + rank - 2) % size; 

あなたはrank % 2の値に基づいて、受信またはnext_nodeprev_nodeに送信するかどうかを選択することができます。

if (rank % 2) { 
     MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
} else { 
     MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
} 

一度か二度これを行うことは結構です、あなたのコードがこのような種類のスイッチでに分かれていることがわかったら、これらのリングルーチンを関数に置き、次のノードと前のノードをパラメータとして渡すのは理にかなっています。

数字の配列と文字の配列を配布するときには、n/sizeは、配列の末尾に残っているn % size要素の残りを処理する必要があることに注意してください。 (おそらく単純化のために、マスターノードにあるでしょう。

$ mpirun -np 16 ./a.out | sort -k3n 
* Rank 0: Heeeelp! from 14 
* Rank 1: Heeeelp! from 3 
* Rank 2: Heeeelp! from 0 
* Rank 3: Heeeelp! from 5 
* Rank 4: Heeeelp! from 2 
* Rank 5: Heeeelp! from 7 
* Rank 6: Heeeelp! from 4 
* Rank 7: Heeeelp! from 9 
* Rank 8: Heeeelp! from 6 
* Rank 9: Heeeelp! from 11 
* Rank 10: Heeeelp! from 8 
* Rank 11: Heeeelp! from 13 
* Rank 12: Heeeelp! from 10 
* Rank 13: Heeeelp! from 15 
* Rank 14: Heeeelp! from 12 
* Rank 15: Heeeelp! from 1 

はあなたがそこに二つのリングを見ることができます:

は、私はいくつかのより多くの出力文(および他のノードからのメッセージを格納する場所)とプログラムが期待通りに動作するシンプルなリングを追加しました、自分の方向にそれぞれが:

#include <iostream> 
#include "mpi.h" 

using namespace std; 
// compile: mpicxx program.cpp 
// run: mpirun -np 4 ./a.out 
int main(int argc, char *argv[]) 
{ 
    int rank;  // unique number associated with each core 
    int size;  // total number of cores 
    char message[80]; 
    char recvd[80]; 
    int prev_node, next_node; 
    int tag; 
    MPI_Status status; 
    // start MPI interface 
    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    sprintf(message, "Heeeelp! from %d", rank); 

    // cout << "Rank " << rank << ": " << message << endl; 

    MPI_Barrier(MPI_COMM_WORLD); 
    next_node = (rank + 2) % size; 
    prev_node = (size + rank - 2) % size; 


    tag = 0; 
    if (rank % 2) { 
     MPI_Send(&message, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&recvd, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD, &status); 
    } else { 
     MPI_Send(&message, 80, MPI_CHAR, next_node, tag, MPI_COMM_WORLD); 
     MPI_Recv(&recvd, 80, MPI_CHAR, prev_node, tag, MPI_COMM_WORLD, &status); 
    } 

    cout << "* Rank " << rank << ": " << recvd << endl; 

    //cout << "After - Rank " << rank << ": " << message << endl; 
    // end MPI interface 
    MPI_Finalize(); 

    return 0; 
} 

それは大きなプログラム(配列MIN、MAX、AVG、およびワードカウントを)書く時間が来る、あなたは少し物事を変更する必要があります:のみrank == 0送信されます私開始時のssages。他のすべてのプロセスにそれらのパズルを送ります。他のすべてのプロセスが受信し、作業を行い、結果を返送します。 rank == 0は、すべての結果を一貫した単一の答えに統合する必要があります。

+0

@Alyssa、私は全部のプログラムにまとめて、受信したメッセージを手に入れました(それぞれがグループ内の次のメッセージで独自のメッセージを上書きしていました)。私はこれが役立つことを願っています – sarnold

+0

うわー、ありがとう!それは意味があり、それは動作します!おかげさまで...ありがとうございました。 –

+0

私は上記のプログラムを編集して、最大の配列を入れようとしました。ちょっとしたことがありましたが、それを実際に最大にする方法は不明です。何かご意見は?ありがとう! –

関連する問題