Reputation: 383
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.
Upvotes: 8
Views: 24041
Reputation: 1
I was having similar problem where I had to pass a string between two processes in MPI C. My solution, aligned to your problem, is the following:
MPI_Send(&result, strlen(result)+1, MPI_CHAR, 1, 0, MPI_COMM_WORLD); // Destination: Process 1
On the other side, process 0 will have the following MPI_Recv function:
MPI_Recv(&result, 100, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // Source: Process 0 and considering 100 as the maximum string length
<string.h>
has to be added in the header.
Upvotes: -1
Reputation: 26184
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.
Upvotes: 19