Rmpi Tutorial 4: Getting Data Back From Slaves

This is going to be the last tutorial for Rmpi. In this post I am going to cover how to receive data from slaves in Rmpi. Let’s think of a situation in the picture below. You want to gather data from slaves and combine them with the data in the master.

mpi_gather_Robj

mpi.gather.Robj() will retrieve data from each slave and put them together like the diagram above.  Let’s try some examples

Example 1: Getting slave number information from each slave

library('Rmpi')
mpi.spawn.Rslaves(nslaves=3)
mpi.bcast.cmd(id<-mpi.comm.rank())
mpi.bcast.cmd(x<-paste("I am slave no.",id))
mpi.bcast.cmd(mpi.gather.Robj(x))
x<-"I am a master"
mpi.gather.Robj(x)
mpi.remote.exec(x)
mpi.close.Rslaves()

Here is the output (showing only the last part)

> mpi.gather.Robj(x)
[1] "I am a master"    "I am slave no. 1" 
"I am slave no. 2" "I am slave no. 3"
> mpi.remote.exec(x)
$slave1
[1] "I am slave no. 1"
$slave2
[1] "I am slave no. 2"
$slave3
[1] "I am slave no. 3"

If you want to retrieve data from each slave and give the whole data to all slaves, you use mpi.allgather.Robj().
mpi_allgather_Robj

Example 2: Send a string “fruit” to master” and “apple”, “banana” and “orange” to slave 1 to 3. Then retrieve data from each slave and send the all data to master and all slaves.

library('Rmpi')
mpi.spawn.Rslaves(nslaves=3)
x<-c("fruits","apple","banana","orange")
mpi.bcast.cmd(x<-mpi.scatter.Robj())
x<-mpi.scatter.Robj(x)
mpi.remote.exec(x)
mpi.bcast.cmd(x<-mpi.allgather.Robj(x))
mpi.allgather.Robj(x)
mpi.remote.exec(x)
mpi.close.Rslave()

Here is the output

> mpi.remote.exec(x) 
$slave1
[1] "apple" 
$slave2 
[1] "banana" 
$slave3 
[1] "orange" 
....
>mpi.allgather.Robj(x)
[1] "fruits" "apple" "banana" "orange" 
>mpi.remote.exec(x) 
$slave1 
[1] "fruits" "apple" "banana" "orange" 
$slave2 
[1] "fruits" "apple" "banana" "orange" 
$slave3 
[1] "fruits" "apple" "banana" "orange"

mpi.reduce and mpi.allreduce Will Reduce Data By Simple Operation

mpi_reduce_maxloc_minloc

mpi.reduce command examines a variable in the slaves & the master, do simple operation such as finding minimum or maximum value then return the value. The variable needs to exist in every slave including master, the returned value is a single value. In order for it to work, you need to call this command from all slaves and master, otherwise it will go to infinite loop.

Example 3: Set a value of x to 1 in the master, 2,3, & 4 in slave 1, 2, & 3.  Then using mpi.reduce to return a sum of all x.

library('Rmpi')
mpi.spawn.Rslaves(nslave=3)
# Define function for reduction
red<-function(option="sum"){
    mpi.reduce(x,type=2,op=option)
}
# Send a function to all slaves
mpi.bcast.Robj2slave(red)
# Set object x and send to slaves
x<-c(1,2,3,4)
mpi.bcast.cmd(x<-mpi.scatter.Robj())
x<-mpi.scatter.Robj(x)
mpi.remote.exec(x)
# call the function in slaves
mpi.remote.exec(red("sum"))
# call the same function in master
mpi.reduce(x,2,"sum")
mpi.close.Rslaves()

Here is the output

> mpi.remote.exec(red("sum"))
  X1 X2 X3
1  2  3  4
> mpi.reduce(x,2,"sum")
[1] 10

If you use mpi.allreduce, it will send the final value to all slaves. There are two more options in mpi.reduce and they are maxloc and minloc. If you use these options, the command will return two values, the value resulting from the operation (either minimum or maximum) and the location of the value. This can be useful to find the slave which provides the value.

> mpi.reduce(x,2,"maxloc")
[1] 4 3
> mpi.reduce(x,2,"minloc")
[1] 1 0

Note: the rank for the master is 0

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: