Rcpp распараллелить функции, которые возвращают XPtr?
Принимая пример XPtr
функция:
test.cpp
#include <Rcpp.h>
// [[Rcpp::export]]
SEXP funx()
{
/* creating a pointer to a vector<int> */
std::vector<int>* v = new std::vector<int> ;
v->push_back( 1 ) ;
v->push_back( 2 ) ;
/* wrap the pointer as an external pointer */
/* this automatically protected the external pointer from R garbage
collection until p goes out of scope. */
Rcpp::XPtr< std::vector<int> > p(v, true) ;
/* return it back to R, since p goes out of scope after the return
the external pointer is no more protected by p, but it gets
protected by being on the R side */
return( p ) ;
}
р
library(Rcpp)
sourceCpp("test.cpp")
xp <- funx()
xp
<pointer: 0x9618cc0>
Но если я пытаюсь распараллелить это, я получаю нулевые указатели
library(parallel)
out <- mclapply(1:2, function(x) funx())
out
[[1]]
<pointer: (nil)>
[[2]]
<pointer: (nil)>
Можно ли достичь такого рода функциональности?
редактировать
Стоит отметить, что, несмотря на повторяющийся вопрос, похоже, нет истинного решения этой проблемы. Из того, что я понимаю сейчас, XPtr
не может быть многопоточным. Так что по сути это не может быть сделано в R.
Например, когда я помещаю функцию в пакет test
и попробуйте использовать snow
он по-прежнему не может вернуть указатели.
library(test)
library(snow)
fun <- function(){
library(test)
test:::funx()
}
cl <- makeCluster(2, type = "SOCK")
clusterExport(cl, 'fun')
clusterCall(cl, fun)
[[1]]
<pointer: (nil)>
[[2]]
<pointer: (nil)>
1 ответ
Относительно
Можно ли достичь такого рода функциональности?
Я бы сказал, что ответ довольно твердый "нет", поскольку здесь применяется Первое Правило Бойцовского клуба: вы просто не можете распараллелить базовый экземпляр R, просто надеясь, что он сработает. Такие пакеты, как RcppParallel, очень осторожны при использовании не-R структур данных для многопоточной работы.
Возможно, я слишком пессимистичен, но я бы поместил "уровень сбора" на один уровень глубже и вернул бы только агрегированный результат R.