【问题标题】:How to do parallel computing inside a cluster with the R future package?如何使用 R 未来包在集群内进行并行计算?
【发布时间】:2017-10-12 14:46:53
【问题描述】:

我想在集群的节点(多台机器)内分配作业(带有for 循环)。我尝试使用 R 包future 来做到这一点。我不知道这是否是最好的方法;我尝试使用doParallel 包的foreach,但没有成功。如何判断循环迭代次数何时大于集群节点数?

library(doParallel);
library(doFuture);
#library(future);

registerDoFuture();

workers <- c(rep("129.20.25.61",1), rep("129.20.25.217",1));
cl <- makeClusterPSOCK(workers, revtunnel = TRUE, outfile = "", verbose = FALSE);

plan(cluster, workers = cl)

mu <- 1.0
sigma <- 2.0

for(i in 1:3){
 res %<-%{ rnorm(i, mean = mu, sd = sigma)}
 print(i);
}

【问题讨论】:

    标签: r parallel-processing cluster-computing r-future


    【解决方案1】:

    如果你使用普通的Future API,即future()+value()%&lt;-%,则不需要涉及foreach,doFuture等。这里是如何单独使用Future API以及你可以输出什么期望:

    (A) 设置工人

    library("future")
    
    workers <- c("129.20.25.61", "129.20.25.217")
    cl <- makeClusterPSOCK(workers, revtunnel = TRUE, outfile = "")
    ### starting worker pid=20026 on localhost:11900 at 11:47:28.334
    ### starting worker pid=12291 on localhost:11901 at 11:47:37.172
    
    print(cl)
    ### socket cluster with 2 nodes on hosts '129.20.25.61', '129.20.25.217'
    
    plan(cluster, workers = cl)
    

    (B) 显式未来 API

    这里我们使用future() 显式创建期货列表,并使用values() 检索它们的值(基本上等于调用lapply(f, FUN = value))。

    mu <- 1.0
    sigma <- 2.0
    
    f <- list()
    for (i in 1:3) {
      f[[i]] <- future({ rnorm(i, mean = mu, sd = sigma) })
    }
    v <- values(f)
    str(v)
    ### List of 3
    ###  $ : num 3.25
    ###  $ : num [1:2] 3.24 3.29
    ###  $ : num [1:3] 1.251 2.299 0.923
    

    (C) 隐式未来 API

    在这个替代方案中,我们使用未来赋值运算符 %&lt;-% 隐式创建期货(当您尝试访问未来的值时,它将在内部执行 future()value())。由于%&lt;-% 只能分配给环境(而不是列表、data.frames 等),我们需要使用作为环境的容器。这里我使用了 listenv 类,它是一个环境,但允许您将其作为列表进行索引。

    library("listenv")  ## listenv()
    mu <- 1.0
    sigma <- 2.0
    
    v <- listenv()
    for (i in 1:3) {
      v[[i]] %<-% { rnorm(i, mean = mu, sd = sigma) }
    }
    v <- as.list(v)
    str(v)
    ### List of 3
    ###  $ : num 1.15
    ###  $ : num [1:2] 2.2277 -0.0164
    ###  $ : num [1:3] -2.09 3.34 -1.09
    

    (D) 使用future_lapply()

    如果您更喜欢lapply()-like 方法,您可以这样做:

    v <- future_lapply(1:3, FUN = function(i) {
      rnorm(i, mean = mu, sd = sigma)
    })
    str(v)
    ### List of 3
    ###  $ : num 2.12
    ###  $ : num [1:2] 2.56 -1.21
    ###  $ : num [1:3] 2.89 -0.159 -0.983
    

    (D) 使用foreach()

    如果您想使用foreach(),那么您可以执行以下操作。请注意,在每个 foreach 设计中使用 foreach() 时,最好始终显式导出全局变量 - 但是,如果您始终使用 doFuture,则实际上不需要。

    library("doFuture")
    registerDoFuture()
    workers <- c("129.20.25.61", "129.20.25.217")
    cl <- makeClusterPSOCK(workers, revtunnel = TRUE, outfile = "")
    plan(cluster, workers = cl)
    
    v <- foreach(i = 1:3, .export = c("mu", "sigma")) %dopar% {
      rnorm(i, mean = mu, sd = sigma)
    }
    str(v)
    ### List of 3
    ###  $ : num 3.12
    ###  $ : num [1:2] -0.0887 -2.8016
    ###  $ : num [1:3] 2.15 3.5 -2.24
    

    如何确定循环迭代次数何时更高 超过集群节点数?

    我不确定你在这里问什么。您是否担心在有工人的情况下同时运行更多的期货?如果是这样,那将自动得到处理。如果所有工作人员都被占用,那么额外期货的创建将被阻止,直到其中一名工作人员再次可用。

    【讨论】:

    • 谢谢!确切地说,我担心在你有工人的情况下同时运行更多的期货。我还有一个问题,如果将来我想保存一个 txt 文件并将它们发送到主计算机内的文件夹中,是否可以这样做?
    • future 没有文件传输协议,如果你正在寻找的话。因此,除非 master 和 worker 共享相同的文件系统,否则“将结果传递回 master”的唯一方法是通过 v %&lt;-% expr 中的未来表达式 expr 的值 v;很像它对正则表达式的工作原理v &lt;- expr
    猜你喜欢
    • 1970-01-01
    • 2020-04-26
    • 2020-12-16
    • 1970-01-01
    • 2012-05-29
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多