如何使用一次广播在 MPI 中传输不同类型的向量
Posted
技术标签:
【中文标题】如何使用一次广播在 MPI 中传输不同类型的向量【英文标题】:How to transmit vectors of different types in MPI using one broadcast 【发布时间】:2016-11-29 05:38:53 【问题描述】:我有一些向量,我想在 C++ 中使用 MPI 在进程之间传输。我一直在使用broadcast
一次交换一个向量的数据,但它似乎并没有随着进程的数量而很好地扩展。有人告诉我这是因为我使用了太多的广播调用,随着进程数量的增加,它会导致太多的延迟。因此,建议我将所有数据打包在一个结构中,然后一次性发送。
我的问题是我的向量是 int
和 double
类型(每种类型 2 个向量),并且它们的长度在编译时是未知的(它等于进程数)。因此,我无法创建一个struct
来保存所有数据,然后使用here 所述的自定义MPI 结构(MPI_Type_create_struct)进行广播,因为它需要在编译时硬编码c 数组的大小。我知道如何创建 MPI 自定义结构,但我不知道如何将数据打包到结构中以便发送。
那么,总而言之,有没有办法只使用一次广播在进程之间广播 4 个不同类型的向量(2 个 int 和 2 个 double)?
【问题讨论】:
MPI 结构化数据类型是通用的,并不需要真正对应 C/C++struct
s。
确实如此,但是我怎样才能使用它来实际发送数据呢?例如,我可以使用: MPI_Send(&custom_object_to_send, 1, mpi_custom_type, dest, tag, MPI_COMM_WORLD);但我需要创建 custom_object_to_send 并为其分配值以便我可以发送它,而且据我所知,这需要用语言构建。
不,你没有。您只需创建一个 MPI 结构类型并指定每个数组/向量开头的绝对地址作为偏移量,然后在对 MPI_Send
的调用中指定 MPI_BOTTOM
作为数据缓冲区地址。只需使用您喜欢的搜索引擎搜索"MPI_Type_create_struct" "MPI_BOTTOM"
。
【参考方案1】:
注意:“4.1.2”等数字参考MPI标准v3.0中的章节
这应该可以使用MPI_Type_create_struct
(4.1.2) 而没有实际的 C-struct
。
使用MPI_Type_vector
(4.1.2) 创建两种数据类型。一个用于int
的向量,一个用于double
的向量,您将从vector<>::data()
获得。您可以假设vector<>
以连续方式存储数据。
您可以在运行时为 MPI_Type_vector
提供大小值。
现在使用MPI_Type_create_struct
将两种向量类型中的每一种的两个实例组合成一个数据类型,然后您可以轻松地使用它进行通信。
使用MPI_Get_address
(4.1.5),我们可以在运行时获取变量的 MPI 友好地址。在构造虚拟结构的派生数据类型期间,您可能需要它。 (阅读 MPI 标准中对用户的建议,了解为什么不使用&
)
为了更灵活,省略中间向量数据类型,直接计算vector<>::data()
数组的地址和扩展,并将其直接输入MPI_Type_create_struct
。
免责声明:IIRC,我一直在成功地使用这种方法通过单个消息发送多个不连续的连续数据块(不久前)。
【讨论】:
以上是关于如何使用一次广播在 MPI 中传输不同类型的向量的主要内容,如果未能解决你的问题,请参考以下文章