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

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

0 ответов

Другие вопросы по тегам