9

我是 MPI 编程的新手,仍然在学习,在通过定义结构创建派生数据类型之前我是成功的。现在我想在我的结构中包含 Vector,并希望通过 Process 发送数据。例如:

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

我做你正在做的事情,而且我知道我的处理器架构是同质的。我通过使用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 数据类型。例如,您可以定义一个 Struct 来描述单个结构实例的布局和内容,然后定义一个来自这些 Struct 数据类型的向量,用于整个对象向量。哎呀,如果你有几个这样的向量,你可以创建第三层抽象,从结构的向量创建一个 HIndexed 数据类型,然后用一条消息将它们全部发送。

在我上面链接的帖子中,您将找到各种自定义 MPI 数据类型描述的链接,这将有助于您决定正确的方法。

于 2010-04-02T17:46:02.890 回答
0

嗯...仅当您保证所有参与机器上的数据布局完全相同时,才能将 C/C++ 结构作为数据流发送。一般来说,这是行不通的。另外,有些人会争辩说,为了代码的清晰和显示意图,发送打包为 MPI 派生数据类型的结构是 +1。

于 2012-01-05T10:41:17.700 回答
-2

我当然不是 MPI 数据结构专家,但我不认为这是可以做到的。原因是基本上你有一个结构,其中包含指向要发送的数据的指针。所有 MPI 数据类型函数都假定您要发送的数据位于内存的连续区域中。如果向量的最大大小是固定的,你可以这样做

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

然后只发送填充的元素。

或者,您可以在发送之前将数据自己打包到一个数组中并发送数组。您必须进行一些分析,看看这是否比单独发送更快。

于 2010-03-30T18:51:19.260 回答