Rcpp with openmp - r

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.

This has been covered before:
There are two posts at the Rcpp Gallery about OpenMP and Rcpp
There is also an (older, may need an update) example directory OpenMP in the sources which also gets copied into your installation
And Rcpp Attributes defines a plugin for OpenMP

Related

Error when running Rcpp in linux batch mode

I am trying to run a very simple model with rstan in batch mode and have some errors. I do not have any errors when I try to run the same code not in batch mode.
The community from STAN Forums helped me to understand that the issue is that Rcpp instead of STAN is not working properly on the server of my university. We reached this understanding from a test trying to run a very simple Rcpp code in batch mode and not in batch mode. The Rcpp code is:
### Libraries
library(Rcpp)
Rcpp::sourceCpp(code='
#include <Rcpp.h>
// [[Rcpp::export]]
int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}',
verbose = TRUE,
rebuild = TRUE
)
The results are below.
Not in batch mode:
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_178b21d435d91/sourceCpp_4.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_178b21d435d91
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB --preclean -o 'sourceCpp_4.so' 'file178b25628f5ea.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -c file178b25628f5ea.cpp -o file178b25628f5ea.o
g++ -std=gnu++14 -shared -L/hpc/apps/R/4.1.2/lib64/R/lib -L/hpc/apps/zlib/1.2.8/lib -L/hpc/apps/pcre/8.38/lib -L/hpc/apps/bzip2/1.0.6/lib -L/hpc/apps/curl/7.54.1/lib -L/hpc/apps/cairo/1.14.12/lib -o sourceCpp_4.so file178b25628f5ea.o -L/hpc/apps/R/4.1.2/lib64/R/lib -lR
In batch mode:
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/localscratch/250948.1.ragatkolab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_142bd68d660f1/sourceCpp_2.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /localscratch/250948.1.mylab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_142bd68d660f1
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'file142bd64ebe902.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/localscratch/250948.1.ragatkolab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -c file142bd64ebe902.cpp -o file142bd64ebe902.o
In file included from /hpc/apps/gcc/9.1.0/include/c++/9.1.0/x86_64-pc-linux-gnu/bits/c++config.h:524,
from /hpc/apps/gcc/9.1.0/include/c++/9.1.0/cmath:41,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file142bd64ebe902.cpp:2:
/hpc/apps/gcc/9.1.0/include/c++/9.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:39:10: fatal error: features.h: No such file or directory
39 | #include <features.h>
| ^~~~~~~~~~~~
compilation terminated.
make: *** [file142bd64ebe902.o] Error 1
Error in Rcpp::sourceCpp(code = "\n #include <Rcpp.h>\n\n // [[Rcpp::export]]\n int fibonacci(const int x) {\n if (x == 0) return(0);\n if (x == 1) return(1);\n return (fibonacci(x - 1)) + fibonacci(x - 2);\n }", :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please install GNU development tools including a C++ compiler.
Execution halted
Then, they asked me to modify my makevars file - which I did using the R-package usethis::edit_r_makevars() - adding the lines:
CXXFLAGS += -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/"
CXX14FLAGS += -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/"
Once I did this modification (I hope I did it correctly), my error message change to:
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
#ifdef RCPP_USE_GLOBAL_ROSTREAM
Rcpp::Rostream<true>& Rcpp::Rcout = Rcpp::Rcpp_cout_get();
Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
#endif
// fibonacci
int fibonacci(const int x);
RcppExport SEXP sourceCpp_1_fibonacci(SEXP xSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< const int >::type x(xSEXP);
rcpp_result_gen = Rcpp::wrap(fibonacci(x));
return rcpp_result_gen;
END_RCPP
}
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_1e50364a03315/sourceCpp_2.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_1e50364a03315
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'file1e50325e7686.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/" -c file1e50325e7686.cpp -o file1e50325e7686.o
In file included from /hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/c++config.h:571,
from /hpc/apps/gcc/11.1.0/include/c++/11.1.0/cmath:41,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file1e50325e7686.cpp:2:
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:44:19: error: missing binary operator before token "("
44 | #if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE)
| ^
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:52:19: error: missing binary operator before token "("
52 | #if __GLIBC_PREREQ(2, 27)
| ^
In file included from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file1e50325e7686.cpp:2:
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/cmath:45:15: fatal error: math.h: No such file or directory
45 | #include_next <math.h>
| ^~~~~~~~
compilation terminated.
make: *** [file1e50325e7686.o] Error 1
Error in Rcpp::sourceCpp(code = "\n #include <Rcpp.h>\n\n // [[Rcpp::export]]\n int fibonacci(const int x) {\n if (x == 0) return(0);\n if (x == 1) return(1);\n return (fibonacci(x - 1)) + fibonacci(x - 2);\n }", :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please install GNU development tools including a C++ compiler.
Execution halted
My knowledge in Linux is limited and I am afraid that my question is out of scope for STAN Forums. Any thoughts how to proceed?
I fear your problem is still local. On the computing you use, someone may have set up R in way that makes it differ between interactive R use, and what you call batch use.
But that is non-standard, and at your end. In general, it just works. Using a minimally modified version of your program (which I still find confusing: it loads doParallel, registers cores but ... triggers to parallel code -- anyway) it works just fine:
Using Rscript
edd#rob:~/git/stackoverflow/70470842(master)$ Rscript answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Using R in batch mode
edd#rob:~/git/stackoverflow/70470842(master)$ R -s -f answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Using our littler frontend
edd#rob:~/git/stackoverflow/70470842(master)$ r answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: utils
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Modified source code
library(doParallel) # Library
ncores <- 5 # Simulation parameters
n_sim <- 5
registerDoParallel(ncores)
Rcpp::sourceCpp(code='
#include <Rcpp.h>
// [[Rcpp::export]]
int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}'
)
cat("Fib(10) is ", fibonacci(10), "\n")
For future reference, I interacted with IT team from my institution after feedback received here and STAN Forums, and they finally found a solution. In their words:
"Compute nodes aren't normally used for development. So certain development packages are not installed by default. We installed "glibc-devel" and "glibc-headers" on the compute nodes.
So, it seems that when run interactively the job was running on the submit node (which had these libraries installed) and when run from the scheduler it was run on the compute nodes (which did not have the library installed). The reason for the discrepancy being that the libraries in question have traditionally been only used during development and compilation. This use posed a unique use case."

Rcpp installed but compilation error from complex code snippet

I have Rcpp and RccpEigen already installed in RStudio. I am able to run an Rcpp code (that didn't use RccpEigen) successfully as well. However the following code which uses both doesn't seem to work.
Here is the code -
library(Rcpp)
library(RcppEigen)
sourceCpp(code = '
#include <Rcpp.h>
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using namespace Rcpp;
using namespace Eigen;
using namespace RcppEigen;
// [[Rcpp::export]]
List luEigen(MatrixXd M) {
FullPivLU<MatrixXd> luE(M);
return List::create(Named("L_matrix") = luE.matrixLU().triangularView<Upper>());
}')
A <- 0.8 + 0.2 * diag(100)
(luEigen(A))
This code gives a really long error, so here are the key error lines -
/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include/Rcpp/generated/Vector__create.h:71:10: note: in instantiation of function template specialization 'Rcpp::Vector<19, PreserveStorage>::create__dispatch<Rcpp::traits::named_object<Eigen::TriangularView<const Eigen::Matrix<double, -1, -1, 0>, 2>>>' requested here
return create__dispatch( typename traits::integral_constant<bool,
^
file16bbd8305f5c.cpp:11:18: note: in instantiation of function template specialization 'Rcpp::Vector<19, PreserveStorage>::create<Rcpp::traits::named_object<Eigen::TriangularView<const Eigen::Matrix<double, -1, -1, 0>, 2>>>' requested here
return List::create(Named("L_matrix") = luE.matrixLU().triangularView<Upper>());
^
18 warnings and 1 error generated.
make: *** [file16bbd8305f5c.o] Error 1
clang++ -mmacosx-version-min=10.13 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I"/Library/Frameworks/R.framework/Versions/4.1/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/4.1/Resources/library/RcppEigen/include" -I"/private/var/folders/_3/wdql3v5d4vggzffw3xdcr3p80000gn/T/RtmpQioi38/sourceCpp-x86_64-apple-darwin17.0-1.0.7" -I/usr/local/include -fPIC -Wall -g -O2 -c file16bbd8305f5c.cpp -o file16bbd8305f5c.o
Given that Rcpp and RccpEigen are installed and a different Rccp code does work, what may be causing error in this code?
With a very helpful suggestion from #Dirk, I simplified the decomposition and that did the trick. Still not sure why the more complex construction threw an error, but bottom line is that simplification gets the job done. Here is my modified code that works -
library(Rcpp)
library(RcppEigen)
sourceCpp(code = '
#include <Rcpp.h>
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using namespace Rcpp;
using namespace Eigen;
using namespace RcppEigen;
// [[Rcpp::export]]
List luEigen(MatrixXd M) { // here I name our function
FullPivLU<MatrixXd> luE(M); // here I perform the decomposition
MatrixXd upper = luE.matrixLU().triangularView<Upper>(); // this creates the upper matrix
MatrixXd lower = luE.matrixLU().triangularView<StrictlyLower>(); // this creates the lower matrix
return List::create(Named("U_matrix") = upper, Named("L_matrix") = lower); // this makes the list of the 2 matrices
}')
A <- 0.8 + 0.2 * diag(100)
(luEigen(A))
You could possibly speed it up further by doing the decomposition only once and calling the upper and lower triangular matrices from it, like so -
FullPivLU<MatrixXd> luE(M); // here I perform the decomposition
MatrixXd decomp = luE.matrixLU();
MatrixXd upper = decomp.triangularView<Upper>(); // this creates the upper matrix
MatrixXd lower = decomp.triangularView<StrictlyLower>(); // this creates the lower matrix

using R's c code in my standalone executables: "Undefined symbols"

Suppose I have the following c source code, in dexp_test.c:
#include <stdio.h>
double dexp(double x, double scale, int log);
int main() {
double x;
x = dexp(1 , 2, 0);
printf("Value: %f\n", x);
return 0;
}
where dexp is defined in R's source code (https://github.com/wch/r-source/blob/trunk/src/nmath/dexp.c). I would like to compile this to a standalone executable. I have R 4.0 installed on my system. I have the following gcc lines:
gcc r-source/src/nmath/dexp.c -I/Library/Frameworks/R.framework/Versions/4.0/Resources/include -c -o a.o
gcc dexp_test.c -c -o b.o
These lines run just fine on my system and I am left with new files a.o and b.o without errors.
When I run this line to get an executable:
gcc -o test_exp a.o b.o
...I get these errors:
Undefined symbols for architecture x86_64:
"_R_NaN", referenced from:
_Rf_dexp in a.o
"_R_NegInf", referenced from:
_Rf_dexp in a.o
"_dexp", referenced from:
_main in b.o
(maybe you meant: _Rf_dexp)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'm definitely missing something conceptually here; how do I get this to compile? If it helps, I'm on OSX 15.6, and the output of gcc -v is
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.2)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
You should mention the operating system you are using.
You need to include the appropriate headers. And tell the linker where and which libraries you want to use.
So your source should be
#include <stdio.h>
#include <R.h>
#include <Rmath.h>
int main() {
double x;
x = dexp(1 , 2, 0);
printf("Value: %f\n", x);
return 0;
}
And on the command line you should use the following
gcc -I/Library/Frameworks/R.framework/Versions/4.0/Resources/include -L/Library/Frameworks/R.framework/Versions/4.0/Resources/lib -lR -o test_exp trydexp.c

How to use a user-defined data C structure into an R package

This minimal example compiles when I "source" the file:
/*
read_header.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <RcppCommon.h>
typedef struct {
int my_data;
} MY_HEADER_INFO;
namespace Rcpp {
template <> SEXP wrap(const MY_HEADER_INFO& x);
}
#include <Rcpp.h>
namespace Rcpp {
template <>
SEXP wrap(const MY_HEADER_INFO& x) {
std::vector<std::string> names;
std::vector<SEXP> elements(1);
// do something with the elements and names
names.push_back("my_data");
elements[0] = Rcpp::wrap( x.my_data );
};
}
//' #export
// [[Rcpp::export]]
MY_HEADER_INFO read_header() {
MY_HEADER_INFO *header;
header = (MY_HEADER_INFO*)malloc(sizeof(MY_HEADER_INFO));
memset(header, 0, sizeof(MY_HEADER_INFO));
return *header;
}
When I try to build it in RStudio into a package (CMD + SHIFT + B), I get the following, long, error message, that clearly lists the problem is my user-defined return structure, MY_HEADER_INFO:
DESCRIPTION
Package: myPackage
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Depends: R (>= 4.0.0)
License: GPL-3
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.0
Imports:
Rcpp
Suggests:
knitr,
rmarkdown,
testthat
VignetteBuilder: knitr
LinkingTo:
Rcpp
NAMESPACE
# Generated by roxygen2: do not edit by hand
export(read_header)
I receive the following error:
==> Rcpp::compileAttributes()
* Updated src/RcppExports.cpp
* Updated R/RcppExports.R
==> devtools::document(roclets = c('rd', 'collate', 'namespace'))
Updating myPackage documentation
Loading myPackage
Re-compiling myPackage
─ installing *source* package ‘myPackage’ ...
** using staged installation
** libs
clang++ -mmacosx-version-min=10.13 -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I'/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include' -I/usr/local/include -fPIC -Wall -g -O2 -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:9:1: error: unknown type name 'MY_HEADER_INFO'
MY_HEADER_INFO read_header();
^
1 error generated.
make: *** [RcppExports.o] Error 1
ERROR: compilation failed for package ‘myPackage’
─ removing ‘/private/var/folders/gl/jvj9b0xn34lgq6_h9370p8q80000gn/T/RtmpLKsw0o/devtools_install_1f333d54be59/myPackage’
Error: System command 'R' failed, exit status: 1, stdout + stderr:
E> * installing *source* package ‘myPackage’ ...
E> ** using staged installation
E> ** libs
E> clang++ -mmacosx-version-min=10.13 -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I'/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include' -I/usr/local/include -fPIC -Wall -g -O2 -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c RcppExports.cpp -o RcppExports.o
E> RcppExports.cpp:9:1: error: unknown type name 'MY_HEADER_INFO'
E> MY_HEADER_INFO read_header();
E> ^
E> 1 error generated.
E> make: *** [RcppExports.o] Error 1
E> ERROR: compilation failed for package ‘myPackage’
E> * removing ‘/private/var/folders/gl/jvj9b0xn34lgq6_h9370p8q80000gn/T/RtmpLKsw0o/devtools_install_1f333d54be59/myPackage’
Stack trace:
1. base:::suppressPackageStartupMessages({ ...
2. base:::withCallingHandlers(expr, packageStartupMessage = function(c) tryInv ...
3. devtools::document(roclets = c("rd", "collate", "namespace"))
4. withr::with_envvar(r_env_vars(), roxygen2::roxygenise(pkg$path, ...
5. base:::force(code)
6. roxygen2::roxygenise(pkg$path, roclets, load_code = load_code)
7. roxygen2:::load_code(base_path)
8. pkgload::load_all(path, helpers = FALSE, attach_testthat = FALSE)
9. pkgbuild::compile_dll(path, quiet = quiet)
10. withr::with_makevars(compiler_flags(TRUE), assignment = "+=", ...
11. withr:::with_envvar(c(R_MAKEVARS_USER = makevars_file), { ...
12. base:::force(code)
13. base:::force(code)
14. pkgbuild:::install_min(path, dest = install_dir, components = "libs", ...
15. pkgbuild:::rcmd_build_tools("INSTALL", c(path, paste("--library=", ...
16. pkgbuild:::with_build_tools(callr::rcmd_safe(..., env = env, ...
17. callr::rcmd_safe(..., env = env, spinner = FALSE, show = FALSE, ...
18. callr:::run_r(options)
19. base:::with(options, with_envvar(env, do.call(processx::run, ...
20. base:::with.default(options, with_envvar(env, do.call(processx::run, ...
21. base:::eval(substitute(expr), data, enclos = parent.frame())
22. base:::eval(substitute(expr), data, enclos = parent.frame())
23. callr:::with_envvar(env, do.call(processx::run, c(list(bin, args = real_cmd ...
24. base:::force(code)
25. base:::do.call(processx::run, c(list(bin, args = real_cmdargs, ...
26. (function (command = NULL, args = character(), error_on_status = TRUE, ...
27. throw(new_process_error(res, call = sys.call(), echo = echo, ...
x System command 'R' failed, exit status: 1, stdout + stderr:
E> * installing *source* package ‘myPackage’ ...
E> ** using staged installation
E> ** libs
E> clang++ -mmacosx-version-min=10.13 -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I'/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include' -I/usr/local/include -fPIC -Wall -g -O2 -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c RcppExports.cpp -o RcppExports.o
E> RcppExports.cpp:9:1: error: unknown type name 'MY_HEADER_INFO'
E> MY_HEADER_INFO read_header();
E> ^
E> 1 error generated.
E> make: *** [RcppExports.o] Error 1
E> ERROR: compilation failed for package ‘myPackage’
E> * removing ‘/private/var/folders/gl/jvj9b0xn34lgq6_h9370p8q80000gn/T/RtmpLKsw0o/devtools_install_1f333d54be59/myPackage’
Execution halted
Exited with status 1.
The following is written to Rcpp_exports:
// Generated by using Rcpp::compileAttributes() -> do not edit by hand
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
#include <Rcpp.h>
using namespace Rcpp;
// read_header
MY_HEADER_INFO read_header();
RcppExport SEXP _myPackage_read_header() {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
rcpp_result_gen = Rcpp::wrap(read_header());
return rcpp_result_gen;
END_RCPP
}
static const R_CallMethodDef CallEntries[] = {
{"_myPackage_read_header", (DL_FUNC) &_myPackage_read_header, 0},
{NULL, NULL, 0}
};
RcppExport void R_init_myPackage(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
If I try to modify this file, however, it all gets written over when I call CMD+SHIFT+B.
Other C programs I've written for this same package that return standard data types (e.g., "std::vector") compile without a problem, both when I "source" the code in the Console and when I build them into a package.
I have read through the Rcpp documentation and related vignettes (and even bought Dirk's book!), but I cannot find how to tell the package builder where the definition of MY_HEADER_INFO is located. How do I tell the package compiler where the definition of this file is located?
Thanks!
That look like another instance of a not-entirely-uncommon problem for which we do have a wonderfully simple answer that is somewho less known than it should be.
In short, for a package <pkg> (where <pkg> is an alias for your package name, with lower or undercase as you please. and obviously no < or >) please such struct (or in the C++ case class) or typedef or ... definitions into a file inst/include/<pkg>_types.h (replacing <pkg> with your package name).
If such a file exists, it is automagically included by RcppExports.cpp and you are good to go.
Details are in the Rcpp Attributes vignette, and a few related forms are allowed as well:
src/<pkg>_types.h
src/<pkg>_types.hpp
inst/include/<pkg>_types.h
inst/include/<pkg>_types.hpp
inst/include/<pkg>.h
but inst/include/<pkg>_types.h may be the most commonly used one. One example of using it via src/ is src/RSQLite_types.h. On the other hand, an example of using it in inst/include/ is inst/include/RcppQuantuccia_types.h and another, much larger one in inst/include/RcppGSL_types.h.

Rcpp Compilation ERROR: 'clang: error: no such file or directory: '/usr/local/lib/libfontconfig.a'

I was trying to run this peace of code in R (credit to the author):
require(Rcpp)
require(RcppArmadillo)
require(inline)
cosineRcpp <- cxxfunction(
signature(Xs = "matrix"),
plugin = c("RcppArmadillo"),
body='
Rcpp::NumericMatrix Xr(Xs); // creates Rcpp matrix from SEXP
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false); // reuses memory and avoids extra copy
arma::mat Y = arma::trans(X) * X; // matrix product
arma::mat res = (1 - Y / (arma::sqrt(arma::diagvec(Y)) * arma::trans(arma::sqrt(arma::diagvec(Y)))));
return Rcpp::wrap(res);
')
And got, after few fixes, the following error:
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created!
clang: error: no such file or directory: '/usr/local/lib/libfontconfig.a'
clang: error: no such file or directory: '/usr/local/lib/libreadline.a'
make: *** [file5a681e35ebe1.so] Error 1
In addition: Warning message:
running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB file5a681e35ebe1.cpp 2> file5a681e35ebe1.cpp.err.txt' had status 1
I used to use Rcpp a lot in the past. But between now and then my computer has been reformatted and all the installation re-done using homebrew.
I installed cairo with brew: brew install cairo
the libreadline.a error was solved with:
brew link --force readline
But the same did not work for libfontconfig.a since was already linked:
brew link --force fontconfig
Warning: Already linked: /usr/local/Cellar/fontconfig/2.11.1
To relink: brew unlink fontconfig && brew link fontconfig
I would have assumed that fontconfig is within cairo. In fact, when I type
brew install fontconfig
Warning: fontconfig-2.11.1 already installed
But the truth is that there is no libfontconfig.a at /usr/local/lib/:
ls /usr/local/lib/libfont*
/usr/local/lib/libfontconfig.1.dylib
/usr/local/lib/libfontconfig.dylib
Using the very questionable approach of going here and download it, the code runs, but still gives a the corresponding warning, since the file corresponds to a different os.x architecture (I did not found one for 10.9):
+ . + ld: warning: ignoring file /usr/local/lib/libfontconfig.a, missing required architecture x86_64 in file /usr/local/lib/libfontconfig.a (2 slices)
So at this stage I am a little lost.
How do I install libfontconfig.a or find the 10.9 version?
In case is of any use, I have Xcode installed, I am on a Mac 10.9.5,
and based on this very nice and detailed answer my ~/.R/Makevars file looks like:
CC=clang
CXX=clang++
FLIBS=-L/usr/local/bin/
Your system setup is broken. Neither R nor Rcpp have anything to do with clang (unless you chose clang as your system compiler) or fontconfig.
So start simpler:
R> library(Rcpp)
R> evalCpp("2 + 2")
[1] 4
R>
This just showed that my system has a working compiler R (and Rcpp) can talk to. We can it more explicit:
R> evalCpp("2 + 2", verbose=TRUE)
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP get_value(){ return wrap( 2 + 2 ) ; }
No rebuild required (use rebuild = TRUE to force a rebuild)
[1] 4
R>
and R is clever enough not to rebuild. We can then force a build
R> evalCpp("2 + 2", verbose=TRUE, rebuild=TRUE)
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP get_value(){ return wrap( 2 + 2 ) ; }
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
// get_value
SEXP get_value();
RcppExport SEXP sourceCpp_0_get_value() {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
__result = Rcpp::wrap(get_value());
return __result;
END_RCPP
}
Generated R functions
-------------------------------------------------------
`.sourceCpp_0_DLLInfo` <- dyn.load('/tmp/Rtmpeuaiu4/sourcecpp_6a7c7c8295fc/sourceCpp_2.so')
get_value <- Rcpp:::sourceCppFunction(function() {}, FALSE, `.sourceCpp_0_DLLInfo`, 'sourceCpp_0_get_value')
rm(`.sourceCpp_0_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /tmp/Rtmpeuaiu4/sourcecpp_6a7c7c8295fc
/usr/lib/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' --preclean 'file6a7c6d1fc2d6.cpp'
ccache g++ -I/usr/share/R/include -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp/Rtmpeuaiu4" -fpic -g -O3 -Wall -pipe -Wno-unused -pedantic -c file6a7c6d1fc2d6.cpp -o file6a7c6d1fc2d6.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_2.so file6a7c6d1fc2d6.o -L/usr/lib/R/lib -lR
[1] 4
R>
and on that you see system details on my side (Linux, also using ccache) that will be different for you.
After that, try (Rcpp)Armadillo one-liners and so on.

Resources