【问题标题】:Using Rcpp functions within R6 class在 R6 类中使用 Rcpp 函数
【发布时间】:2021-09-12 13:20:08
【问题描述】:

我正在尝试使用执行某些线性回归的 R 4.1.0 构建一个 R 包 (RegressionTool)。为了加快矩阵乘法,我想在 .cpp 脚本中外包矩阵乘法运算,我想将其包含在我的最终 R 包中。 我想用于矩阵乘法的脚本 Cmatmult.cpp 如下所示:

#include <RcppArmadillo.h>
#include <RcppEigen.h>

// Correctly setup the build environment 
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
using namespace Rcpp;
using namespace arma;
using namespace Eigen;

// [[Rcpp::export]]
SEXP armaMatMult(arma::mat A, arma::mat B){
    arma::mat C = A * B;

    return Rcpp::wrap(C);
}

// [[Rcpp::export]]
SEXP eigenMatMult(Eigen::MatrixXd A, Eigen::MatrixXd B){
    Eigen::MatrixXd C = A * B;

    return Rcpp::wrap(C);
}

// [[Rcpp::export]]
SEXP eigenMapMatMult(const Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> B){
    Eigen::MatrixXd C = A * B;

    return Rcpp::wrap(C);
}

RegressionTool 文件夹中,除了包含 R6 类的文件夹 R 之外,还有文件 DESCRIPTIONNAMESPACE ,我保存了包含文件 Cmatmult.cpp 的文件夹 src。为了尝试编译包,我在 R 控制台中运行以下命令:

RcppArmadillo::RcppArmadillo.package.skeleton("RegressionTool")
Rcpp::compileAttributes()
roxygen2::roxygenize(roclets="rd")

我注意到生成子文件夹RegressionToolRcppArmadillo.package.skeleton() 命令不会生成任何Makevars/Makevars.win 文件。虽然前两个命令运行没有错误,但最后一个命令停止并出现以下错误:

C:/Program Files/R/R-4.1.0/library/RcppArmadillo/include/armadillo_bits/translate_blas.hpp:88: undefined reference to `dsyrk_'
collect2.exe: error: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'RegressionTool'

我已经将 Rcpp 和 RcppArmadillo 的 LinkingTo:Depends: 包含在存储在文件夹 RegressionTool 中的说明文件中,但我仍然不明白为什么要使用 Makevars/Makevars。 win 文件没有生成(这是否是roxygenize 出错的原因)。

【问题讨论】:

    标签: c++ r rcpp r6 rcpparmadillo


    【解决方案1】:

    您声称 RcppArmadillo 的包骨架生成器不会创建 src/Makevars{,.win}。我无法重现:

    edd@rob:~$ cd /tmp/
    edd@rob:/tmp$ rm -rf RegressionTool  # just in case
    edd@rob:/tmp$ Rscript -e 'RcppArmadillo::RcppArmadillo.package.skeleton("RegressionTool")'
    
    Calling kitten to create basic package.
    Creating directories ...
    Creating DESCRIPTION ...
    Creating NAMESPACE ...
    Creating Read-and-delete-me ...
    Saving functions and data ...
    Making help files ...
    Done.
    Further steps are described in './RegressionTool/Read-and-delete-me'.
    
    Adding pkgKitten overrides.
     >> added .gitignore file
     >> added .Rbuildignore file
     >> added tinytest support
    First time using roxygen2. Upgrading automatically...
    Updating roxygen version in /tmp/RegressionTool/DESCRIPTION
    ℹ Loading RegressionTool
    Warning: The existing 'NAMESPACE' file was not generated by roxygen2, and will not be overwritten.
    Writing hello2.Rd
    Deleted 'Read-and-delete-me'.
    Done.
    
    Consider reading the documentation for all the packaging details.
    A good start is the 'Writing R Extensions' manual.
    
    And run 'R CMD check'. Run it frequently. And think of those kittens.
    
    
    Adding RcppArmadillo settings
     >> added Imports: Rcpp
     >> added LinkingTo: Rcpp, RcppArmadillo
     >> added useDynLib and importFrom directives to NAMESPACE
     >> added Makevars file with Rcpp settings
     >> added Makevars.win file with RcppArmadillo settings
     >> added example src file using armadillo classes
     >> added example Rd file for using armadillo classes
     >> invoked Rcpp::compileAttributes to create wrappers
    edd@rob:/tmp$
    

    这没有错误并且确实创建了文件:

    edd@rob:/tmp$ ls -l RegressionTool/src/
    total 16
    -rw-rw-r-- 1 edd edd  597 Jun 30 07:07 Makevars
    -rw-rw-r-- 1 edd edd  597 Jun 30 07:07 Makevars.win
    -rw-rw-r-- 1 edd edd 1453 Jun 30 07:07 rcpparma_hello_world.cpp
    -rw-rw-r-- 1 edd edd 2490 Jun 30 07:07 RcppExports.cpp
    edd@rob:/tmp$ 
    

    还有一个用于包创建的单元测试,该包在 CRAN 多年来一直保持良好的信誉。所有这些都让我怀疑你的结局有些不同。

    PS 我也刚刚签入了一个没有包 pkgKitten 的 Docker 容器,以防万一,它以同样的方式通过。

    【讨论】:

    • 请原谅,文件Makevars{, .win} 存储在新创建的子文件夹RegressionTool\RegressionTool\src 中。如果我在“原始”src 文件夹中手动移动这些文件,我实际上可以生成包,即 RegressionTool\src。
    • 看起来只是对基本 R 的 package.skeleton() 作品感到困惑。调用它,然后进入创建的目录。你这里有两层RegressionTool,和Rcpp无关。
    • 再次感谢。一旦我移动到创建的目录,我就可以正确生成文档并编译包,但它只包含 .cpp 脚本中包含的函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    相关资源
    最近更新 更多