我必须运行很多随机森林模型,所以我想在我的 8 核服务器上使用 doParallel 来加速这个过程。
然而,某些模型需要比其他模型更长的时间,甚至可能会引发错误。我想并行运行 8 个模型,如果模型抛出错误和/或被跳过,那么工作人员应该继续。每个模型结果都保存在硬盘上,以便我以后可以访问和组合它们。
TryCatch
Run Code Online (Sandbox Code Playgroud)
或者
.errorhandling="remove"
Run Code Online (Sandbox Code Playgroud)
没有解决问题。我得到
Error in unserialize(socklist[[n]]) : error reading from connection
Run Code Online (Sandbox Code Playgroud)
代码示例:我用 %do% 试了一下,模型 2-7 运行成功。然而在 %dopar% 我得到了显示的错误
foreach(model=1:8, .errorhandling="remove") %dopar% {
tryCatch({
outl <- rf_perform(...)
saveRDS(outl,file=getwd() %+% "/temp/result_" %+% model %+% ".rds")
}, error = function(e) {print(e)}, finally = {})
}
Run Code Online (Sandbox Code Playgroud) 以下问题是与此处描述的问题相关的非常详细的问题。上一个问题
使用Ubuntu Server 14.04 LTS 64位Amazon Machine Image在具有R版本3.2.3的c4.8xlarge(36核)上启动。
考虑以下代码
library(doParallel)
cl=makeCluster(35)
registerDoParallel(cl)
tryCatch({
evalWithTimeout({
foreach(i=1:10) %:%
foreach(j=1:50) %dopar% {
tryCatch({
evalWithTimeout({
set.seed(j)
source(paste("file",i,".R", sep = "")) # File that takes a long time to run
save.image(file=paste("file", i, "-run",j,".RData",sep=""))
},
timeout=300); ### Timeout for individual processes
}, TimeoutException=function(ex) {
return(paste0("Timeout 1 Fail ", i, "-run", j))
})
}
},
timeout=3600); ### Cumulative Timeout for entire process
}, TimeoutException=function(ex) {
return("Timeout 2 Fail")
})
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
请注意,这两个超时异常均有效。我们注意到单个进程超时,如果有必要,还会出现累积进程超时。
但是,我们发现单个进程可以启动,并且由于未知的原因,300秒后不会超时。请注意,单个进程超时可确保该进程不会“花费很长时间”。结果,内核被该单个进程占据,并以100%的速度运行,直到达到3600秒的累积超时。请注意,如果累积超时不到位,则该过程及其核心将被无限期占用,并且foreach循环将无限期继续。一旦达到累积时间,将返回“超时2失败”,脚本将继续。
问题:如果某个单独的工作进程以某种方式“挂起”,即使单独的超时机制也无法正常工作,那么如何重新启动该工作程序,以便继续在并行处理中使用它?如果无法重新启动工作程序,是否可以以达到累积超时时以外的其他方式停止工作程序?这样做将确保在仅运行单个“错误”进程时,该进程不会在“等待”达到累积超时的延长时间内继续进行。 …
我正在分别具有 4 个和 8 个物理和逻辑内核的 PC(OS Linux)上运行以下代码(从doParallel 的 Vignettes 中提取)。
运行代码iter=1e+6或更少,一切都很好,我可以从 CPU 使用率中看到所有内核都用于此计算。然而,随着迭代次数的增多(例如iter=4e+6),在这种情况下并行计算似乎不起作用。当我还监视 CPU 使用率时,只有一个核心参与计算(100% 使用率)。
示例 1
require("doParallel")
require("foreach")
registerDoParallel(cores=8)
x <- iris[which(iris[,5] != "setosa"), c(1,5)]
iter=4e+6
ptime <- system.time({
r <- foreach(i=1:iter, .combine=rbind) %dopar% {
ind <- sample(100, 100, replace=TRUE)
result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit))
coefficients(result1)
}
})[3]
Run Code Online (Sandbox Code Playgroud)
你知道可能是什么原因吗?记忆可能是原因吗?
我四处搜索,发现这与我的问题有关,但重点是我没有出现任何错误,而且 OP 似乎通过在内部提供必要的包来提出解决方案foreach循环。但是可以看出,我的循环中没有使用任何包。
更新1
我的问题还是没有解决。根据我的实验,我不认为记忆可能是原因。我在运行以下简单并行(在所有 8 个逻辑内核上)迭代的系统上有 8GB 内存:
例2
require("doParallel")
require("foreach")
registerDoParallel(cores=8)
iter=4e+6
ptime <- system.time({
r <- foreach(i=1:iter, …Run Code Online (Sandbox Code Playgroud) 假设我有一个 8 核 CPU。doParallel在 R 中使用,当我注册时makeCluster(x),理想的核心数是x多少?
是尽可能多的核心吗?或者使用 7 核会比使用 6 核慢吗?有什么规则可以解决这个问题吗?
我正在使用foreach和parallel库来执行并行计算,但由于某种原因,在运行时,它一次仅使用 1 个 CPU(我使用“top”(Linux 终端上的 Bash)进行查找。
服务器有48核,我尝试过:
list.of.packages <- c("foreach", "doParallel")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if (length(new.packages)) install.packages(new.packages)
library(foreach)
library(doParallel)
no_cores <- detectCores() / 2 # 24 cores
cl<-makeCluster(no_cores)
registerDoParallel(cl)
df.a = data.frame(str = cbind(paste('name',seq(1:60000))), int = rnorm(60000))
df.b = data.frame(str = sample(df.a[, 1]))
df.b$int = NA
foreach(row.a = 1:length(df.a$str),
.combine = rbind,
.verbose = T) %dopar% {
row.b = grep(pattern = df.a$str[row.a], x = …Run Code Online (Sandbox Code Playgroud) 我有一个函数 doSomething(),它在 foreach 循环中运行,因此将一些计算保存为 .csv 文件。因此,我不需要 foreach 的返回值,实际上我不想要返回值,因为它使我的记忆混乱到无法运行尽可能多的迭代的程度。
如何强制 foreach 没有返回值,或删除迭代的返回值?
这是一个说明我的问题的最小示例:
cl <- parallel::makePSOCKcluster(1)
doParallel::registerDoParallel(cl)
"%dopar%" <- foreach::"%dopar%"
doSomething <- function () {
a <- as.numeric(1L)
}
foreach::foreach (i = 1:4) %dopar% {
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
输出是:
[[1]]
[1] 1
[[2]]
[1] 1
[[3]]
[1] 1
[[4]]
[1] 1
Run Code Online (Sandbox Code Playgroud) 目前我正在开发一个小型 R 项目,从 Word 文件中读取一些信息。由于这些是底层的压缩 xml 文件,我认为使用 R 来完成这个任务会非常容易。我的脚本基本上可以工作,但我想提高它的速度,所以我查看了 和doParallel包foreach。
library(foreach)
library(doParallel)
cores <- detectCores()
cl <- makeCluster(cores - 1)
registerDoParallel(cl)
file_list <- list.files(path = "/path/to/word/files", pattern = glob2rx("*.docx"), ignore.case = TRUE, full.names = TRUE, recursive = TRUE)
final <- foreach(
filename = file_list[1:4], .combine = rbind, .packages = c("stringr", "xml2", "tibble"),
.verbose = T, .inorder = FALSE
) %dopar% {
name <- str_extract(filename, "[0-9a-f]{40}")
# doc <- read_xml(unzip(zipfile = filename, files = c("word/document.xml")), encoding = …Run Code Online (Sandbox Code Playgroud) 这是出于好奇而提出的一般性问题。我正在使用该doParallel包进行并行计算。我使用这些包来进行模拟。
我观察到,当我使用foreach循环进行模拟时,Rstudio 中的当前使用内存急剧上升 (4+GiB),并且 Rstudio 有时崩溃。
现在我再次parallel::mclapply进行了相同的模拟,但令人惊讶的是没有问题,并且当前使用内存没有增加太多(10+MiB)。
我不明白代码内部发生了什么。我期待对上述过程的详细解释。
sessionInfo()因为我的 R 是
R version 4.2.1 (2022-06-23) -- "Funny-Looking Kid"
Copyright (C) 2022 The R Foundation for Statistical Computing
Platform: aarch64-apple-darwin20 (64-bit)
Run Code Online (Sandbox Code Playgroud)
操作系统是MacOS。
doParallel软件包版本 1.0.17。
RStudio 版本 2023.03.01。
假设我们正在尝试计算 Erdos-Renyi 图的边数。我试图每次模拟图形并存储每次模拟的边计数值。
代码如下
#ER random graph generator
src1 <- {"#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix ER_AdjMatGEN_cpp(int N, double p){
NumericMatrix temp(N,N);
for(int i=0; i< N; i++){
for(int j=0; j < i; j++){ …Run Code Online (Sandbox Code Playgroud) 我目前正在处理一些大型数据集,因此并行化工作流程是唯一的方法.
我需要在开始时为每个线程加载一些包(即:for(this.thread in threads) { #load some packages }.
不幸的是,我不知道该怎么做.
下面的代码进一步说明我的问题,在这里我想使用管道操作者magrittr在%dopar%:
.
library(parallel)
library(doParallel)
library(foreach)
library(magrittr)
# Generate some random data and function :
# -----------------------------------------
randomData = runif(10^3)
randomFunction = function(x) {x * (2^x) }
randomData[1] %>% randomFunction #Works
# And now ... The parallel part :
# --------------------------------
myCluster = makeCluster(6)
registerDoParallel(myCluster)
# Test that the do par is up and running:
foreach(i = randomData) %dopar% { i }
# Use magrittr …Run Code Online (Sandbox Code Playgroud) 我正在尝试招募更多核心来增加我正在分析的一些激光雷达数据的处理时间,但我不断收到“makePSOCKcluster(names = spec, ...) 中的错误:集群设置失败。3 个工作人员中的 3 个无法连接。” 我运行此命令后:
UseCores <-detectCores() -1
cl <- makeCluster(UseCores)
registerDoParallel(cl)
foreach(i=1:lengthcanopy_list)) %dopar% {
library(raster)
ttops <- vwf(CHM = canopy_test, winFun = lin, minHeight = 2, maxWinDiameter = NULL)
}
Run Code Online (Sandbox Code Playgroud)
为什么我会收到此错误?我该如何修复它?