1

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?

coatless
  • 20,011
  • 13
  • 69
  • 84
zdebruine
  • 3,687
  • 6
  • 31
  • 50
  • 1
    A `#pragma` is something different from `#define`, so you should probably be more careful about your language. As for 'why doesn't devtools...': you probably want to talk to somebody else. The Rcpp documentation never suggests or recommends devtools; I do not use and cannot help you. That said, all these tools tend to have _verbose_ modes showing you _exactly_ how the compilers are called. You may need to do some digging. – Dirk Eddelbuettel Jul 23 '21 at 21:20
  • @DirkEddelbuettel Thanks for pointing that out. Compiler calls are the same, I checked the verbose feed. Indeed, the result is the same with `R CMD build` and `devtools::document()` (Q updated). Here's hoping someone from Rstudio/devtools has run across this before. In the meantime I can be more explicit with my Eigen matrix initializations. – zdebruine Jul 23 '21 at 22:33

1 Answers1

1

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>.

F. Privé
  • 11,423
  • 2
  • 27
  • 78
  • 1
    Thanks!! Adding `-DEIGEN_INITIALIZE_MATRICES_BY_ZERO` to `src/Makevars` worked! I don't think I would have figured that one out. So appreciated. No, it's not a problem of ordering -- preprocessor directives can be defined (and should be by best practice) before loading the library headers. – zdebruine Jul 24 '21 at 11:13