R Ошибка параллельной обработки `Ошибка в checkForRemoteErrors(val): 6 узлов произвели ошибки; первая ошибка: нижний индекс выходит за пределы`

Я изучаю параллельную обработку как способ обработки огромных наборов данных.

У меня есть некоторые предопределенные переменные, как показано ниже:

CV <- function(mean, sd) {(sd / mean) * 100} 
distThreshold <- 5 # Distance threshold 
CVThreshold <- 20 # CV threshold 

LocalCV <- list()
Num.CV <- list()

Затем загрузите библиотеку parallel, распределите базовую переменную и библиотеку по кластерам:

library(parallel)
clust_cores <- makeCluster(detectCores(logical = T) ) 
clusterExport(clust_cores, c("i","YieldData2rd","CV", "distThreshold", "CVThreshold"))
clusterEvalQ(clust_cores, library(sp))

Затем передайте аргумент кластера clust_cores в parSapply:

for (i in seq(YieldData2rd)) {
  LocalCV[[i]] = parSapply(clust_cores, X = 1:length(YieldData2rd[[i]]), 
                   FUN = function(pt) {
                     d = spDistsN1(YieldData2rd[[i]], YieldData2rd[[i]][pt,])
                     ret = CV(mean = mean(YieldData2rd[[i]][d < distThreshold, ]$yield), 
                              sd = sd(YieldData2rd[[i]][d < distThreshold, ]$yield))
                     return(ret)
                   }) # calculate CV in the local neighbour 
}

stopCluster(clust_cores) 

Затем я получаю Error in checkForRemoteErrors(val) : 6 nodes produced errors; first error: subscript out of bounds в дополнение к warning messages: 1: closing unused connection (<-localhost:11688).

Пожалуйста, дайте мне знать, как решить эту проблему.

Для воспроизводимого примера я создаю большой объект списка, который отлично работает в исходном цикле for без компонентов параллельной обработки.

library('rgdal')

Yield1 <- data.frame(yield=rnorm(460, mean = 10), x1=rnorm(460, mean = 1843235), x2=rnorm(460,mean = 5802532))
Yield2 <- data.frame(yield=rnorm(408, mean = 10), x1=rnorm(408, mean = 1843235), x2=rnorm(408, mean = 5802532))
Yield3 <- data.frame(yield=rnorm(369, mean = 10), x1=rnorm(369, mean = 1843235), x2=rnorm(369, mean = 5802532))

coordinates(Yield1) <- c('x1', 'x2')
coordinates(Yield2) <- c('x1', 'x2')
coordinates(Yield3) <- c('x1', 'x2')

YieldData2rd <- list(Yield1, Yield2, Yield3)

person Golden Jiang    schedule 20.09.2018    source источник
comment
Не могли бы вы предоставить образец YieldData2rd? без него код не запускается. Кроме того, вы экспортируете i в кластер перед его определением.   -  person Omry Atia    schedule 20.09.2018
comment
Пожалуйста, найдите мой отредактированный вопрос. Небольшой образец набора данных, представленный в качестве воспроизводимого примера, отлично работает в исходном цикле for. Я экспортирую i в кластер, потому что в противном случае мне не удается найти объект i.   -  person Golden Jiang    schedule 21.09.2018
comment
когда я запускаю ваш код, как в этой исправленной версии выше, я получаю другую ошибку: Ошибка в checkForRemoteErrors(val): 4 узла произвели ошибки; первая ошибка: объект 'i' не найден. Причина в том, что для индексированных данных parApply не подходит: проверьте функцию foreach, которая является параллельной версией цикла for. Надеюсь это поможет   -  person Omry Atia    schedule 21.09.2018
comment
@OmryAtia Спасибо, я попытался переписать код с использованием пакета foreach и опубликовать ответ ниже, который, похоже, отлично работает на моей стороне. Только один вопрос, откуда я знаю, что это на самом деле быстрее, чем цикл for?   -  person Golden Jiang    schedule 21.09.2018


Ответы (1)


Спасибо за комментарий @Omry Atia, я начал изучать пакет foreach и сделал свою первую попытку.

library(foreach)
library(doParallel)

#setup parallel backend to use many processors
cores=detectCores()
clust_cores <- makeCluster(cores[1]-1) #not to overload your computer
registerDoParallel(clust_cores)

LocalCV = foreach(i = seq(YieldData2rd), .combine=list, .multicombine=TRUE) %dopar% {
                       LocalCV[[i]] = sapply(X = 1:length(YieldData2rd[[i]]), 
                                            FUN = function(pt) {
                                                  d = spDistsN1(YieldData2rd[[i]], YieldData2rd[[i]][pt,])
                                                ret = CV(mean = mean(YieldData2rd[[i]][d < distThreshold, ]$yield), 
                                                 sd = sd(YieldData2rd[[i]][d < distThreshold, ]$yield))
                                                 return(ret)
                                                 }) # calculate CV in the local neighbour 
                       }

stopCluster(clust_cores)

Он распечатает все это, не помещая LocalCV перед foreach.

Он попробует новые коды на некоторых огромных наборах данных и посмотрит, насколько быстро они могут работать.

Ссылка: параллельный запуск цикла for в R

person Golden Jiang    schedule 21.09.2018