2016-06-12 10 views
0

私はstd::list<int>をマスタとスレーブの間でやり取りしようとしています。しかし、私はMPIデータ型を作成し、そのリストをスレーブに渡す方法が不明です。私はboostのような別のライブラリを使わずにこれをしたいと思います。私はこのpostを解決しようとしていますが、私はlistで作業することができませんでした。以下は、私が作業しているコードです。C++ OpenMPIを使用してマスタ/スレーブプロセス間でリストを送受信

#include <iostream> 
#include <list> 
#include "mpi.h" 
#include <stdio.h> 
#include <stdlib.h> 

using namespace std; 

int main(int argc, char **argv) 
{ 
int rank, size, tag, rc, i; 
MPI_Status status; 
char message[20]; 
char new_message[20]; 
MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
tag=7; 

if (rank==0) { 
    strcpy(message, "Hello, world"); 
    for (int i=1; i<size; ++i){ 
     list<int> rand_list; 
     list<int>::iterator it = rand_list.end(); 
     list<int> *lt_ptr = &rand_list; 
     for(int j = 0; j < 5; ++j) 
     { 
      int r; 
      r = rand(); 
      rand_list.push_front(r); 
      it++; 
     } 
     //Instead of sending the string I'd like to send the list of random ints 
     MPI_Send(message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD); 
     MPI_Recv(new_message, 13, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status); 
     cout << "master: " << new_message << endl; 
     } 
} 
else{ 
    // slaves processes 
    rc = MPI_Recv(message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD, &status); 
    cout << "node " << rank << ": " << message << endl; 
    strcpy(new_message, "Goodbye, world"); 
    // code to manipulate the lists and send back to the master process 
    rc = MPI_Send(new_message, 13, MPI_CHAR, 0, tag, MPI_COMM_WORLD); 
    } 
MPI_Finalize(); 
} 

以下は、私がコンパイルして実行するために使用したコマンドです。

mpic++ mpi_prog.cpp -o mpi_prog.o 
mpirun -np 5 mpi_prog.o 
+1

'std :: list 'の代わりに 'std :: vector 'を使うと、これは簡単になります。送信バッファは '&rand_vec [0]'であり、カウントは 'rand_vec.size()'です。特にリストを使用する必要はありますか? – Novelocrat

答えて

0

ここでstd::listを使用しますか? std::vectorが適切であるように見えますが、データは連続して保存され、MPIで直接動作するはずです。あなたは事を過度に複雑にしており、方法によってはstd::randではなくstd::uniform_int_distributionを好む。

そのようなことのようになります。ランダムベクトルを埋めるためにあなたのマスターコード:

std::vector<int> v(5); 
std::random_device rd; 
std::mt19937 gen(rd()); // mersenne twister engine 
std::uniform_int_distribution<> dis; 
std::generate(v.begin(), v.end(), [&](){ return dis(gen); }); // fill the vector with random values 

あなたのマスターノードは、MPIで直接呼び出すことができます。

MPI_Send(&v[0], v.size(), MPI_INT, i, tag, MPI_COMM_WORLD); 

スレーブノードコード:

MPI_Recv(&v[0], v.size(), MPI_INT, 0, tag, MPI_COMM_WORLD, &status); 

これはあなたがしたいことがわかりません。あなたのマスターはランダムな値で異なるベクトルsizeを初期化し、それぞれを1つのスレーブノードに送ります。スレーブによって受信された各ベクトルは異なる。それが正しいか ?

0

リストを送信する最も簡単な方法は、一つずつを送信し、その後の要素をループを使用すると、5として持つリストの長さを、送信、およびである可能性があります。これはパフォーマンスがかなり悪くなりますが、リストを使用することは、おそらく多くの理由から問題のある設計選択です。

マスターでプロセスを1つずつループして、それぞれ異なる番号を送信するので、全体的に異なるデザインを使用する方がよいでしょう。あなたの特定のユースケースでは、乱数を実際に使用するプロセスで並列に生成する方法はありますか?目的設計の並列乱数生成アルゴリズムと先進の乱数生成器があり、各スレーブにストリーム内でどのくらい先にスキップして重複しないようにするかを指示できます。

関連する問題