c++reigenrcpprcppeigen

RcppEigen #define works when using sourceCpp() but ignored with R CMD build


I've noticed that sourceCpp() respects C++ #define while devtools::document() and R CMD build seems to disregard them, at least in the case of Eigen matrix initialization.

Consider this .cpp file:

#define EIGEN_INITIALIZE_MATRICES_BY_ZERO

//[[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>

//[[Rcpp::export]]
Eigen::MatrixXd initialize_matrix(int nrow, int ncol) {
  return Eigen::MatrixXd(nrow, ncol);
}

One may source this file using sourceCpp, and then run the following in R:

> initialize_matrix(5, 3)
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0
[3,]    0    0    0
[4,]    0    0    0
[5,]    0    0    0

Great, the matrix is initialized with zeros!

Now put the same .cpp file in an RcppEigen package and compile using devtools::document() or R CMD build.

> initialize_matrix(5, 3)
              [,1]          [,2]          [,3]
[1,] 1.845608e-317 9.881313e-324 9.881313e-324
[2,] 1.107517e-311  0.000000e+00  0.000000e+00
[3,] 9.881313e-324  0.000000e+00  0.000000e+00
[4,]  0.000000e+00 2.121963e-314 9.881313e-324
[5,]  0.000000e+00 1.107517e-311  0.000000e+00

The matrix is not initialized with zeros, rather what looks like a memset.

Why does sourceCpp() respect the pragma declaration while devtools::document() ignores it during compilation?


Solution

  • I think, to be used in a package, you need to add -DEIGEN_INITIALIZE_MATRICES_BY_ZERO to src/Makevars, e.g. as in https://github.com/privefl/bigstatsr/blob/master/src/Makevars#L2 (there are 2 flags for armadillo there).

    Or maybe just a problem of ordering? Try putting the #define after #include <RcppEigen.h>.