Rmpi Tutorial 3: Sending Data to A Specific Slave


Today’s topic is point-to-point communication using Rmpi. If you want to send data to a specific slave, you will need to use a pair command of mpi.send and mpi.recv. These commands have to be used as a pair, and mpi.send comes always before mpi.recv, otherwise R will crash. This is because both mpi.send and mpi.recv are blocking calls and it will wait for data which haven’t been sent at the moment.

Another way of explaining blocking calls is that the program won’t return until it completes send & receive. Thus, if receive is called before send, it goes into infinite wait and this situation is called deadlock.

In addition, because  mpi.recv command needs to be executed on a slave CPU, usually codes containing mpi.recv() is sent as a function to slaves first. Then the function is called after calling mpi.send by master. Here is the basic process to send data to specific slave.

1. Define a function to receive data from master
2. Send the function to slave using mpi.send.Robj()
3. mpi.send() from master
4. Call the function
5. Check the results

The syntax for mpi.send() and mpi.recv() is

mpi.send(x,type,dest,tag, comm)



x     : data to be sent
type  : 1 for integer,2 for double and 3 for character
dest  : destination rank
source: source rank 
       (Use mpi.any.source for any source)
tag   : non-negative number 
       (Use mpi.any.tag for any tag flag)
comm  : communication number (default=1)

For tag and source, you can use wild card (mpi.any.tag, and mpi.any.source). If  you use it, the receiver will receive data with any tag value or no matter where the data is coming from .

Example: Send an integer from the master CPU to slave #2


#define function to receive data in slave

#send the function to all slaves

#send an integer from master

#create x to receive data in slaves

#call the function

#check results

Here is the output

> mpi.remote.exec(x)
  X1 X2 X3
1  0 21  0

mpi.send command can be inside of the function instead of being called in the main program. In this case, you place mpi.send inside of if-close using mpi.comm.rank to run only by master. However, the if-statement needs to be before mpi.recv command to work properly.

if (mpi.comm.rank()==0){
mpi.send (.......)

mpi.send and mpi.recv are used to send small data to a slave. For a large data, you can use  mpi.send.Robj and mpi.recv.Robj. The syntax for these commands are similar to mpi.send and mpi.recv.


mpi.isend and mpi.irecv are Non-Blocking Calls

If you use blocking calls such as mpi.send or mpi.recv, you may have a deadlock situation. To avoid crash, you can use non-blocking calls such as mpi.isend and mpi.irecv (i stands for immediate). These commands will not wait to complete send/receive, and go to the next code immediately. This means that even if you don’t succeed sending data to slaves, you will go to next line of the program.

What is a Benefit of Using Non-Blocking Calls?

Besides avoiding crash, using non-blocking call may bring better performance. For example, if you send data but you don’t need to use the data right away, you can perform some tasks before you check to see if sending data is completed.

### slave side # do not wait to complete receiving data x<-mpi.irecv(...) ... some codes (no access to x) ... some codes (no access to x) mpi.wait() #codes using x starts here

If you have multiple requests, you can use mpi.waitall. Please see more details for these functions here.

About bioinfomagician

Bioinformatic Scientist @ UCLA

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: