6

私は現在、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 は少し小さいように思えます。より大きなメッセージを送信する方法はありますか?

4

1 に答える 1

4

メッセージ サイズの制限は : の場合と同じMPI_SendですINT_MAX

問題は、次の反復でisendベクトルのサイズを変更する前に が終了するのを待っていないことです。aこれはisend、 vector の再割り当てにより、 が無効なデータを読み取ることを意味しaます。aバッファは参照によって渡されるため、操作が完了するまでboost::mpiバッファを変更できないことに注意してください。aisend

でプログラムを実行するとvalgrind、i = 131072 になるとすぐに無効な読み取りが表示されます。

プログラムが 65536 バイトまで動作する理由は、メッセージがコンポーネントよりも小さい場合、OpenMPI がメッセージを直接送信するためですbtl_eager_limit。コンポーネント (独自のプロセスに送信) の場合self、これはたまたま128*1024バイトになります。のサイズをバイト ストリームにboost::serialization追加するため、入力サイズとして使用するとすぐにこれを超えます。std::vectoreager_limit128*1024 = 131072

コードを修正するには、boost::mpi::request戻り値を保存してから、ループの最後にisend()追加します。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;
}
于 2015-03-07T22:18:07.030 に答える