mirai - Parallel Integration

Parallel Integration

mirai provides an alternative communications backend for R. This functionality was developed to fulfil a request by R Core at R Project Sprint 2023.

make_cluster() creates a cluster object of class ‘miraiCluster’, which is fully-compatible with parallel cluster types.

Created clusters may be used for any function in the parallel base package such as parallel::clusterApply() or parallel::parLapply(), or the load-balanced versions such as parallel::parLapplyLB().

library(mirai)

cl <- make_cluster(4)
cl
#> < miraiCluster | ID: `4` nodes: 4 active: TRUE >
parallel::parLapply(cl, iris, mean)
#> $Sepal.Length
#> [1] 5.843333
#> 
#> $Sepal.Width
#> [1] 3.057333
#> 
#> $Petal.Length
#> [1] 3.758
#> 
#> $Petal.Width
#> [1] 1.199333
#> 
#> $Species
#> [1] NA

status() may be called on a ’miraiCluster` to query the number of connected nodes at any time.

status(cl)
#> $connections
#> [1] 4
#> 
#> $daemons
#> [1] "abstract://72c96e3b8c531fe9d5c32bfa"
stop_cluster(cl)

Making a cluster specifying ‘url’ without ‘remote’ causes the shell commands for manual deployment of nodes to be printed to the console.

cl <- make_cluster(n = 2, url = host_url())
#> Shell commands for deployment on nodes:
#> 
#> [1]
#> Rscript -e "mirai::daemon('tcp://hostname:45985',rs=c(10407,-409141256,1907397017,-1822270330,1627186511,1735893828,-1856229003))"
#> 
#> [2]
#> Rscript -e "mirai::daemon('tcp://hostname:45985',rs=c(10407,1184372690,-983753352,952506510,543524672,1744308145,-1294231923))"
stop_cluster(cl)

Foreach Integration

A ‘miraiCluster’ may also be registered by doParallel for use with the foreach package.

Running some parallel examples for the foreach() function:

library(foreach)
library(iterators)

cl <- make_cluster(4)
doParallel::registerDoParallel(cl)

# normalize the rows of a matrix
m <- matrix(rnorm(9), 3, 3)
foreach(i = 1:nrow(m), .combine = rbind) %dopar%
  (m[i, ] / mean(m[i, ]))
#>               [,1]       [,2]      [,3]
#> result.1 1.5236796  0.6250741 0.8512463
#> result.2 1.4332458  0.1446897 1.4220646
#> result.3 0.4319478 -0.2369253 2.8049775
# simple parallel matrix multiply
a <- matrix(1:16, 4, 4)
b <- t(a)
foreach(b = iter(b, by='col'), .combine = cbind) %dopar%
  (a %*% b)
#>      [,1] [,2] [,3] [,4]
#> [1,]  276  304  332  360
#> [2,]  304  336  368  400
#> [3,]  332  368  404  440
#> [4,]  360  400  440  480