将大型矩阵传递给RcppArmadillo函数而不创建副本(高级构造函数)

use*_*795 8 r rcpp

我想将一个大矩阵传递给一个RcppArmadillo函数(大约30,000*30,000)并且感觉这个过去只会消耗所有的性能提升.这里还提出了一个问题,建议使用带有copy_aux_mem = false参数的高级构造函数.这似乎也是一个很好的解决方案,因为我只需要从矩阵中读取行而不需要改变任何东西.我在正确实施解决方案时遇到问题.这可能只是一个简单的语法问题.

这是我当前设置的函数调用(当然简化):

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec test(arma::mat M) {
    return(M.row(0))
}
Run Code Online (Sandbox Code Playgroud)

这是非常慢的大矩阵M(例如M=matrix(rnorm(30000*30000), nrow=30000, ncol=30000),所以我想使用这里记录的高级构造函数.语法是mat(aux_mem*, n_rows, n_cols, copy_aux_mem = true, strict = true)并且copy_aux_mem应该设置false为'传递引用'.我只是不确定语法功能定义.我该如何使用它arma::vec test(arma::mat M) {

Rom*_*ois 14

这已经在Rcpp邮件列表中进行了广泛讨论.看到这个帖子.已实现的解决方案RcppArmadilloarma::mat通过引用传递.在内部,这将为您调用高级构造函数.

所以对于这个版本,你会做这样的事情:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec test(const arma::mat& M) {
    // do whatever with M
    ...
}
Run Code Online (Sandbox Code Playgroud)

来自R矩阵的数据不是复制而是借用.线程中的更多细节.

以下是一些基准测试,比较复制或通过引用传递所需的时间:

                 expr      min        lq    median        uq      max neval
    arma_test_value(m) 3540.369 3554.4105 3572.3305 3592.5795 4168.671   100
      arma_test_ref(m)    4.046    4.3205    4.7770   15.5855   16.671   100
arma_test_const_ref(m)    3.994    4.3660    5.5125   15.7355   34.874   100
Run Code Online (Sandbox Code Playgroud)

有了这些功能:

#include <RcppArmadillo.h>
using namespace Rcpp ;

// [[Rcpp::depends("RcppArmadillo")]]

// [[Rcpp::export]]
void arma_test_value( arma::mat x){}

// [[Rcpp::export]]
void arma_test_ref( arma::mat& x){}

// [[Rcpp::export]]
void arma_test_const_ref( const arma::mat& x){}
Run Code Online (Sandbox Code Playgroud)


Rom*_*ois 5

使用CRAN版本RcppArmadillo,您将使用这种语法:

void foo( NumericMatrix x_ ){
    arma::mat M( x_.begin(), x_.nrow(), x_.ncol(), false ) ;
    // do whatever with M
}
Run Code Online (Sandbox Code Playgroud)

这已被用于许多地方,包括Rcpp画廊中的几篇文章.