R нестандартная оценка: получить значение обещания, оставив его без оценки [или: сохранить внешний указатель действительным ...] - PullRequest
0 голосов
/ 19 февраля 2019

Это продолжение Функция распараллеливания с использованием внешних указателей (XPtr)

Я не буду здесь воспроизводить код Cpp, чтобы сделать вещи короче.Проблема заключалась в том, что после оценки параметра функции он определяется в среде функции и, в случае внешнего указателя, больше не доступен в кластере вилок.

Так что пока эта функцияработал:

require(parallel)
test1 <- function(a) {
  cl <- makeForkCluster(nnodes=2)
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

Эта функция не:

test2 <- function(a) {
  cl <- makeForkCluster(nnodes=2)
  p <- g(a, 0)
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

Как указал Ральф Стубнер, это произошло из-за того, что вызов g(a, 0) вызвал оценку обещанияa.Он предложил следующую работу (здесь с двумя отладочными отпечатками, чтобы понять, как это работает):

test3 <- function(a) {
  cl <- makeForkCluster(nnodes = 2)
    print(pryr::promise_info(a))
  b <- eval(substitute(a))
  p <- g(b, 0)
    print(pryr::promise_info(a))
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

Это позволило получить доступ ко всему, что было в a, но a все еще оставалось невыполненным обещанием.Но это не работает, когда test3 вызывается из другой функции!

test4 <- function(b) test1(b)
test5 <- function(b) test3(b)

В то время как test4 работает хорошо (рекурсивная оценка обещания дает правильный указатель), обходной путь в test3больше не работает при вызове с test5.

Отладочные отпечатки показывают, что, несмотря на уловку eval(substitute(a)), обещание оценивается.Насколько я понимаю, этот трюк заставляет оценивать обещание b из test5 в его окружении, таким образом, a также оценивается.

Есть ли другой обходной путь?(Я пытался играть с pryr::parent_promise, но даже код из примера на странице руководства дает странные результаты).

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

...