cannot send std::vector using MPI_Send and MPI_Recv

16,188

Solution 1

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);
}

Solution 2

Consider Boost::MPI, which explicits suppports 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.

Share:
16,188
Abdullah
Author by

Abdullah

Updated on June 07, 2022

Comments

  • Abdullah
    Abdullah almost 2 years

    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?