How to send and receive string using MPI

19,100

The address of a std::string is not the same as address of the underlying C string, so sending should be fixed like this:

MPI_Send(result.c_str(), result.size(), MPI_CHAR, 0, 0, MPI_COMM_WORLD);

Receiving cannot be done as you tried to do it. You need a buffer (an array of char), which you will pass to MPI_Recv and use it later to create a std::string instance. To get a length of the string received use MPI_Get_count - this you should pass along the pointer to buffer to std::string constructor.

In order to avoid preallocating the buffer and allow it to receive a string of any size you should call MPI_Probe and MPI_Get_count to get the length first. Knowing the length you can allocate the buffer with the exact size which is necessary, and only then call MPI_Recv.

If this sounds a bit complicated then you can consider using BOOST MPI wrappers.

Share:
19,100
John
Author by

John

Updated on June 07, 2022

Comments

  • John
    John almost 2 years

    I am trying to send and recieve string using MPI but results are hopless.

    Send function:

    MPI_Send(&result, result.size(), MPI_CHAR, 0, 0, MPI_COMM_WORLD);
    

    And the recv function:

        MPI_Recv(&result,      /* message buffer */
            128,                 /* one data item */
            MPI_CHAR,        /* of type char real */
            MPI_ANY_SOURCE,    /* receive from any sender */
            MPI_ANY_TAG,       /* any type of message */
            MPI_COMM_WORLD,    /* default communicator */
            &status);          /* info about the received message */
    

    Where result is a string.

    I didn't get any error but program doesn't want to finish.

  • Štěpán Němejc
    Štěpán Němejc over 10 years
    +1, beat me to it. Regarding the receive, if result is known to have a large enough buffer (previously created), he can use &result[0] to get a non-const pointer to the internal buffer.
  • piokuc
    piokuc over 10 years
    If result is a std::string then &result[0] should be the same as result.c_str(), except it is non-const. I would personally use the former, with a const_cast. I see what you mean here, passing a preallocated std::string can work with MPI_Recv, but it will fail if the string contains 0, for example, so care should be taken...
  • John
    John over 10 years
    When I change argument to array of char, everything works fine. Thx guys. :)
  • Darqer
    Darqer over 9 years
    Should not you use MPI_Send(result.c_str(), result.size() + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD); in order to incorporate string termination sign '\0' ?
  • Nurlan
    Nurlan about 9 years
    @piokuc MPI_Send(result.c_str(), result.size(), MPI_CHAR, 0, 0, MPI_COMM_WORLD); gives compiler error telling the first argument with type of const char* is incompatable with parameter void*. How can I solve that?
  • NoseKnowsAll
    NoseKnowsAll over 8 years
    @Nurlan I know this is very late, but your problem is that you declared result as const. However, by definition of a Send/Recv pair, you need to be able to change result on the receiving end. So it cannot be a const std::string, but rather a non-const std::string.