r - mclapply 因 data.table 失败
问题描述
我目前遇到了一个奇怪的情况,我使用 mclapply 并行化了一个循环。
并行调用有时会使用 mclapply 返回 NULL,但是当我使用 lapply 时一切正常。
使用 mclapply 也可以解决问题,但前提是我不使用 data.table 在调用的函数中进行子集化。
我还没有可以在此处发布的合理 mve,但可以根据要求提供代码。
简化的一般结构如下所示:
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] compiler_3.5.2 tools_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)) 中的错误:写入错误,关闭到主机的管道”。我发现令人不安的是,这些调用会默默地失败,而不会停止执行。
解决方案
无法访问您的 data.table,我希望您的问题是dist
某些组失败(可能它们太小),并且分配给同一核心的所有其他组都被返回的一组“污染”一个错误,正如 mclapply 的记录行为一样,如https://stackoverflow.com/a/57979216/415228中更全面地描述的那样。
推荐阅读
- python - 如何在 Python 中将图像划分为块、处理它们并将它们重新合并在一起?
- javascript - 我的数据没有添加到我的 firebase 实时数据库中
- c - 如何在c中重新分配数组?
- html - HTML/CSS - 如何将多个图像自动调整/缩放到 1 行
- c# - DynamoDB 或具有 .NET 持久性模型的条件
- linux - 实时随机静音部分输入音频
- css - 是否有像“all:”这样的速记 css 属性,但对于未指定的属性?
- javascript - defaultValues 不会填充 react-hook-form 中的输入字段
- c# - 如何使用 ASPX 表单中的列表项
- java - 输入后如何在同一行显示输出