В настоящее время я столкнулся со странной ситуацией с циклом, который я распараллеливаю, используя mclapply.
Параллельные вызовы иногда возвращают NULL с mclapply, но все работает, когда я использую 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
Thisвыглядит почти как один из четырех потоков (я использую 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)): ошибка записи, закрытие канала длямастер "для этих звонков.Что меня беспокоит, так это то, что эти вызовы молча терпят неудачу, не останавливая выполнение.