问题
Taking an example XPtr
function:
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 ) ;
}
R
library(Rcpp)
sourceCpp("test.cpp")
xp <- funx()
xp
<pointer: 0x9618cc0>
But if I try to parallelize this I get null pointers
library(parallel)
out <- mclapply(1:2, function(x) funx())
out
[[1]]
<pointer: (nil)>
[[2]]
<pointer: (nil)>
Is it possible to achieve this kind of functionality?
Edit
It is worth noting that despite a duplicate question there appears to be no true solution to this problem. From what I understand now, an XPtr
is not able to be multi-threaded. So essentially this cannot be done in R.
For example, when I put the function inside package test
and try to use snow
it still fails to return the pointers.
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:
Regarding
Is it possible to achieve this kind of functionality?
I would say the answer is a pretty firm 'nope' as the First Rule of Fight Club applies here: you simply cannot parallelise the underlying R instance merely by hoping it would work. Packages like RcppParallel are very careful about using non-R data structures for multithreaded work.
I may be too pessimistic but I would place the 'collection level' one level deeper, and only return its aggregated result to R.
来源:https://stackoverflow.com/questions/37167479/rcpp-parallelize-functions-that-return-xptr