NumericMatrix未被识别为RcppParallel Package

时间:2016-07-06 00:07:29

标签: c++ r parallel-processing rcpp r-package

我正在学习使用RcppParallel在我的工作中使用并尝试安装一个用Rcpp.package.skeleton()创建的简单包。该软件包包含三个源文件,Rcpp的HelloWorld(rcpp_hello_world.cpp)和RcppParallel网站(http://gallery.rcpp.org/articles/parallel-matrix-transform/)中的两个版本的矩阵转换函数。串行版本(matrixSqrt.cpp)和并行版本(parallelMatrixSqrt.cpp)。此外,我对DESCRIPTION和NAMESPACE文件进行了必要的添加,并使用建议的行创建了Makevars和Makevars.win。

问题是,当我尝试安装软件包时,出现以下错误:

  

parallelMatrixSqrt.cpp:14:21:错误:'NumericMatrix'没有命名类型       SquareRoot(const NumericMatrix输入,NumericMatrix输出)

我不知道它是否是链接器问题。 Makevars文件如下所示:

Makevars

PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")

Makevars.win

PKG_CXXFLAGS += -DRCPP_PARALLEL_USE_TBB=1
PKG_LIBS += $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" \
              -e "RcppParallel::RcppParallelLibs()")

编辑: 这就是parallelMatrixSqrt.cpp的样子

#include <RcppParallel.h>
using namespace RcppParallel;

struct SquareRoot : public Worker
{
   // source matrix
   const RMatrix<double> input;

   // destination matrix
   RMatrix<double> output;

   // initialize with source and destination
   SquareRoot(const NumericMatrix input, NumericMatrix output) 
      : input(input), output(output) {}

   // take the square root of the range of elements requested
   void operator()(std::size_t begin, std::size_t end) {
      std::transform(input.begin() + begin, 
                     input.begin() + end, 
                     output.begin() + begin, 
                     ::sqrt);
   }
};

// [[Rcpp::export]]
NumericMatrix parallelMatrixSqrt(NumericMatrix x) {

  // allocate the output matrix
  NumericMatrix output(x.nrow(), x.ncol());

  // SquareRoot functor (pass input and output matrixes)
  SquareRoot squareRoot(x, output);

  // call parallelFor to do the work
  parallelFor(0, x.length(), squareRoot);

  // return the output matrix
  return output;
}

由于

2 个答案:

答案 0 :(得分:4)

NumericMatrix类由Rcpp提供,因此您需要通过使用

拉入Rcpp命名空间来访问它
using namespace Rcpp;

或明确地为命名空间名称添加前缀,例如

Rcpp::NumericMatrix

请注意,警告:避免使用R / Rcpp API意味着避免在RcppParallel::Worker函数的定义中使用它们。您希望避免在并行上下文中使用R / Rcpp API的主要原因是这些例程可能:

  1. 分配,从而触发R垃圾收集器,如果在单独的线程上完成,将导致大问题;或
  2. 抛出一个错误,从而导致一个longjmp炸毁宇宙(如果我理解正确的话,这是C ++程序中未定义行为的允许结果)
  3. 您通常可以从Worker对象构造Rcpp对象,但为了安全起见,您通常希望将关联数据与本地RcppParallel::RMatrix<T>对象一起存储,因为该对象是&# 39;更安全&#39;因为它只提供在并行上下文中可以安全使用的例程 - 特别是,它提供了允许您将它与C ++ STL一起使用的迭代器,在许多情况下这应该足够了。

答案 1 :(得分:0)

#include <RcppParallel.h>
using namespace RcppParallel;

用下面的行而不是代码中的上面的行来修补代码。您尚未包括Rcpp命名空间,这对我有用。

// [[Rcpp::depends(RcppParallel)]]
#include <Rcpp.h>
#include <RcppParallel.h>
using namespace Rcpp;
using namespace RcppParallel;

您还没有拉出Rcpp名称空间,这是在编译NumericVector或NumericMatrix空间时需要的。

因此,工作代码将为

// [[Rcpp::depends(RcppParallel)]]
#include <Rcpp.h>
#include <RcppParallel.h>
#include <limits>
using namespace Rcpp;
using namespace RcppParallel;
struct SquareRoot : public Worker
{
// source matrix
 const RMatrix<double> input;

// destination matrix
RMatrix<double> output;

// initialize with source and destination
 SquareRoot(const NumericMatrix input, NumericMatrix output) 
 : input(input), output(output) {}

// take the square root of the range of elements requested
 void operator()(std::size_t begin, std::size_t end) {
 std::transform(input.begin() + begin, 
               input.begin() + end, 
               output.begin() + begin, 
               ::sqrt);
 }
 };

  // [[Rcpp::export]]
   NumericMatrix parallelMatrixSqrt(NumericMatrix x) {

  // allocate the output matrix
   NumericMatrix output(x.nrow(), x.ncol());

  // SquareRoot functor (pass input and output matrixes)
   SquareRoot squareRoot(x, output);

  // call parallelFor to do the work
    parallelFor(0, x.length(), squareRoot);

  // return the output matrix
  return output;
  }

但是,我收到“没有匹配的函数来调用转换”错误,如果您知道答案可能是,请回复。