在MPI进程之间传递可变长度结构
我需要MPI_Gatherv()
一些int /字符串对。假设每一对看起来像这样:在MPI进程之间传递可变长度结构
struct Pair {
int x;
unsigned s_len;
char s[1]; // variable-length string of s_len chars
};
如何为Pair定义合适的MPI数据类型?
总之,理论上不可能发送一个可变大小的消息并将其接收到完美大小的缓冲区中。您将不得不发送每个字符串的大小的第一条消息,然后发送第二条消息与字符串本身,或者将该metainfo编码到有效负载中,并使用静态接收缓冲区。
如果您只需发送一条消息,那么我会放弃为Pair定义数据类型:相反,我会为整个有效负载创建一个数据类型,并将所有数据转储到一个连续的非类型化包中。然后在接收端,您可以遍历它,分配每个字符串所需的确切空间量并填充它。让我掀起一个ASCII图来说明。这将是你的有效载荷:
| ..x1 .. | ..s_len1 .. | ....字符串1 .... | ..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()来从每个进程收集有效负载大小。这些有效载荷大小用于计算recv缓冲区和位移矢量的大小(http://www.mpi-forum.org/docs/mpi-11-html/node70.html)。 – Constantin 2010-02-19 19:58:20
我不认为你可以做你想要的MPI。我是一名Fortran程序员,如果我对C的理解有点不稳定,请耐心等待。您希望将一个由1个int和1个字符串组成的数据结构(从字符串中第一个字符的位置传递过来)从一个进程传递到另一个进程?我认为你所要做的就是传递一个固定长度的字符串 - 因此,这个字符串应该和你真正想要传递的任何字符串一样长。收集这些字符串的接待区必须足够大以接收所有字符串及其长度。
您可能想要为您的结构声明新的MPI数据类型;您可以收集这些数据,并且由于收集的数据包含字符串的长度,因此可以在接收方恢复字符串的有用部分。
我不能肯定这一点,但我从来没有碰到过你似乎想用真正的可变信息长度,它并排序觉得非MPI-等。但它可能是我刚刚从未偶然发现的MPI最新版本中实现的,尽管在线查看文档似乎并不如此。
我希望避免浪费固定长度缓冲区的空间。想要避免的另一个可能的选择是使用2个独立阵列表示len/chars对的数组:镜头和字符之一。不管怎么说,还是要谢谢你。 – Constantin 2010-02-16 10:37:21
马克,自从我和MPI一起打球已经有一段时间了,但我确信你在这里是准确的。至少在大约2005年的MPI。 – 2010-02-16 15:46:11
MPI实现不检查或解释消息的实际内容。假如你知道数据结构的大小,你可以用一些char或int来表示这个大小。 MPI实现不会知道或关心数据的实际内部细节。
有几点需要注意......发送方和接收方都需要就消息内容的解释达成一致,并且您在发送方和接收方提供的缓冲区需要适合某些可定义数量的字符或INT的。
使用'char s [0];'作为变长数组,而不是'char s [1];'。 – kennytm 2010-02-15 11:47:28
@KennyTM,s [0]给出了“警告C4200:使用的非标准扩展:struct/union中的零大小数组”。 – Constantin 2010-02-15 16:12:46
啊MSVC。 C99被gcc正确支持,但不支持MSVC。 – kennytm 2010-02-15 16:35:59