MPI_Bcast c++ STL vector

2019-02-21 02:52发布

问题:

Why does the following code not work? It works for my user-defined class but not for STL vector.

std::vector<int> v(4);
MPI_Bcast(&v, sizeof(v), MPI_BYTE, 0, MPI_COMM_WORLD);

I got segmentation error:

[sdg:13611] Signal: Segmentation fault (11)
[sdg:13611] Signal code: Address not mapped (1)

Since the elements in vector are stored contiguously, why can't I send std::vector as a whole using MPI_BYTE?

回答1:

The address of a vector itself is not the same as of it's data. Sending objects like you propose only works for trivially copyable types - you can imagine MPI communication works similarly to memcpy. You can check with std::is_trivially_copyable - std::vector itself is never trivially copyable.

However, vector stores it's data in contiguous memory - on which you may use memcpy.

You must ensure that all MPI processes have a vector with the same size before the operation. capacity is not sufficient. If you only know the size on one process, you must broadcast the size before and resize the target vectors on the other process accordingly.

Also, the elements in your vector must be trivially copyable themselves.

MPI_Bcast(v.data(), v.size(), MPI_INT, 0, MPI_COMM_WORLD);

If for some reason you have trouble figuring out the MPI type (e.g. MPI_INT), you can do it as follows (avoiding redundancy that breaks when you change the type).

MPI_Bcast(v.data(), v.size() * sizeof(decltype(v)::value_type)), MPI_BYTE, 0, MPI_COMM_WORLD);


回答2:

Most likely you want

if (!v.empty())
    MPI_Bcast(&v[0], v.size() * sizeof(decltype(v)::value_type)), MPI_BYTE, 0, MPI_COMM_WORLD);