Reputation: 39
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
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
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:
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