微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 RcppArmadillo 和 SuperLU 构建 R 包?

如何解决如何使用 RcppArmadillo 和 SuperLU 构建 R 包?

我在 R 中有一个项目,它使用 C++ 函数来加速计算。在我的 src 文件夹中,我有一个 C++ 文件,它调用我在同一文件夹中的不同头文件和 C++ 文件中定义的函数。为了提供一个最小的工作示例,我创建了一个包含一些非常小的文件的新项目,我将在下面描述这些文件内容

src/test_func.cpp:

#include "RcppArmadillo.h"
#include "extra1.h"


// [[Rcpp::export]]
arma::vec OLS(const arma::mat & X,const arma::vec & y)
{
    arma::vec beta = compute_b(X,y);

    return beta;
}


// [[Rcpp::export]]
arma::vec sparse_solver()
{
    arma::sp_mat X = arma::sprandu<arma::sp_mat>(1000,1000,0.1);
    arma::vec y(1000,arma::fill::randu);

    arma::vec beta = compute_sp_b(X,y);

    return beta;
}

src/extra1.h:

#include "RcppArmadillo.h"

arma::vec compute_b(const arma::mat & X,const arma::vec & y);
arma::vec compute_sp_b(const arma::sp_mat & X,const arma::vec & y);

src/extra1.cpp:

#define ARMA_USE_SUPERLU 1

#include "RcppArmadillo.h"
#include "extra1.h"


arma::vec compute_b(const arma::mat & X,const arma::vec & y)
{
    arma::vec b = arma::solve(X.t() * X,X.t() * y);

    return b;
}


arma::vec compute_sp_b(const arma::sp_mat & X,const arma::vec & y)
{
    arma::vec b = arma::spsolve(X,y,"superlu");

    return b;
}

使用此代码通过

Sys.setenv("PKG_LIBS" = "-lsuperlu")
Rcpp::sourceCpp("src/test_func.cpp")

X = matrix(rnorm(20),nrow = 10)
b = matrix(rnorm(2))
y = X %*% b + matrix(rnorm(10,0.1))

OLS(X,y)
sparse_solver()

完全按预期工作,我可以在 R 中使用我的函数而不会出现任何问题。但是,我的项目已经发展壮大,并且拥有的不仅仅是单个头文件和相应的 cpp 文件,如果我对单个文件进行了小的更改,则使用它来重新编译所有内容开始花费相当多的时间。此外,我在网上的一些帖子中读到 Rcpp::sourceCpp() 不适用于编译多个源文件,建议创建一个包。

为了实现这一点,我按照在线说明操作并使用 RcppArmadillo::RcppArmadillo.package.skeleton("Test2",example_code = FALSE) 创建了文件结构,将我的源代码复制到 src 文件夹并运行 Rcpp::compileAttributes("Test2")。然后我在 RstudioBuild 选项卡中按下选项 Install and Restart 并得到以下错误

Error: package or namespace load Failed for ‘Test2’ in dyn.load(file,DLLpath = DLLpath,...):
    ... some_path/Test2.so: undefined symbol: set_default_options
Error: loading Failed
Execution halted
ERROR: loading Failed

这可能与我的代码使用 SuperLU 有关。如果我注释掉 #define ARMA_USE_SUPERLU 1 并将 "superlu" 替换为 "lapack" 中的 arma::spsolve() 包构建没有问题(但这并不是一个真正可行的解决方案,因为它变成了稀疏矩阵成一个密集的)。我没有构建 R 包的经验,也找不到在线示例包,该包使用 SuperLU 求解稀疏方程组以找出如何构建此包。目前我不太关心可移植性,这个包仍然纯粹供个人使用,但最近出现了一些将它变成可安装包的其他原因(我也希望能够从 Python 调用这些函数使用 rpy2 库,对于它来说,它似乎必须是一个已安装的包)。

简而言之,我的问题是,如果有人知道如何使用 SuperLU 构建包或知道使用 SuperLU 的 R 包,那么我可以看看他们是如何编译的。

编辑:我的操作系统是 Ubuntu 20.04

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。