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

Posted

技术标签:

【中文标题】将大型矩阵传递给 RcppArmadillo 函数而不创建副本(高级构造函数)【英文标题】:Passing large matrices to RcppArmadillo function without creating copy (advanced constructors) 【发布时间】:2013-09-18 07:22:05 【问题描述】:

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

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

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec test(arma::mat M) 
    return(M.row(0))

对于大型矩阵 M(例如 M=matrix(rnorm(30000*30000), nrow=30000, ncol=30000)),这非常慢。所以我想使用记录在 here 中的高级构造函数。语法是 mat(aux_mem*, n_rows, n_cols, copy_aux_mem = true, strict = true)copy_aux_mem 应该设置为 false到“按引用传递”。我只是不确定函数定义中的语法。如何在arma::vec test(arma::mat M) 中使用它?

【问题讨论】:

我几乎可以肯定这也是一个多余的问题。 【参考方案1】:

这已在 Rcpp 邮件列表中进行了广泛讨论。请参阅此thread。在RcppArmadillo 中已经实现的解决方案是通过引用传递arma::mat。在内部,这将为您调用高级构造函数。

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

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec test(const arma::mat& M) 
    // do whatever with M
    ...

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

使用这些功能:

#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)

【讨论】:

gmane.org 线程的链接已失效。 gmane.org 本身似乎已经不存在了,而是被 gmane.io 取代了。有没有办法在 gmane.io 上查看引用的(哈哈)线程?【参考方案2】:

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

void foo( NumericMatrix x_ )
    arma::mat M( x_.begin(), x_.nrow(), x_.ncol(), false ) ;
    // do whatever with M

这已在许多地方使用,包括 Rcpp 库中的几篇文章。

【讨论】:

在最突出的示例FastLm.cpp 中,包本身也使用和讨论了它。

以上是关于将大型矩阵传递给 RcppArmadillo 函数而不创建副本(高级构造函数)的主要内容,如果未能解决你的问题,请参考以下文章

使用 RcppArmadillo 在矩阵的列上应用函数有效,但在应用于行时返回错误

RcppArmadillo 的 sample() 在更新 R 后不明确

将动态数组/矩阵传递给函数进行初始化

如何将矩阵传递给打印它的函数?

使用 RcppArmadillo 时调用 one 或 eye 函数失败

将指针(矩阵)传递给c中的函数[重复]