在群集中的不同节点上并行运行RandomForest
我想在群集(大学服务器)上并行运行randomForest,我可以同时保留4个节点,每个节点还包含12个内核。我使用了foreach和doSNOW软件包,正如在foreach软件包描述中提到的一样,但通过使用以下代码,我可以看到所有负载仅在第一个节点上,而对于其他3个节点,则没有内存消耗。有人可以指导我如何编辑此代码,以便每个节点的每个核心都可以得到同样的工作,然后将其合并到一个森林中。在群集中的不同节点上并行运行RandomForest
> library("foreach")
> library("doSNOW")
> registerDoSNOW(makeCluster(48, type="SOCK"))
> x <- matrix(runif(500), 100)
> y <- gl(2, 50)
> rf <- foreach(ntree = rep(22, 48), .combine = combine, .packages = "randomForest") %dopar%
+ randomForest(x, y, ntree = ntree)
> rf
Call:
randomForest(x = x, y = y, ntree = ntree)
Type of random forest: classification
Number of trees: 1056
要开始在袜子集群的多个节点工人,第一个参数makeCluster
应节点名称而不是数字的向量。在这种情况下,makeCluster
将使用ssh
命令在每个指定节点上启动worker。
例如,在每个节点开始的12名工人 “N1”, “N2”, “N3”,以及 “N4”,你可以使用:
> nodelist <- rep(c("n1", "n2", "n3", "n4"), each=12)
> cl <- makeCluster(nodelist, type="SOCK")
> registerDoSNOW(cl)
注意,出现的每个节点名nodelist
12次,所以nodelist
的长度是48.
如果您使用批量排队系统来运行作业,您应该获得分配给作业的节点名称列表,而不是硬编码它们你的脚本。您通常可以从环境变量中获取该信息,但这取决于您的批处理排队系统。例如,扭矩则可以使用得到的节点列表:
> nodelist <- readLines(Sys.getenv("PBS_NODEFILE"))
我喜欢用makeMPIcluster
创建一个MPI集群和运行在HPC集群并行作业时doSNOW注册,但这种方法可初学者更难。例如,您必须安装Rmpi软件包,并且您必须通过“mpirun”命令执行您的R脚本。如果你能从知识渊博的系统管理员处获得帮助,那么从长远来看,它可能会更好。
另一种方法是使用doMPI并行后端而不是doSNOW,因为doMPI是专门设计用于HPC集群的。有关更多信息,请参阅doMPI vignette。
还要注意的是,如果你在这个例子中使用foreach .multicombine=TRUE
参数,你会得到更好的性能。这将导致combine
函数被调用一次而不是47次。
非常感谢您的详细回复。我正在使用的HPC使用OAR批处理调度程序。你能告诉我如何获得OAR中的节点列表吗?其次,你建议使用Rmpi而不是doSNOW?如果我使用Rmpi包,那么运行randomForest的代码将是相同的,或者我必须根据Rmpi包修改它? – Newbie
@Newbie我并不是建议你使用纯Rmpi。我建议你可以使用带有MPI集群的doSNOW(使用'makeMPIcluster'函数创建),或者可以使用doMPI而不是doSNOW。这两个选项都需要Rmpi,但不直接使用。 –
@Newbie尝试使用OAR_NODEFILE环境变量。文档表明它的工作原理与PBS_NODEFILE一样,在这种情况下,您可以使用与我的答案中列出的Torque示例基本相同的代码。 –
您是否使用批量排队系统(如Torque,LSF或Slurm)来请求四个节点? –
以下是很好的答案,但我想补充一点,您应该与您的大学群集管理员联系。他们将能够以最佳方式为您的特定群集提供帮助。 – vincentmajor