2015-01-15 61 views
5

我目前正在使用boost :: mpi在openMPI上编写一个模拟程序,并且一切都很好。但是,一旦我扩大系统,因此必须发送更大的std ::向量,我会得到错误。使用boost :: mpi的消息大小在mpi中是否有限制?

我已经减少了问题存在如下问题:

#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

根据[这](http://stackoverflow.com/questions/13558861/maximum-of-data-that-c​​an-be-sent-using-mpisend)你甚至不应该接近最大值。消息大小。不知道这里发生了什么问题。 –

+0

如果将'isend'更改为'send',会发生什么情况?这可能是非阻塞发送导致问题。 – NathanOliver

+0

@NathanOliver:如果我改变isend发送,它只是在写入65536 B 65536行后停止(块)。 – tik

回答

3

消息大小限制与MPI_SendINT_MAX相同。

问题在于,在下一次迭代中调整矢量a的大小之前,您并未等待isend完成。这意味着由于向量a中的重新分配,isend将读取无效数据。请注意,通过引用boost::mpi传递缓冲区a,因此您不允许更改缓冲区a,直到isend操作完成。

如果用valgrind运行您的程序,你会看到无效的,一旦读为i = 131072

你的程序工作到65536个字节的原因,就是会的openmpi直接发送消息,如果他们是比小组件btl_eager_limit。对于self组件(发送到自己的进程),这恰好是128*1024字节。由于boost::serializationstd::vector的大小添加到字节流中,只要您使用128*1024 = 131072作为输入大小,就会超过此eager_limit

要解决你的代码,从isend()保存boost::mpi::request返回值,然后添加wait()到循环的末尾:

#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 < 1E9; i *= 2) { 
      a.resize(i); 
      std::cout << "a " << a.size(); 
      mpi::request req = world.isend(0, 0, a); 
      world.recv(0, 0, b); 
      std::cout << "\tB " << b.size() << std::endl; 
      req.wait(); 
     } 
    } 
    return 0; 
} 
相关问题