6

I got this Rcpp implementation to the rmvnorm function of the mvtnorm package, and I was wondering what I'd need to add in order for it to use openmp so it can take advantage of multiple cores.

I though this ought to do it:

library(Rcpp)
library(RcppArmadillo)
library(inline)
settings <- getPlugin("RcppArmadillo")
settings$env$PKG_CXXFLAGS <- paste('-fopenmp', settings$env$PKG_CXXFLAGS)
settings$env$PKG_LIBS <- paste('-fopenmp -lgomp', settings$env$PKG_LIBS)

code <- '
#include <omp.h>
using namespace Rcpp;
int cores = 1;
cores = as<int>(cores_);
omp_set_num_threads(cores);
int n = as<int>(n_);
arma::vec mu = as<arma::vec>(mu_);
arma::mat sigma = as<arma::mat>(sigma_);
int ncols = sigma.n_cols;
#pragma omp parallel for schedule(static)
arma::mat Y = arma::randn(n, ncols);
return wrap(arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma));
'

rmvnorm.rcpp <- cxxfunction(signature(n_="integer", mu_="numeric", sigma_="matrix", cores_="integer"), body=code, plugin="RcppArmadillo", settings=settings, verbose=TRUE)

But apparently I'm wrong as I'm getting this compilation error message:

Compilation argument:
 /software/free/Linux/redhat_5_x86_64/pkgs/r_3.0.2/lib64/R/bin/R CMD SHLIB file50825babe43a.cpp 2> file50825babe43a.cpp.err.txt
/software/free/Linux/redhat_5_x86_64/pkgs/gcc_4.5.3/bin/g++ -I/software/free/Linux/redhat_5_x86_64/pkgs/r_3.0.2/lib64/R/include -DNDEBUG  -I/usr/local/include -I"/software/free/Linux/redhat_5_x86_64/pkgs/r_3.0.2/lib64/R/library/RcppArmadillo/include" -I"/software/free/Linux/redhat_5_x86_64/pkgs/r_3.0.2/lib64/R/library/Rcpp/include"  -fopenmp  -fpic  -g -O2  -c file50825babe43a.cpp -o file50825babe43a.o
In file included from file50825babe43a.cpp:31:0:
/software/free/Linux/redhat_5_x86_64/pkgs/gcc_4.5.3/lib/gcc/x86_64-unknown-linux-gnu/4.5.3/include/omp.h: In function 'SEXPREC* file50825babe43a(SEXPREC*, SEXPREC*, SEXPREC*, SEXPREC*)':
/software/free/Linux/redhat_5_x86_64/pkgs/gcc_4.5.3/lib/gcc/x86_64-unknown-linux-gnu/4.5.3/include/omp.h:56:8: error: expected unqualified-id before string constant
file50825babe43a.cpp:35:26: error: 'omp_set_num_threads' was not declared in this scope
file50825babe43a.cpp:41:1: error: for statement expected before 'arma'
make: *** [file50825babe43a.o] Error 1

ERROR(s) during compilation: source code errors or compiler configuration errors!

. . .

Error in compileCode(f, code, language = language, verbose = verbose) :
  Compilation ERROR, function(s)/method(s) not created! In file included from file50825babe43a.cpp:31:0:
/software/free/Linux/redhat_5_x86_64/pkgs/gcc_4.5.3/lib/gcc/x86_64-unknown-linux-gnu/4.5.3/include/omp.h: In function 'SEXPREC* file50825babe43a(SEXPREC*, SEXPREC*, SEXPREC*, SEXPREC*)':
/software/free/Linux/redhat_5_x86_64/pkgs/gcc_4.5.3/lib/gcc/x86_64-unknown-linux-gnu/4.5.3/include/omp.h:56:8: error: expected unqualified-id before string constant
file50825babe43a.cpp:35:26: error: 'omp_set_num_threads' was not declared in this scope
file50825babe43a.cpp:41:1: error: for statement expected before 'arma'
make: *** [file50825babe43a.o] Error 1

I may be missing something trivial but I don't know what it is.

Community
  • 1
  • 1
user1701545
  • 5,706
  • 14
  • 49
  • 80

1 Answers1

12

This has been covered before:

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • I'm still not sure I understand what I am doing wrong. When the #include command in my rcpp function is is commented out (as well as the omp_set_num_threads command and the #pragma omp parallel for schedule(static) line) the code compiles successfully. Is this perhaps a gcc issue? – user1701545 Mar 30 '14 at 21:05
  • 5
    You are fighting with the (older) [inline](http://cran.rstudio.com/package=inline) when you could follow the examples I showed you and use the newer `sourceCpp()` or `cppFunction()`. It is "just" a matter of gettting the options down to the compiler / linker, but the devil is in the detail. – Dirk Eddelbuettel Mar 30 '14 at 21:18
  • 1
    You're right. It was an old habit I needed to get rid of. Thanks! – user1701545 Mar 31 '14 at 22:46