Экспорт входных данных функции в параллельной обработке в R - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь написать функцию с возможностью параллельных вычислений. Чтобы заставить его работать как в средах windows, так и в среде ma c или Linux, я использую систему PSOCK, которая, на мой взгляд, является конфигурацией по умолчанию в makeCluster(). Мой вопрос заключается в том, должен ли я или более желательно передать все аргументы в кластеры с помощью функции clusterExport. Если я сделаю это, я думаю, что мне нужно оценить все входные аргументы - вместо ленивых вычислений по умолчанию. Если некоторые переменные используются только в некоторых особых случаях, это не представляется желательным.

Например, в следующем коде мне интересно, следует ли мне добавить clusterExport(varlist = c("a","b","c"),cl = cl,envir = environment()) в функцию. Следующий код прекрасно работает на моем компьютере, но подобный код не сработал на другом компьютере.

Мне было бы очень интересно услышать о наилучшей практике. Спасибо!

library(pbapply)
foo = function(a=3, b=4, c=5, B = 8, parallel = FALSE){

  if(parallel) {cl = makeCluster(4) } else{cl = NULL}


  # default a,b,c values are desired to be used 
  if(a>5){
    # c is used only in this case 
    v= pbsapply(1:B,FUN = function(i) {Sys.sleep(.5); a+b+c+i},cl = cl) 
  }else{
    v= pbsapply(1:B,FUN = function(i) {Sys.sleep(.5); a+b+i},cl = cl) 
  }

  if(parallel) stopCluster(cl)

  return(v)
}

system.time(foo())
system.time(foo(parallel = T))

1 Ответ

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

Вы можете попытаться установить значения по умолчанию NULL и выполнить обработку регистра с использованием sapply. Я не уверен, однако, если это действительно работает, потому что я не могу воспроизвести вашу ошибку.

foo <- function(a=NULL, b=NULL, c=NULL, B=NULL, parallel=FALSE) {
  if (parallel) {
    cl <- makeCluster(detectCores() - 4)  ## safer to code this more dynamically
    ## case handling:
    sapply(c("a", "b", "c", "B"), function(x) {
      if (!is.null(get(x))) clusterExport(cl, x, environment())
    })
  } else { 
    cl <- NULL
  }
  # default a,b,c values are desired to be used 
  if (a > 5) {
    # c is used only in this case 
    v <- pbsapply(1:B, FUN=function(i) {
      Sys.sleep(.2)
      a + b + c + i
    }, cl=cl) 
  } else {
    v <- pbsapply(1:B, FUN=function(i) {
      Sys.sleep(.2)
      a + b + i
    }, cl=cl) 
  }
  if (parallel) stopCluster(cl)
  return(v)
}

foo(a=3, b=4, c=5, B=8, parallel=TRUE)
#   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
# [1]  8  9 10 11 12 13 14 15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...