Rcpp broken on Opensuse 15.2

Created on 9 Feb 2021  Â·  11Comments  Â·  Source: RcppCore/Rcpp

When trying to implement a Rcpp module to expose a C++ class I get an error about I get the following error:

  /usr/include/c++/9/bits/stl_vector.h:509:30:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = double; _Alloc = std::allocator<double>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<double>]’/home/pingu/lib64/R-4.0.3/library/Rcpp/include/Rcpp/sugar/functions/sample.h:153:28:   required from here/usr/include/c++/9/bits/stl_uninitialized.h:597:18: error: ‘value’ is not a member of ‘std::is_copy_assignable<double>’       const bool __assignable = is_copy_assignable<_ValueType>::value;                  ^~~~~~~~~~~~make: *** [/home/pingu/lib64/R-4.0.3/etc/Makeconf:181: file388d7a0874cb.o] Error 1

It turns out that this error message is independent on the particular module code and also happens with all module examples as provided with the package (this is the minimal example):

library('inline')
library('Rcpp')
unifModCode = '
using namespaceRcpp;
/// create external pointer to a Uniform object
RcppExport SEXP Uniform__new(SEXPmin_,SEXPmax_) {
// convert inputs to appropriate C++ types
double min = as<double>(min_),max = as<double>(max_);
// create pointer to an Uniform object and
// wrap it as an external pointer
Rcpp::XPtr<Uniform>ptr(newUniform( min, max ),true);
// return the external pointer to the R side
return ptr;}
/// invoke the draw method
RcppExport SEXP Uniform__draw(SEXP xp, SEXPn_) {
// grab the object as a XPtr (smart pointer)
// to UniformRcpp::XPtr<Uniform> ptr(xp);
// convert the parameter to int
int n = as<int>(n_);
// invoke the function
NumericVector res = ptr->draw( n );
// return the result to Rreturnres;}
}';

    f1<-cxxfunction( ,"",includes =unifModCode,plugin ="Rcpp");
    ## will display info about'f1
    getDynLib(f1)

My sessionInfo is:

R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: openSUSE Leap 15.2

Matrix products: default
BLAS:   /home/user/lib64/R-4.0.3/lib/libRblas.so
LAPACK: /home/user/lib64/R-4.0.3/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=de_DE.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] Rcpp_1.0.6    inline_0.3.17

loaded via a namespace (and not attached):
[1] compiler_4.0.3   tools_4.0.3      codetools_0.2-16

The compiler version is:

g++ --version
g++ (SUSE Linux) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.

The following complier command was generated:

g++ -std=gnu++11 -I"/home/pingu/lib64/R-4.0.3/include" -DNDEBUG  -I"/home/pingu/lib64/R-4.0.3/library/Rcpp/include" -I/usr/local/include   -L"/home/pingu/Documents/src/mmap/build" -lmmap_rcpp -I/home/pingu/lib64/R-4.0.3/library/Rcpp/include -I/usr/include/c++/9 -fpic  -g -O2  -c file388d7a0874cb.cpp -o file388d7a0874cb.o

Thank you very much in advance. Any help appreciated.

Most helpful comment

My suggestion is to use the ~/.R/Makevars file to define CXX and posibly other variables and flags.

All 11 comments

Can you may try to embed your Rcpp Modules in a package as we generally recommend?

I may well be forgetting something but did we ever suggest to try it with package inline? Did you follow a particular piece of doucmentation or tutorial here?

There are existing packages out there using Modules, both on CRAN where they get tested regularly as well as in the "wild" and I just updated one locally for my use. Plus we do have use of Rcpp Modules in our unit tests.

Sorry I got confused by your lingo. You used "module" but you didn't mean Rcpp Modules.

May I suggest you look at the Rcpp Attributes vignette along with the Rcpp Introduction vignette? Creating a simple function is much easier. (Dealing with external pointers is possible too and we have other examples.) It may help if you first clarified what you really wanted to do.

And there are various copy and paste errors here missing whitespace, plus the class Uniform you are templating on is not defining. I am not able to repair this for you, sorry.

Might be best to just close it.

Also, for general use questions, maybe post on rcpp-devel? If your code tries to extend the Uniform example in Modules, I generally found it easiest to keep other extensions in the same file.

Thank you very much for the quick reply. I have done Rcpp modules before and have followed the same recipe in my current effort. On seeing the non-obvious error I went back to the examples from the vignette Rcpp-modules.pdf. The example above was copy-pasted from the document. I have also checked other examples with a class definition from the same pdf all resulting in the same error message.

At the moment, incompatible compiler flags/compiler bug/STL incompatibility seem to be the most likely culprits. I have tried to fiddle around with Sys.setenv to change the compiler command/compiler flags without success. Is there some documentation to which environment variables cxxfunction is sensitive to? Or would such changes require to implement a plugin?

I would appreciate it this bug report can stay open for a while to see whether others see this problem too. If I cannot find a solution here, I will turn to the mailing list.

I just went on a quick walk to get some groceries and mulled over this. I can probably help by injecting the Uniform class.

But you still haven't explained what your issue is. I doubt it is a general inability to compile under OpenSuSE. Detlef Steuer over at HSU has been looking at R and OpenSuSE for almost as long as I have for Debian and things tend to just work. This will be something "simple". We'll get to it.

But I need a _minimally complete and verifiable_ example which your first post wasn't.

@sboehringer I see:

[...] -I/usr/include/c++/9` [...]

so standard library from GCC 9, but

g++ (SUSE Linux) 7.5.0

so GCC 7 from the official repos. If you compiled your custom R version with a custom GCC version, use the same compiler for the packages.

So here is a cleaned up (lots of whitespace got lost in your version) and simplified (using Rcpp Attributes gets us automatic conversion of types such as C++ scalars making the interface simpler). I also added the Uniform class.

If you save the file as, say, /tmp/rcpp1140.cpp the a simple Rcpp::sourceCpp("/tmp/rcpp1140.cpp") will

  • read the file
  • compile and link and load it
  • export the two tagged functions to R
  • run the illustration at the bottom to

    • set the RNG at a seed

    • instantiate an Uniform drawer object

    • call it for 5 draws

which on my machine now gets me

> Rcpp::sourceCpp("/tmp/rcpp1140.cpp")

> set.seed(123) # reproducible draws

> xp <- getUniform(10,20)

> vec <- drawUniform(xp, 5)

> vec
[1] 12.8758 17.8831 14.0898 18.8302 19.4047
> 

Code is below. It should work on any machine with proper compile and headers.

#include <Rcpp.h>

using namespace Rcpp;

class Uniform {
public:
    Uniform(double min_, double max_) : 
       min(min_), max(max_) {}

    NumericVector draw(int n) {
        RNGScope scope;
        return runif(n, min, max);
    }

private:
    double min, max;
};

// create external pointer to a Uniform object
// [[Rcpp::export]]
XPtr<Uniform> getUniform(double min, double max) {
  // create pointer to an Uniform object and
  // wrap it as an external pointer
  Rcpp::XPtr<Uniform> ptr(new Uniform( min, max ), true);
  // return the external pointer to the R side
  return ptr;
}

// invoke the draw method
// [[Rcpp::export]]
NumericVector drawUniform(XPtr<Uniform> xp, int n) {
  // grab the object as a XPtr (smart pointer)
  // to UniformRcpp::XPtr<Uniform> ptr(xp);
  // convert the parameter to int
  // invoke the function
  NumericVector res = xp->draw( n );
  // return the result to R
  return res;
}

/*** R
set.seed(123) # reproducible draws
xp <- getUniform(10,20)
vec <- drawUniform(xp, 5)
vec
*/

My aplogies, the examples work after all. I somehow mixed up the error output with those from my own code.

I have now narrowed down the problem to a c++ standard issue. As cxxfunction outputs the compilation commands, I could switch to the temporary directory to tweak the commands. Strangely, I do get different errors even for the same command. Still, by using --std c++17 and clang++ as the compiler, I could generate the shared library manually. I still haven't managed to load the Module from this shared library using the 'Module' function, however, I believe that this should be possible. Using dyn.load on the shared library works as a first step.

The remaining question is whether I can make cxxfunction to use a different compiler and change the c++ standard. I found the //[[Rcpp::plugins(cpp17)]] directive. However, this does not seem to have any effect.

@eddelbuettel: thanks for your help and patience so far.

My suggestion is to use the ~/.R/Makevars file to define CXX and posibly other variables and flags.

There are a few StackOverflow posts as well as mailing list posts I made over the last decade+ which show the ~/.R/Makevars use. With a little creative googling you should find it. I think it's also in the Rcpp FAQ (or should be ...).

All good then so I close this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iago-pssjd picture iago-pssjd  Â·  4Comments

PeteHaitch picture PeteHaitch  Â·  6Comments

eddelbuettel picture eddelbuettel  Â·  3Comments

ivan-krukov picture ivan-krukov  Â·  8Comments

progtw picture progtw  Â·  8Comments