我需要MPI_Gatherv()
多个int / string对。让我们说每一对看起来像这样:
struct Pair {
int x;
unsigned s_len;
char s[1]; // variable-length string of s_len chars
};
如何为Pair定义合适的MPI数据类型?
答案 0 :(得分:4)
简而言之,从理论上讲,发送一条可变大小的消息并将其接收到一个完美大小的缓冲区是不可能的。您要么必须发送包含每个字符串大小的第一条消息,然后发送包含字符串本身的第二条消息,要么将该元信息编码到有效负载中并使用静态接收缓冲区。
如果您只发送一条消息,那么我将放弃为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;
}
但请注意,只有在发送和接收系统中整数和字符的数据表示相同时,此解决方案才有效。
答案 1 :(得分:2)
我认为你不能用MPI做你想做的事。我是Fortran程序员,所以如果我对C的理解有些不稳定,请耐心等待。您似乎希望传递一个由1个int和1个字符串组成的数据结构(通过将字符串中第一个字符的位置传递给它)从一个进程传递到另一个进程?我认为你要做的就是传递一个固定长度的字符串 - 因此,它应该与你真正想要传递的任何字符串一样长。收集这些字符串的接收区域必须足够大,以便能够接收所有字符串及其长度。
您可能希望为结构声明一个新的MPI数据类型;然后你可以收集它们,因为收集的数据包括字符串的长度,所以在接收器处恢复字符串的有用部分。
我不确定这一点,但我从来没有遇到真正可变的消息长度,因为你似乎想要使用它并且它确实感觉不像MPI那样。但它可能是在最新版本的MPI中实现的,我从来没有偶然发现过,虽然在线查看文档似乎并非如此。
答案 2 :(得分:1)
MPI实现不检查或解释消息的实际内容。如果您知道数据结构的大小,则可以在某些char或int中表示该大小。 MPI实现不会知道或关心数据的实际内部细节。
有一些警告......发送方和接收方都需要就消息内容的解释达成一致,并且您在发送方和接收方提供的缓冲区需要适合某些可定义数量的char或int 。