9

私は MPI プログラミングに慣れていませんが、構造を定義して派生データ型を作成するまで成功しました。今、私は自分の構造にベクターを含めて、プロセス全体でデータを送信したいと考えています。例:

struct Structure{

//Constructor 
Structure(): X(nodes),mass(nodes),ac(nodes) {

//code to calculate the mass and accelerations
}
//Destructor
Structure() {}

//Variables
double radius;
double volume;
vector<double> mass;
vector<double> area;

//and some other variables

//Methods to calculate some physical properties

今MPIを使用して、プロセス全体で構造内のデータを送信したいと考えています。含まれている MPI_type_struct ベクターを作成してデータを送信することはできますか?

フォーラムを読んでみましたが、そこにある回答から明確な全体像を得ることができません。データを送信するための明確なアイデアまたはアプローチを得ることができることを願っています

PS: データを個別に送信できますが、ドメインが非常に大きい (10000*10000 など) と見なされる場合、MPI_Send/Recieve を使用してデータを送信するオーバーヘッドが発生します。

4

5 に答える 5

12

MPIで構造を定義するのは面倒です。より簡単なアプローチは、STLベクトルが連続して割り当てられたメモリを持つことが保証されているという事実を使用することだと思います。つまり、最初の要素へのポインタを取得することで、それらをC配列のように扱うことができます。

std::vector<float> data;
// ... add elements to your vector ...
MPI_Send(&data.front(), data.size(), MPI_FLOAT, 0, 1, MPI_COMM_WORLD);
于 2010-03-30T15:18:28.337 に答える
0

うーん...データのストリームとして C/C++ 構造体を送信することは、参加しているすべてのマシンのデータ レイアウトがまったく同じであることが保証されている場合にのみ機能します。一般に、これは機能しません。さらに、MPI 派生データ型としてパックされた構造体を送信することは、コードを明確にし、意図を示すために +1 であると主張する人がいます。

于 2012-01-05T10:41:17.700 に答える
0

私はあなたがやっているようなことをしています、そして私のプロセッサアーキテクチャが同種であることを知っています. Boost serializationを使用することで、大量のバイトスワップと多数の MPI パッキングおよびアンパックを回避しています。

送信:

  ostringstream oss;
  {
    binary_oarchive oa(oss);
    oa << BOOST_SERIALIZATION_NVP(myStruct);
  }

  MPI::COMM_WORLD.Send(oss.str().c_str(),
                       oss.str().size(),
                       MPI::Datatype(MPI_BYTE),
                       MpiLibWrapper::DEST_PROC_RANK,
                       MpiLibWrapper::MY_STRUCT_TAG);

受信:

    vector<char> incomingBuffer(MAX_BUFFER_SIZE);

    MPI::COMM_WORLD.Recv(&incomingBuffer[0], incomingBuffer.size(),
                         MPI::Datatype(MPI_BYTE),
                         MpiLibWrapper::SRC_PROC_RANK,
                         MpiLibWrapper::MY_STRUCT_TAG,
                         msgStatus);
    if (MpiLibWrapper::ErrorOccurred(msgStatus.Get_error(),
                                     info.logging)) {
      break;
    }
    incomingBuffer.resize(msgStatus.Get_count(MPI::Datatype(MPI_BYTE)));

    if (incomingBuffer.size() > 0) {
      // Shockingly, this does not result in a memory allocation.
      istringstream iss(string(&incomingBuffer[0], incomingBuffer.size()));

      binary_iarchive ia(iss);

      ia >> BOOST_SERIALIZATION_NVP(myStruct);
    }
于 2010-04-05T18:48:47.147 に答える
0

ここで、同様の問題に対する私の解決策について説明します。

メッセージパッシング任意のオブジェクトグラフ?

以前に定義したカスタム MPI データ型からカスタム MPI データ型を作成できることに注意してください。たとえば、Structure の単一インスタンスのレイアウトとコンテンツを記述する Struct を定義してから、これらの Struct データ型からオブジェクトのベクター全体の Vector を定義できます。そのようなベクトルが複数ある場合は、抽象化の第 3 層を作成して、構造体のベクトルから HIndexed データ型を作成し、それらすべてを 1 つのメッセージで送信できます。

上記でリンクした投稿には、さまざまなカスタム MPI データ型の説明へのリンクがあり、適切なアプローチを決定するのに役立ちます。

于 2010-04-02T17:46:02.890 に答える
-2

私は確かに MPI データ構造の専門家ではありませんが、これができるとは思いません。その理由は、基本的に、送信されるデータへのポインターを持つ構造体があるためです。MPI データ型関数はすべて、送信するデータが連続したメモリ領域にあることを前提としています。ベクトルの最大サイズが固定されている場合、次のことができます

double radius;
double volume;
int mass_size;
int area_size;
double mass[MASS_MAXLEN];
double area[AREA_MAXLEN];

そして、入力された要素のみを送信します。

または、送信前にデータを自分で 1 つの配列にパックして、配列を送信することもできます。これが個別の送信よりも速いかどうかを確認するには、プロファイリングを行う必要があります。

于 2010-03-30T18:51:19.260 に答える