Распараллеливание внутри функции в R - избегая автоматического c экспорта объектов в кластер - PullRequest
0 голосов
/ 23 апреля 2020

В R я хочу иметь возможность создавать кластеры psock, используя параллельный пакет, и избегать (я думаю, очень плохо спроектированного) поведения, когда все объекты в функции автоматически экспортируются в кластер (при запуске из globalenv). , объекты не экспортируются). Я надеялся, что смогу сделать это путем оценки из globalenv, но, как вы увидите в testfunc2 (), это не работает. Я хочу сделать это, чтобы избежать ненужных издержек сериализации в моих функциях. В этой тестовой функции затраченное время ничтожно мало, у меня есть приложения, где оно ничтожно мало.

Ранее я задавал связанный вопрос: R - ужасная производительность распараллеливания внутри функции из-за бессмысленной сериализации, как ее улучшить? и странного взлома, который я разместил в комментариях, было достаточно для этой проблемы, но я все еще думаю / надеюсь, что то, что я сейчас спрашиваю, «должно быть» возможно.

library(parallel)

#all works as expected in the global environment
bob <- 4
cl=makeCluster(2,type='PSOCK')
clusterCall(cl,function(x) bob) #error initially
clusterExport(cl,'bob')
clusterCall(cl,function(x) bob) #but fine after explicitly sending bob to cl
stopCluster(cl)
rm(bob)

#inside a function, parallelisation is madness
testfunc <- function(){
  bob <- 4
  cl=makeCluster(2,type='PSOCK')
  x <- clusterCall(cl,function(x) bob) #I want this to generate: Error: object 'bob' not found
  stopCluster(cl)
  return(x)
}

testfunc()

#tried evaluating in globalenv, setting cluster to globalenv, passing text string...
testfunc2 <- function(){
  bob <- 4
  cl=eval(makeCluster(2,type='PSOCK'),envir = globalenv())
  environment(cl) <- globalenv()
  x <- eval(clusterCall(cl,function(x) eval(parse(text='bob'))),envir = globalenv())
  stopCluster(cl)
  return(x)
}

testfunc2()

1 Ответ

0 голосов
/ 23 апреля 2020

Хорошо, сработал другой вариант того, что я пробовал выше:

testfunc3 <- function(doexport=FALSE){
  bob <- 4
  jane <- 7
  cl=makeCluster(2,type='PSOCK')
  if(doexport) clusterExport(cl,'bob',envir = environment())
  x <- clusterCall(cl,function(x) eval(parse(text='bob'),envir=globalenv()))
  x <- clusterCall(cl,function(x) eval(parse(text='jane'),envir=globalenv()))
  stopCluster(cl)
  return(x)
}

testfunc3()
testfunc3(TRUE) #now only errors on jane, which is not exported
...