Как вернуть ошибки из каждого узла параллельного процесса - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь использовать пакет parallel (на самом деле я хотел бы, чтобы решение этой проблемы было общим, чтобы я мог использовать любой пакет распараллеливания) для запуска данной функции и возврата любых ошибок из любого изузлы, которые возвращают один. Давайте рассмотрим простой пример.

parallel::parLapply(
  cl = parallel::makeCluster(2),
  list(1, 2),
  fun = function(x) {
    print(x)
    stop('test')
  }
)

Так что в этом случае моя функция печатает заданное значение, а затем возвращает ошибку. Если я запускаю этот код, я получаю следующую ошибку

Error in checkForRemoteErrors(val) : 
  2 nodes produced errors; first error: test

Поэтому я попытался обернуть код в tryCatch

tryCatch(
  parallel::parLapply(
    cl = parallel::makeCluster(2),
    list(1, 2),
    fun = function(x) {
      print(x)
      stop('test')
    }
  ),
  error = function(e) e
)

, который дает ошибку

<simpleError in checkForRemoteErrors(val): 2 nodes produced errors; first error: test>

Я также попытался обернуть саму функцию в tryCatch безрезультатно.

fun <- function(x) {
  print(x)
  stop('test')
}

parallel::parLapply(
  cl = parallel::makeCluster(2),
  list(1, 2),
  fun = tryCatch(fun, error = function(e) e)
)

это дает ошибку

Error in checkForRemoteErrors(val) : 
  2 nodes produced errors; first error: test

Я знаю, что это будет работать, если я включуtryCatch внутри фактической функции, например

parallel::parLapply(
  cl = parallel::makeCluster(2),
  list(1, 2),
  fun = function(x) {
    print(x)
    tryCatch(stop('test'), error = function(e) e)
  }
)

, это возвращает

[[1]]
<simpleError in doTryCatch(return(expr), name, parentenv, handler): test>

[[2]]
<simpleError in doTryCatch(return(expr), name, parentenv, handler): test>

Но я хочу иметь возможность передавать любую случайную функцию в parLapply, и поэтому явозможно, не удастся добавить tryCatch, и я не хочу добавлять его только для целей параллельного процесса - я бы предпочел добавить что-то один раз в самом распараллеливании.

1 Ответ

0 голосов
/ 17 октября 2019

Таким образом, решение этой проблемы - заключить фактический вызов функции в tryCatch, но вы должны убедиться, что функция доступна в каждом кластере. Вы можете сделать это, экспортировав его, используя clusterExport, если он недоступен из пакета.

fun <- function(x) {
  print(x)
  stop('test')
}

cl <- parallel::makeCluster(2)

parallel::clusterExport(cl, "fun", env = environment())

parallel::parLapply(
  cl = cl,
  list(1, 2),
  fun = function(x) tryCatch(fun(x), error = function(e) e)
)

Это вернет ошибки, как и ожидалось

[[1]]
<simpleError in fun(x): test>

[[2]]
<simpleError in fun(x): test>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...