我目前遇到一个奇怪的情况,我使用mclapply进行了并行化。
并行调用有时会使用mclapply返回NULL,但是当我使用lapply时一切正常。
mclapply也可以正常工作,但前提是我不使用data.table进行子集调用。
我还没有一个合理的工具可以在这里发布,但是可以根据要求提供代码。
简化后的一般结构如下:
foo <- function(d) { # d is a data.table
unlist(mclapply(1:nrow(d), function(i) bar(d[-i])))
}
bar <- function(d) {
...
## this version fails:
pdists <- lapply(unique(d$comp),
function(cc) dist(d[d$comp==cc,.(X,Y)]))
## this also fails:
pdists <- lapply(unique(d$comp),
function(cc) dist(d[cc, .(X,Y), on="comp"]))
## this way it works:
pdists <- lapply(unique(d$comp),
function(cc) dist(d[d$comp==cc,c("X","Y")]))
...
}
查看mclapply返回什么并检查哪些元素为NULL时,我得到:
write error, closing pipe to the master
[1] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
[25] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
...
[337] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
[349] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
这几乎看起来像是四个线程死亡之一(我使用mc.cores = 4)。
data.table中的线程安全是否存在问题?
(我已经在两台不同的计算机上重现了该问题)
> sessionInfo()
R version 3.5.2 (2018-12-20)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.2 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_DK.utf8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=de_CH.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=de_CH.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=de_CH.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.12.0
通过名称空间(未附加)加载: [1]编译器_3.5.2工具_3.5.2
更新:根据@jangorecki的评论,我添加了setDTthreads(1)
,但仍然发生错误。我再次尝试了不同的版本:
## works:
pdists <- lapply(split(d[,.(comp,X,Y)], by="comp", keep.by=FALSE), FUN=dist)
## these fail:
pdists <- lapply(unique(d$comp), function(cc) dist(d[cc, .(X,Y), on="comp"]))
pdists <- lapply(unique(d$comp), function(cc) dist(d[comp==cc,.(X,Y)]))
更新2 :有趣的是,时间发挥了作用。通过在被调用函数bar
中引入随机延迟,并以mc.preschedule = FALSE
作为mclapply
的参数,失败的调用次数会有所不同。
总是第三次失败的呼叫(带有mc.cores> = 3),再加上许多连续的呼叫。 mclapply
返回的列表中的对应值为NULL。
对于这些调用,我还看到“在sendMaster(try(eval(expr,env),silent = TRUE))中出错:写入错误,关闭了到主服务器的管道”。我感到不安的是,这些调用默默地失败了,没有停止执行。
答案 0 :(得分:0)
无法访问您的data.table,我希望您的问题是某些组的dist
失败了(也许它们太小了),分配给同一核心的所有其他组都是“由一组“污染”返回错误,如mclapply记录的行为一样,如https://stackoverflow.com/a/57979216/415228中所述。