Fatal error when tring to call C++ function from R - c++

I have a C++ function called "file1.cpp" that looks like:
#include <cmath>
#include <stdio.h>
#include <RcppArmadillo.h>
#include <boost/math/special_functions/gamma.hpp>
#include <mpi.h>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
using namespace std;
using namespace arma;
using namespace boost::math;
const double PIVAL = std::acos(0.0)*2;
class function1
{
...
}
extern "C"
void functin2
{
...
}
I want to call it from an R function. In order to do that I needed to compile it first to get the "file1.so", which I can use it later in the R command:
dyn.load("file1.so.so")
So it ubuntu 16.10 terminal I wrote:
$ R CMD SHLIB file1.cpp -O2 -larmadillo -llapack -lblas
when I press enter I will get the follwing error message:
g++ -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-rAT5Oi/r-base-3.3.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c file1.cpp -o file1.o
file1.cpp:12:81: fatal error: RcppArmadillo.h: No such file or directory
#include <RcppArmadillo.h>
I couldn't find solution for that error. So, I tried to call the C++ function from inside Rstudio. I wrote the follwing commands:
library(Rcpp)
library(RcppArmadillo)
sourceCpp("file1.cpp")
function2()
When executing it I will get this error:
file1.cpp:11:81: fatal error: RcppArmadillo.h: No such file or directory
Anybody have an idea about how to solve it? Thanks in advance.
Best Regards,

Please read some of the many existing examples on RcppArmadillo here, at the Rcpp Gallery or, heaven forbid, in the package documentation.
You could of course just call RcppArmadillo.package.skeleton() and have a working package created for you to start from and place your local changes in.
See this:
R> setwd("/tmp")
R> RcppArmadillo::RcppArmadillo.package.skeleton("demoPkg")
Calling kitten to create basic package.
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './demoPkg/Read-and-delete-me'.
Adding pkgKitten overrides.
Deleted 'Read-and-delete-me'.
Done.
Consider reading the documentation for all the packaging details.
A good start is the 'Writing R Extensions' manual.
And run 'R CMD check'. Run it frequently. And think of those kittens.
Adding RcppArmadillo settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp, RcppArmadillo
>> added useDynLib and importFrom directives to NAMESPACE
>> added Makevars file with Rcpp settings
>> added Makevars.win file with RcppArmadillo settings
>> added example src file using armadillo classes
>> added example Rd file for using armadillo classes
>> invoked Rcpp::compileAttributes to create wrappers
R>
which creates, _inter alia, this file:
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
// we only include RcppArmadillo.h which pulls Rcpp.h in for us
#include "RcppArmadillo.h"
// via the depends attribute we tell Rcpp to create hooks for
// RcppArmadillo so that the build process will know what to do
//
// [[Rcpp::depends(RcppArmadillo)]]
// simple example of creating two matrices and
// returning the result of an operatioon on them
//
// via the exports attribute we tell Rcpp to make this function
// available from R
//
// [[Rcpp::export]]
arma::mat rcpparma_hello_world() {
arma::mat m1 = arma::eye<arma::mat>(3, 3);
arma::mat m2 = arma::eye<arma::mat>(3, 3);
return m1 + 3 * (m1 + m2);
}
// another simple example: outer product of a vector,
// returning a matrix
//
// [[Rcpp::export]]
arma::mat rcpparma_outerproduct(const arma::colvec & x) {
arma::mat m = x * x.t();
return m;
}
// and the inner product returns a scalar
//
// [[Rcpp::export]]
double rcpparma_innerproduct(const arma::colvec & x) {
double v = arma::as_scalar(x.t() * x);
return v;
}
// and we can use Rcpp::List to return both at the same time
//
// [[Rcpp::export]]
Rcpp::List rcpparma_bothproducts(const arma::colvec & x) {
arma::mat op = x * x.t();
double ip = arma::as_scalar(x.t() * x);
return Rcpp::List::create(Rcpp::Named("outer")=op,
Rcpp::Named("inner")=ip);
}
and that should be enough to get you going.

Related

The linkage between R and C++(Rccp) [duplicate]

This question already has answers here:
Rcpp - sourceCpp - undefined symbol
(2 answers)
Closed 4 years ago.
I have existing C code that consists of three files: a header file ( a ".h" file), a library file (a ".o" file), and a source file. They currently run under UNIX and as compiled "mex files" in Matlab. I would like to port them to R using Rcpp. They are all long and complex, so I made a minimal example to help me understand how to port them to R.
The simplified header file (my_header.h) is:
typedef unsigned int ui4;
ui4 add_one( ui4 );
The simplified "library" file (my_lib.cpp) is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "my_header.h"
ui4 add_one(ui4 x) {
return(x+1);
}
The simplified function program (my_program.cpp) is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <Rcpp.h>
#include <cmath>
#include "my_header.h"
using namespace Rcpp;
// [[Rcpp::export]]
ui4 my_program_r () {
//int main (int argc, const char * argv[]) {
//
// As a MATLAB mex file, this function calls "main(..."
//
ui4 value = add_one( (ui4)1 );
printf( "%d", value );
return value;
}
From the terminal (I'm on a Mac), I can compile these without an error:
$ g++ my_lib.cpp -c -o my_lib.o
$ g++ my_program.cpp -o my_program my_lib.o
When I try to compile them in RStudio, I get:
> library(Rcpp)
> sourceCpp( "my_program.cpp" )
Warning message:
In sourceCpp("my_program.cpp") :
No Rcpp::export attributes or RCPP_MODULE declarations found in source
>
Why isn't this compiling under Rcpp? How do I specify the linked file (the ".o" library file) in the "sourceCpp" command? Do I need to specify the header file?
The sourceCpp command is meant for single files only. If you have multiple files, you have to use a package:
Call Rcpp::Rcpp.package.skeleton(...) to create a skeleton package.
Copy *.h, *.c and *.cpp to the src folder.
Call Rcpp::compileAtrributes().
Use R CMD build ..., R CMD check ... and R CMD INSTALL ... to build, check and compile the package. (The check will complain about undocumented functions ...)
For more details see Rcpp-package vignette and for example this question. BTW, since R does not have an unsigned int type, I am not sure if your return value will work. You might have to switch to an int or double. I also get a different error message than you:
Error in dyn.load("/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so") :
unable to load shared object '/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so':
/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so: undefined symbol: _Z7add_onej
Are you sure the above code is exactly what you used?

Linking GSL libraries to RcppGSL in Windows 10

I have written the following .cpp file to draw samples from Dirichlet distribution using the random number distribution function in GSL. The filename is C_functions.cpp. I am doing everything in Windows 10.
#include <RcppArmadillo.h>
#include <RcppGSL.h>
// #include <Rcpp.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppGSL)]]
using namespace arma;
// [[Rcpp::export]]
vec rdirichlet_arma(vec a){
const gsl_rng_type * T;
gsl_rng * r;
/* create a generator chosen by the
environment variable GSL_RNG_TYPE */
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
/* print n random variates chosen from
the poisson distribution with mean
parameter mu */
int n=a.size();
vec results(n);
gsl_ran_dirichlet(r, n, a.begin(), results.begin());
gsl_rng_free (r);
a.reset();
return results;
}
// [[Rcpp::export]]
double pow2(double x){
return gsl_pow_2(x);
}
I have created an environmental variable LIB_GSL and set its value as "C:/Users/nkc10/Documents/R/local323". This is the location where I unzipped the local323.zip folder downloaded from this link .
However, when I compile it with sourceCpp the following error is shown
>C:/RBuildTools/3.5/mingw_64/bin/g++ -std=gnu++11 -I"C:/PROGRA~1/R/R-35~1.2/include" -DNDEBUG -I../inst/include -fopenmp -I/include -I"C:/Users/nkc10/Documents/R/win-library/3.5/Rcpp/include" -I"C:/Users/nkc10/Documents/R/win-library/3.5/RcppArmadillo/include" -I"C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include" -I"C:/Users/nkc10/Dropbox/Research/sparse_bayesian_infinite_factor_models-master" -O2 -Wall -mtune=generic -c C_functions.cpp -o C_functions.o
In file included from C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include/RcppGSL.h:25:0,
from C_functions.cpp:2:
C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include/RcppGSLForward.h:26:29: fatal error: gsl/gsl_vector.h: No such file or directory
#include <gsl/gsl_vector.h>
^
compilation terminated.
make: *** [C:/PROGRA~1/R/R-35~1.2/etc/x64/Makeconf:215: C_functions.o] Error 1
Error in sourceCpp("C_functions.cpp") :
Error 1 occurred building shared library.
You are close, since you already got the local323 file.
Two more steps:
Copy the c:\local323\include\gsl folder into your RcppGSL folder (i.e., C:\Users\YOU\Documents\R\win-library\3.6\RcppGSL\include) OR into your project directory. I tried the latter, but I think it should work either way.
From the local323 package, copy libgsl.a libgslcblas.a to c:\Rtoools\mingw_64\libs. I have no idea why it doesn't find it in your c:\local323 folder, but this will work.
And I tested it, your code works.

Strange compilation error: compiler bug or my own?

I have header-only library, and I'm getting the strangest compilation error. The problem in proceeding is that I'm not getting this error in a representative minimal example, and not on all compilers (on macOS everything compiles and runs like a charm). I am not sure if I should be worried about something in my code, or if it is an upstream bug. Regardless, I'm not sure how to work around this.
I'm getting the following compiler error:
In file included from /home/tdegeus/opt/include/eigen3/Eigen/SparseCore:59:0,
from /home/tdegeus/opt/include/eigen3/Eigen/Sparse:26,
from /home/tdegeus/opt/include/eigen3/Eigen/Eigen:2,
from /home/tdegeus/prog/src/GooseFEM/docs/examples/Statics/Periodic/LinearElasticity/main.cpp:1:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h: In function ‘void Eigen::internal::permute_symm_to_symm(const MatrixType&, Eigen::SparseMatrix<typename MatrixType::Scalar, DestOrder, typename MatrixType::StorageIndex>&, const typename MatrixType::StorageIndex*) [with int SrcMode = 1; int DstMode = 2; MatrixType = Eigen::SparseMatrix<double>; int DestOrder = 0]’:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h:517:6: internal compiler error: in predicate_mem_writes, at tree-if-conv.c:2252
void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::StorageIndex>& _dest, const typename MatrixType::StorageIndex* perm)
^~~~~~~~~~~~~~~~~~~~
0xb3530b predicate_mem_writes
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2252
0xb3530b combine_blocks
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2377
0xb359bb tree_if_conversion(loop*)
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2883
0xb3663b execute
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2961
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Which disappears if I comment this line (obviously breaking functionality):
m_solver.compute(m_ACuu);
Note that:
Eigen::SparseMatrix<double> m_ACuu;
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> m_solver;
I tried a minimal example:
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/SparseCholesky>
int main()
{
size_t N = 11;
// allocate system
Eigen::SparseMatrix<double> A(N,N);
Eigen::VectorXd f(N);
// set force
f *= 0.0;
f((N-1)/2) = 1.0;
// construct list of Triplets (row,col,data) that from the matrix "A"
std::vector<Eigen::Triplet<double>> Atr;
// - first equation
Atr.push_back(Eigen::Triplet<double>(0,0,+2.0));
Atr.push_back(Eigen::Triplet<double>(0,1,-1.0));
// - body
for ( size_t i=1; i<N-1; ++i ) {
Atr.push_back(Eigen::Triplet<double>(i,i-1,-1.0));
Atr.push_back(Eigen::Triplet<double>(i,i ,+2.0));
Atr.push_back(Eigen::Triplet<double>(i,i+1,-1.0));
}
// - last equation
Atr.push_back(Eigen::Triplet<double>(N-1,N-2,-1.0));
Atr.push_back(Eigen::Triplet<double>(N-1,N-1,+2.0));
// build matrix from Triplets
A.setFromTriplets(Atr.begin(),Atr.end());
// solve the linear system
// - define solver (according to type above)
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver;
// - analyze the system, and factorize (one could solve different right-hand-sides)
// solver.analyzePattern(A);
solver.factorize(A);
// - solve "A * x = f"
Eigen::VectorXd u = solver.solve(f);
// print to screen
std::cout << A << std::endl;
std::cout << u << std::endl;
return 0;
}
Compiled on the same system with the same libraries and with similar options:
g++ -march=native -O3 test.cpp
But this compiles and runs like a charm!?
Note that I've tried several Eigen versions, including 3.3.90.
Edit
Also note that this problem occurs with
g++ --version
g++ (GCC) 7.3.0
But is gone for
g++ (GCC) 6.4.0

What is the way to pass a custom made struct (vector of pointers) from C++ to python using pybind11?

For a project, I need to pass a C++ struct to python as an input.
I am not a lot familiar with C++, so I find hard to understand how to do it.
The error I get is:
libc++abi.dylib: terminating with uncaught exception of type pybind11::cast_error: Unable to convert call argument 'variable' of type 'Example' to Python object
Since I am obviously not telling python how to transform the struct exactly.
I would highly appreciate any hints or feedbacks on how to do it.
Thank you :)
//example.cpp
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>
#include <pybind11/stl.h>
#include <memory>
// USE TO COMPILE: g++ -fPIC `python3 -m pybind11 --includes` -undefined dynamic_lookup -std=c++11 -O2 example.cpp -o example -L/usr/local/Cellar/python/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/ `python3-config --libs`
using namespace std;
namespace py = pybind11;
using namespace py::literals; // to bring in the `_a` literal
int MAX_LEN=10;
typedef double Real;
struct Example
{
Example()
{
vector1.reserve(MAX_LEN);
vector2.reserve(MAX_LEN);
}
std::vector<std::vector<Real>> vector1;
std::vector<std::vector<Real>> vector2;
~Example() { clear(); }
void clear()
{
vector1.clear();
vector2.clear();
}
};
PYBIND11_EMBEDDED_MODULE(exampleModule, m){
py::class_<Example>(m, "Example")
.def(py::init<>());
}
int main(void){
py::scoped_interpreter guard{};
py::dict locals;
Example ex;
ex.vector1 = std::vector <vector<Real>> (MAX_LEN, vector<Real>(MAX_LEN, 1.0));
ex.vector2 = std::vector <vector<Real>> (MAX_LEN, vector<Real>(MAX_LEN, 2.0));
locals = py::dict("variable"_a=ex);
py::exec(R"(
print(variable)
)", py::globals(), locals);
return 0;
}
You will need to add binding for the Example struct.
This works the same as adding bindings for classes, e.g.:
py::class_(m, "Example")
.def(py::init())
.def_readwrite("vector1", &Example::vector1)
For the STL vector types, remember to include pybind11/stl.h also.
More details are available in the pybind11 documentation.

ARMA_NO_DEBUG in R package with RcppArmadillo

I want to disable bound checks when accessing to matrix elements in RcppArmadillo.
The documentations of Armadillo says
Armadillo can be configured via editing the file
include/armadillo_bits/config.hpp. Specific functionality can be
enabled or disabled by uncommenting or commenting out a particular
#define, listed below.
But in the context of an R package, how can I activate this directive?
I have tried to create a config.h file with
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
and then including it in every .cpp file of my /src folder, but I'm not sure whether it works properly or whether there is some other way other than adding a #include "config.h"in each .cpp file.
Currently I have one .cpp (the one that contains the main algorithm) that start with:
#include "configs.h"
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
SEXP sample_gibbs_cpp(const arma::vec& v_n, const arma::mat& W,
arma::vec h_n, double alpha = 1, double beta = 1, int iter=100,
double burnin = 0.5){
... code ...
}
And then others that are just
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
... code ...
My DESCRIPTION file:
Package: mypackage
Title: What the Package Does (one line, title case)
Version: 0.0.0.9000
Authors#R: person("First", "Last", email = "first.last#example.com", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends:
R (>= 3.2.3)
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 5.0.1
Imports:
ggplot2,
dplyr,
tidyr,
rstan
LinkingTo: Rcpp, RcppArmadillo, RcppEigen
SystemRequirements: C++11
And I compile my package with:
devtools::load_all()
Order matters here. This #define statement must be included before the inclusion of #include<RcppArmadillo.h>
An example:
custom_config.h
#ifndef CONFIG_LOADED
#define CONFIG_LOADED
#define ARMA_NO_DEBUG
#endif
example_compiled_file.cpp
#include "custom_config.h"
#include <RcppArmadillo.h>
// [[Rcpp::export]]
void test_pkg(const arma::vec& x) {
// Should not trigger error bound checking with debug flag on.
double my_val_protected = x(0);
// Never triggers error bound checking
double my_val = x.at(0);
}
Note: As this is a package, the use of // [[Rcpp::depends(RcppArmadillo)]] is not required. Instead, you must specify RcppArmadillo and Rcpp in the LinkingTo: field of the DESCRIPTION file as well as including Rcpp in the Imports: field. You will have to minimally import from Rcpp a function (preferably: evalCpp).
e.g. DESCRIPTION must have:
Imports: Rcpp (>= 0.12.15)
LinkingTo: Rcpp, RcppArmadillo