mpi4py Send/Recv with tag
mpi, python
Solution
The function `Recv` will store a received message inside a variable. You have to supply the rank of the expected sender. Thus you always know who the sender is. A message passing interface does never need to identify someone, that information is always intrinsic to the system.
If you expect multiple message from the same sender you can distinguish these using tags. You need to supply these tags yourself, there is no natural way to obtain these. Just label the messages somehow, number them.
If you have a tag, the `Recv` function will only return when a message has been received which has a fitting source and tag. This is a blocking function call.
In your case, `tag=-1` is equal to the universal constant `MPI.ANY_TAG` (verify via `print MPI.ANY_TAG`) and thus the `Recv` will accept any tag. But it will in no way overwrite its input variable `rnk`. Try `rnk = -2 # EDIT` and you'll see.
You can write your code differently, though this will not change the underlying logic (i.e. you as a programmer must always know the sender) it just hides it, makes it implicit:
#passRandomDraw.py
import numpy
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
randNum = numpy.zeros(1)
rnk = -1 # EDIT
if rank == 1:
randNum = numpy.random.random_sample(1)
print "Process", rank, "drew the number", randNum[0]
comm.Send(randNum, dest=0, tag=rank) # EDIT
if rank == 0:
print "Process", rank, "before receiving has the number", randNum[0]
print "Sender rank:", rnk
status = MPI.Status()
comm.Recv(randNum, source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG, status=status) # EDIT
rnk = status.Get_source()
print "Process", rank, "received the number", randNum[0]
print "Sender rank:", rnk # EDIT
Problem
How can I pass a the rank of a process as a tag to the mpi4py.MPI.COMM_WORLD.Send() function and correctly receive it with mpi4py.MPI.COMM_WORLD.Recv()? I'm referring to the following code example for sending and receiving messages between two processes using Send and Recv functions ``` #passRandomDraw.py import numpy from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() randNum = numpy.zeros(1) if rank == 1: randNum = numpy.random.random_sample(1) print "Process", rank, "drew the number", randNum[0] comm.Send(randNum, dest=0) if rank == 0: print "Process", rank, "before receiving has the number", randNum[0] comm.Recv(randNum, source=1) print "Process", rank, "received the number", randNum[0] ``` I want to pass the rank of the sending process as a tag so that the receiving process can identify it in case there are multiple senders. This is what I do ``` #passRandomDraw.py import numpy from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() randNum = numpy.zeros(1) rnk = -1 # EDIT if rank == 1: randNum = numpy.random.random_sample(1) print "Process", rank, "drew the number", randNum[0] comm.Send(randNum, dest=0, tag=rank) # EDIT if rank == 0: print "Process", rank, "before receiving has the number", randNum[0] print "Sender rank:", rnk comm.Recv(randNum, 1, rnk) # EDIT print "Process", rank, "received the number", randNum[0] print "Sender rank:", rnk # EDIT ``` I expect the value of rnk to be 1 for the receiving process (which has rank=0), but it is still -1. Can someone tell me what I'm doing wrong here? Thanks!