Используя parLapply параллельного интерфейса: невозможно получить доступ к переменным в параллельном коде

Недавно у меня был компьютер с несколькими ядрами, и я учусь использовать параллельные вычисления. Я довольно опытный с lapply и было сказано parLapply работает очень похоже. Я не работаю правильно, хотя. Кажется, я должен явно поместить все в parLapply заставить его работать (то есть используемые функции, переменные и т. д.). С lapply он читает из родительской среды и parLapply похоже, не делает этого. Так что в моем примере ниже я мог бы заставить все работать, поместив всю информацию внутри parLapply но если я использую это внутри определенной пользователем функции, я не могу явно поставить text.var Внутри parLapply,

library(parallel)
text.var <- rep("I like cake and ice cream so much!", 20)
ntv <- length(text.var)
gc.rate <- 10

pos <-  function(i) {
    paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
}

lapply(seq_len(ntv), function(i) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }

)

#doesn't work
cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }

)

#does work but have to specify all the stuff inside parLapply
cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i) {
        ######stuff I have to put inside parLapply##########
        text.var <- rep("I like cake and ice cream so much!", 20)
        ntv <- length(text.var)
        gc.rate <- 10
        pos <-  function(i) {
            paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
        }
        ######stuff I have to put inside parLapply##########
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }
)

Как я могу пройти text.var, ntv, gc.rate, а также pos в parLapply без явного помещения их внутрь? (Я предполагаю, что вы передаете их как список как-то)

PS Windows 7 машина, поэтому мне нужно использовать parLapply Я думаю

3 ответа

Решение

Вам необходимо экспортировать эти переменные в другие процессы R в кластере:

cl <- makeCluster(mc <- getOption("cl.cores", 4))
clusterExport(cl=cl, varlist=c("text.var", "ntv", "gc.rate", "pos"))

Альтернативный метод, предоставленный Мартином Морганом, также будет работать здесь.

Этот метод предоставляет объекты каждому узлу кластера непосредственно в parLapply вызов без необходимости использовать экспорт кластера:

library(parallel)
text.var <- rep("I like cake and ice cream so much!", 20)
ntv <- length(text.var)
gc.rate <- 10

pos <-  function(i) {
    paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
}

cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i, pos, text.var, ntv, gc.rate) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }, pos, text.var, ntv, gc.rate
)
out1<-lapply(seq_len(ntv), function(i) {x <- pos(text.var[i]);if (i%%gc.rate==0) gc();return(x)})
out2<-parLapply(cl, seq_len(ntv), function(i) {x <- pos(text.var[i]);if (i%%gc.rate==0) gc();return(x)})

>     identical(out1,out2)
# [1] TRUE
require(rbenchmark)
benchmark(lapply(seq_len(ntv), function(i) {x <- pos(text.var[i]);if (i%%gc.rate==0) gc();return(x)}),parLapply(cl, seq_len(ntv), function(i) {x <- pos(text.var[i]);if (i%%gc.rate==0) gc();return(x)}))


                                                                                       test
#1        lapply(seq_len(ntv), function(i) {\n    x <- pos(text.var[i])\n    if (i%%gc.rate == 0) \n        gc()\n    return(x)\n})
#2 parLapply(cl, seq_len(ntv), function(i) {\n    x <- pos(text.var[i])\n    if (i%%gc.rate == 0) \n        gc()\n    return(x)\n})
#  replications elapsed relative user.self sys.self user.child sys.child
#1          100   20.03 3.453448     20.31     0.05         NA        NA
#2          100    5.80 1.000000      0.22     0.03         NA        NA

> cl
socket cluster with 2 nodes on host ‘localhost’
Другие вопросы по тегам