Question:
I'm trying to ISend() two arrays: arr1,arr2 and an integer n which is the size of arr1,arr2. I understood from this post that sending a struct that contains all three is not an option since n is only known at run time. Obviously, I need n to be received first since otherwise the receiving process wouldn't know how many elements to receive. What's the most efficient way to achieve this without using the blokcing Send() ?
Answer:
Sending the size of the array is redundant (and inefficient) as MPI provides a way to probe for incoming messages without receiving them, which provides just enough information in order to properly allocate memory. Probing is performed with MPI_PROBE, which looks a lot like MPI_RECV, except that it takes no buffer related arguments. The probe operation returns a status (MPI_Status) object which can then be queried for the number of elements of a given MPI datatype that can be extracted from the content of the message with MPI_GET_COUNT, therefore explicitly sending the number of elements becomes redundant.
Here is a simple example with two ranks:
- if (rank == 0)
- {
- MPI_Request req;
- // Send a message to rank 1
- MPI_Isend(arr1, n, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req);
- // Do not forget to complete the request!
- MPI_Wait(&req, MPI_STATUS_IGNORE);
- }
- else if (rank == 1)
- {
- MPI_Status status;
- // Wait for a message from rank 0 with tag 0
- MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
- // Find out the number of elements in the message -> size goes to "n"
- MPI_Get_count(&status, MPI_DOUBLE, &n);
- // Allocate memory
- arr1 = malloc(n*sizeof(double));
- // Receive the message. ignore the status
- MPI_Recv(arr1, n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
- }
Probing for the message size works as every message carries a header, called envelope. The envelope consists of the sender's rank, the receiver's rank, the message tag and the communicator. It also carries information about the total message size. Envelopes are sent as part of the initial handshake between the two communicating processes.