Alpalentless
Alpalentless

Reputation: 39

NumericMatrix not recognized as a type in RcppParallel Package

I'm learning to use RcppParallel to use in my work and was trying to install a simple package made with Rcpp.package.skeleton(). The package contains three source files, the Rcpp's HelloWorld (rcpp_hello_world.cpp) and the two versions of the matrix transformation functions found in the RcppParallel website (http://gallery.rcpp.org/articles/parallel-matrix-transform/). The serial version (matrixSqrt.cpp) and a the parallel version (parallelMatrixSqrt.cpp). Also, I made the necessary additions to the DESCRIPTION and NAMESPACE files, and made the Makevars and Makevars.win with the suggested lines.

The problem is, when I try to install the package, i got the following error:

parallelMatrixSqrt.cpp:14:21: error: ‘NumericMatrix’ does not name a type SquareRoot(const NumericMatrix input, NumericMatrix output)

I don't know if it is a linker problem. The Makevars files looks like this:

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()")

EDIT: This is how the parallelMatrixSqrt.cpp looks like

#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;
}

Thanks

Upvotes: 1

Views: 1003

Answers (2)

Allan victor
Allan victor

Reputation: 11

#include <RcppParallel.h>
using namespace RcppParallel;

Patch your code with the below lines instead of the above lines in your code. You haven't included the Rcpp name space and this worked for me.

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

You haven't pulled the Rcpp namespace, that will be needed during the compilation of the space NumericVector or NumericMatrix.

So, the working code will be

// [[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;
  }

However, I get the error for "no matching function to call for transform", If you know the answer may be, kindly reply.

Upvotes: 0

Kevin Ushey
Kevin Ushey

Reputation: 21315

The NumericMatrix class is provided by Rcpp, so you need to access it either by pulling in the Rcpp namespace with

using namespace Rcpp;

or explicitly prefix the namespace name, e.g.

Rcpp::NumericMatrix

Note that the warning re: avoiding use of the R / Rcpp API implies avoiding their use within the definition of your RcppParallel::Worker functions. The over-arching reason you want to avoid using the R / Rcpp API within a parallel context is that these routines may:

  1. Allocate, and hence trigger the R garbage collector, which will cause big problems if done on a separate thread; or
  2. Throw an error, and hence cause a longjmp that blows up the universe (which, if I understand correctly, is a permissible consequence of undefined behavior in a C++ program)

You can typically construct your Worker object from Rcpp objects, but to be safe you generally want to store the associated data with a local RcppParallel::RMatrix<T> object, as that object is 'safer' in that it only provides routines that are safe to use in a parallel context -- in particular, it provides iterators that allow you to use it with the C++ STL, which should be sufficient in many scenarios.

Upvotes: 5

Related Questions