首页 > 解决方案 > 如何从 Rcpp 函数中并行调用用户定义的 R 函数?

问题描述

我正在编写一个使用用户定义的 R 函数的 R 包。这些函数需要在 Rcpp 函数中多次评估。

我看到了两条出路:

1- 使用 RInline 创建几个 R 会话,在每个 R 会话中使用不同的参数评估函数,然后收集这些结果?

2- 围绕用户定义的 R 函数编写一个包装器,以便对其进行矢量化并并行评估 R 函数的不同输入。然后将此函数传递给 Rcpp,希望在调用时 R 函数仍将并行运行。

我不确定这些方法是否可行。尝试第二个很容易!但也许有人有更好的解决方案。

标签: rparallel-processingrcpp

解决方案


我想我有第二个工作选择。无论如何,感谢您的快速回复。我也认为第一种方法可以奏效。但这足以满足我的目的。请参见下面的示例:

library(Rcpp)
library(future.apply)


userfunc<-function(x){
   Sys.sleep(1)
   return(x)
}
 

wrapperufpar<-function(xvec){
   plan(multisession)
   future_sapply(xvec, userfunc)
 } 
   cppFunction('NumericVector cppfunc(NumericVector xvec, Function ufunc) {
  NumericVector out(xvec.length());
  for (int i=0;i<xvec.length();i++){
   out(i)=as<double>(ufunc(xvec(i)));
   }
   return out;
 }')

 
cppFunction('NumericVector cppfuncpar(NumericVector xvec, Function ufuncw) {
  NumericVector out=as<NumericVector>(ufuncw(xvec));
   return out;
 }')

 cppfunc(1:10, userfunc)
 [1]  1  2  3  4  5  6  7  8  9 10
 cppfuncpar(1:10, wrapperufpar)
 [1]  1  2  3  4  5  6  7  8  9 10
 
 microbenchmark::microbenchmark(wrapperufpar(1:10),
                                sapply(1:10, userfunc),
                                cppfunc(1:10, userfunc),
                                cppfuncpar(1:10, wrapperufpar),
                                times=10)

单位:秒

                       expr       min        lq      mean    median
    wrapperufpar(1:10)  4.372158  4.456099  4.488181  4.477420
    sapply(1:10, userfunc) 10.002320 10.003834 10.005113 10.004944
    cppfunc(1:10, userfunc) 10.002743 10.004133 10.005217 10.004824
    cppfuncpar(1:10, wrapperufpar)  4.434338  4.475258  4.490961  4.491418


       uq       max neval
 4.548762  4.564422    10
10.006996 10.007854    10
10.006614 10.008436    10
 4.509277  4.545920    10

推荐阅读