我目前正在openMPI上使用boost :: mpi编写模拟,一切都很好。但是,一旦我扩展系统,因此必须发送更大的std :: vectors,我就会收到错误。
我已将问题简化为以下问题:
#include <boost/mpi.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/vector.hpp>
#include <iostream>
#include <vector>
namespace mpi = boost::mpi;
int main() {
mpi::environment env;
mpi::communicator world;
std::vector<char> a;
std::vector<char> b;
if (world.rank() == 0) {
for (size_t i = 1; i < 1E10; i *= 2) {
a.resize(i);
std::cout << "a " << a.size();
world.isend(0, 0, a);
world.recv(0, 0, b);
std::cout << "\tB " << b.size() << std::endl;
}
}
return 0;
}
打印出来:
a 1 B 1
a 2 B 2
a 4 B 4
....
a 16384 B 16384
a 32768 B 32768
a 65536 B 65536
a 131072 B 0
a 262144 B 0
a 524288 B 0
a 1048576 B 0
a 2097152 B 0
我知道mpi邮件大小有限制,但65kB对我来说似乎有点低。 有没有办法发送更大的消息?
答案 0 :(得分:3)
邮件大小限制与MPI_Send
:INT_MAX
相同。
问题在于,在下一次迭代中调整向量isend
之前,您不会等待a
完成。这意味着由于向量isend
中的重新分配,a
将读取无效数据。请注意,缓冲区a
是通过引用boost::mpi
传递的,因此在a
操作完成之前,不允许更改缓冲区isend
。
如果您使用valgrind
运行程序,只要i = 131072,您就会看到无效的读取。
你的程序工作到65536字节的原因是,如果OpenMPI小于组件btl_eager_limit
,它将直接发送消息。对于self
组件(发送到自己的进程),这恰好是128*1024
个字节。由于boost::serialization
会将std::vector
的大小添加到字节流中,所以只要您使用eager_limit
作为输入大小,就会超过此128*1024 = 131072
。
要修复代码,请保存boost::mpi::request
的{{1}}返回值,然后将isend()
添加到循环的结尾:
wait()