在群集中的不同节点上并行运行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 
+0

您是否使用批量排队系统(如Torque,LSF或Slurm)来请求四个节点? –

+0

以下是很好的答案,但我想补充一点,您应该与您的大学群集管理员联系。他们将能够以最佳方式为您的特定群集提供帮助。 – vincentmajor

要开始在袜子集群的多个节点工人,第一个参数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次。

+0

非常感谢您的详细回复。我正在使用的HPC使用OAR批处理调度程序。你能告诉我如何获得OAR中的节点列表吗?其次,你建议使用Rmpi而不是doSNOW?如果我使用Rmpi包,那么运行randomForest的代码将是相同的,或者我必须根据Rmpi包修改它? – Newbie

+0

@Newbie我并不是建议你使用纯Rmpi。我建议你可以使用带有MPI集群的doSNOW(使用'makeMPIcluster'函数创建),或者可以使用doMPI而不是doSNOW。这两个选项都需要Rmpi,但不直接使用。 –

+0

@Newbie尝试使用OAR_NODEFILE环境变量。文档表明它的工作原理与PBS_NODEFILE一样,在这种情况下,您可以使用与我的答案中列出的Torque示例基本相同的代码。 –