【问题标题】:Passing variable-length structures between MPI processes在 MPI 进程之间传递可变长度结构
【发布时间】:2011-01-16 13:21:19
【问题描述】:

我需要MPI_Gatherv() 一些整数/字符串对。假设每一对看起来像这样:

struct Pair {
  int x;
  unsigned s_len;
  char s[1]; // variable-length string of s_len chars
};

如何为 Pair 定义合适的 MPI 数据类型?

【问题讨论】:

  • 对可变长度数组使用char s[0];,而不是char s[1];
  • @KennyTM, s[0] 给出“警告 C4200:使用了非标准扩展:结构/联合中的零大小数组”。
  • 啊 MSVC。 gcc 正确支持 C99,但 MSVC 不支持。
  • @KennyTM,嗯,我仍然想知道在什么意义上 s[0] 会更正确?如果我知道我的字符串永远不会为空,s[0] 还会更正确吗?

标签: c mpi


【解决方案1】:

简而言之,理论上不可能发送一条可变大小的消息并将其接收到完美大小的缓冲区中。您要么必须发送带有每个字符串大小的第一条消息,然后发送带有字符串本身的第二条消息,要么将该元信息编码到有效负载中并使用静态接收缓冲区。

如果您必须只发送一条消息,那么我会放弃为 Pair 定义数据类型:相反,我会为整个有效负载创建一个数据类型,并将所有数据转储到一个连续的、无类型的包中。然后在接收端,您可以对其进行迭代,为每个字符串分配所需的确切空间量并填充它。让我拿出一个 ASCII 图表来说明。这将是您的有效载荷:

|..x1..|..s_len1..|..string1...|..x2..|..s_len2..|.string2.|..x3..|.. s_len3..|........string3........|...

您将整个内容作为一个单元发送(例如,一个 MPI_BYTE 数组),然后接收方会像这样将其解包:

while (buffer is not empty)
{
    read x;
    read s_len;
    allocate s_len characters;
    move s_len characters from buffer to allocated space;
}

但请注意,此解决方案仅适用于整数和字符的数据表示在发送和接收系统上相同的情况。

【讨论】:

  • 将所有内容打包在连续缓冲区中是我最终决定的。需要注意的一点是,我必须使用额外的 MPI_Gather() 来收集每个进程的有效负载大小。这些有效载荷大小用于计算接收缓冲区的大小和位移向量 (mpi-forum.org/docs/mpi-11-html/node70.html)。
【解决方案2】:

我不认为你可以用 MPI 做你想做的事。我是一名 Fortran 程序员,如果我对 C 的理解有点不稳定,请多多包涵。您似乎希望将一个由 1 个 int 和 1 个字符串(您通过传递字符串中第一个字符的位置来传递)组成的数据结构从一个进程传递到另一个进程?我认为你要做的是传递一个固定长度的字符串——因此,它与你真正想要传递的任何字符串一样长。用于收集这些字符串的接收区域必须足够大,以接收所有字符串及其长度。

您可能希望为您的结构声明一个新的 MPI 数据类型;然后你可以收集这些,因为收集的数据包括字符串的长度,所以在接收端恢复字符串的有用部分。

我不确定这一点,但我从未遇到过您似乎想要使用的真正可变的消息长度,而且它确实有点不像 MPI。但这可能是我从未偶然发现的最新版本的 MPI 中实现的东西,尽管查看在线文档似乎并非如此。

【讨论】:

  • 我希望避免使用固定长度的缓冲区浪费空间。要避免的另一个可能的选择是用 2 个单独的数组表示 len/chars 对的数组:一个 lens 和一个 chars。还是谢谢。
  • 马克,我玩 MPI 已经有一段时间了,但我很确定你在这里是准确的。至少在 2005 年 MPI 左右。
【解决方案3】:

MPI 实现不检查或解释消息的实际内容。只要您知道数据结构的大小,您就可以用一些 char 或 int 来表示该大小。 MPI 实现不会知道或关心数据的实际内部细节。

有一些注意事项...发送方和接收方都需要就消息内容的解释达成一致,并且您在发送方和接收方提供的缓冲区需要适合某些可定义数量的 char 或 int .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2014-10-12
    • 2019-10-25
    • 2017-06-10
    • 1970-01-01
    相关资源
    最近更新 更多