9

I am trying to send std:vector using MPI send and recv functions but I have reached no where. I get errors like

Fatal error in MPI_Recv: Invalid buffer pointer, error stack:
MPI_Recv(186): MPI_Recv(buf=(nil), count=2, MPI_INT, src=0, tag=0, MPI_COMM_WORLD, status=0x7fff9e5e0c80) failed
MPI_Recv(124): Null buffer pointer

I tried multiple combinations

A) like what used to send arrays ..

 std::vector<uint32_t> m_image_data2; // definition of  m_image_data2
     m_image_data2.push_back(1);
     m_image_data2.push_back(2);
     m_image_data2.push_back(3);
     m_image_data2.push_back(4);
     m_image_data2.push_back(5);

MPI_Send( &m_image_data2[0], 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2[2], 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2[0], 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

B) without []

MPI_Send( &m_image_data2, 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2 + 2, 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2, 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

C) using vector methods like at()..

MPI_Send( &m_image_data2.at(0), 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2.at(2), 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2.at(0), 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

I am thinking of converting vector to int[] at master node then convert it back to vector in worker node but it will unnecessary overhead.

Does anyone know how to solve it?

1
  • Please post complete code examples. As you commented below, your error has nothing to do with MPI and everything to do with code you omitted to show , but nobody could have known that! Commented Mar 17, 2015 at 0:08

2 Answers 2

13

Without a more complete example I don't know what's going on, but it seems that you are mismatching the sends and receives (or you didn't initialize the receive vector correctly).

Something like the following would be enough:

std::vector<uint32_t> m_image_data2;

if (rank==0) {
  m_image_data2.push_back(1);
  m_image_data2.push_back(2);
  m_image_data2.push_back(3);
  m_image_data2.push_back(4);
  m_image_data2.push_back(5);
  // send 5 ints at once
  MPI_Send( &m_image_data2[0], 5, MPI_INT, 1, 0, MPI_COMM_WORLD);
}
else {
  // make space for 5 ints
  m_image_data2.resize(5);
  // receive 5 ints
  MPI_Recv(&m_image_data2[0], 5, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
}
Sign up to request clarification or add additional context in comments.

5 Comments

I would improve this slightly by using the size() of the vector i.e. MPI_Send(&m_image_data2[0],m_image_data2.size(),...); To cleanly move complex data types you might also investigate the custom data type functionality in MPI. It's tricky, but you can then send structs. Also, transferring data that is of unknown size will require you to be send the size of the vector too, so that the receiver has a chance to allocate. You might check out Boost MPI boost.org/doc/html/mpi.html
Really!!. Thanks it worked!. I was missing this line: m_image_data2.resize(5);
You don't need to use &m_image_data2[0] to get the data from std::vector, there is a .data() function that does exactly that; i.e. &m_image_data2[0] == m_image_data2.data()
@wolfPack88 std::vector.data() is a C++11 feature, it may not be available to the OP, but yes that's a less verbose way.
I think both Intel and GCC had it as early as 2010, before it became part of the standard. Fair enough, though.
4

Consider Boost::MPI, which explicits supports e.g. std::vector through Boost::Serialization.

Of course, Boost::MPI does not support all of MPI 3.0, but rather MPI 1.3 (and maybe a subset of MPI 2.2, but definitely not RMA), so it is not a perfect solution. However, if you use only common features of MPI introduced in MPI-1, then it should be fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.