Это продолжение Функция распараллеливания с использованием внешних указателей (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
в самом конце, без каких-либо проблем с этой проблемой.