Как распараллелить функцию для пакета в R - PullRequest
0 голосов
/ 05 декабря 2018

Я бы хотел распараллелить часть пакета, над которым я работаю.Какие пакеты и какой синтаксис я должен использовать, чтобы сделать пакет гибким и пригодным для использования на разных архитектурах?Моя проблема заключается в одном вызове sapply(), как показано в следующем коде:

.heavyStuff <- function(x) { 
   # do a lot of work
   Sys.sleep(1)
}

listOfX <- 1:20

userFunc1 <- function(listOfX) {    
  res <- sapply(listOfX, .heavyStuff)
  return(res)
}

На основе различных руководств я составил следующее:

userFunc2 <- function(listOfX, dopar.arg=2) {
  if(requireNamespace("doParallel")) {
    doParallel::registerDoParallel(dopar.arg)
    res <- foreach(i=1:length(listOfX)) %dopar% {
       .heavyStuff(listOfX[[i]])
    }
    names(res) <- names(listOfX)
  } else {
    res <- sapply(listOfX, .heavyStuff)
  }
  return(res)
}

Вопросы:

  1. Можно ли безопасно использовать такой код в пакете?Будет ли это хорошо работать на ряде платформ?
  2. Есть ли способ избежать конструкции foreach()?Я бы предпочел использовать функцию, похожую на sapply или lapply.Однако конструкции в параллельной библиотеке выглядят гораздо более специфичными для платформы.
  3. Приведенный выше код не работает, если dopar.arg==NULL, хотя введение в doParallel говорит, что без каких-либоАргументы: «вы получите трех рабочих, а в Unix-подобных системах вы получите количество рабочих, равное примерно половине количества ядер в вашей системе».

1 Ответ

0 голосов
/ 06 декабря 2018

Как автор future framework, я предлагаю вам взглянуть на пакет future.apply , например

library(future.apply)
userFunc2 <- function(listOfX) {    
  res <- future_sapply(listOfX, .heavyStuff)
  return(res)
}

По умолчаниючто все работает последовательно, но если пользователь пожелает, он может использовать любой параллельный будущий бэкэнд, который ему захочется, например,

library(future)
plan(multiprocess)    # parallel on local machine - all cores by default

library(future.batchtools)
plan(batchtools_sge)  # parallel on an SGE compute cluster

library(future)
plan(sequential)      # sequentially

Шаблон проектирования таков, что вы решаете что для распараллеливания, тогда как пользователь как для распараллеливания.

...