On Sun, Apr 22, 2012 at 12:13 PM, Dirk Eddelbuettel <e...@debian.org> wrote:
> On 22 April 2012 at 11:41, Thell Fowler wrote: > | On Sun, Apr 22, 2012 at 10:49 AM, Dirk Eddelbuettel <e...@debian.org> > wrote: > | On 22 April 2012 at 10:17, Thell Fowler wrote: > > | | Any examples or direction on how (if I can) to get to a Rcpp Rmpfr > bridge > | with > | | speed would go a long way... > | > | Sounds fine. Not sure how to return (or pass down) the mpfr arrays. > But you > | may be able to > | look at the existing CRAN packages wrapping mpfr for ideas. > | > | I'll try reading through the Rmpfr source to see how it does its' magic. > | Also, the Bessel package depends on Rmpfr so that might yield some ideas. > > It shouldn't be too hard, apart from the fact that instead of Rcpp niceties > you have to deal with R API which is plain C and macros... > > After some trial and error I was able to pass down mpfr values. You're right though, it wasn't 'nice'. --->8 --- > | > | You just need to add the required -I and -L flags to src/Makevars > and you > | should be fine. [ Higher-end solutions use configure, or pkg-config, > or > | ... to find those values. Harcoded may work on standard Linux > systems. ] > | > | That part _should_ be pretty straight forward. > > Yes. > > Well, it wasn't really all that straight forward after all as I need to use -std=c++0x. Here's the code and comments used to setup access... <I hope gmail doesn't mess this up too much, I haven't setup alpine for this list yet...> suppressMessages( require( Rcpp ) ) suppressMessages( require( inline ) ) ## Base Access to mpfr ##### # To have access to mpfr the following was done... # Extracted Rtools Local215keep3.zip to `c:\RtoolsLocal\R-2.15.0` # Created an environment var `RTOOLS_LOCAL` to that path. # Set LOCAL_SOFT = $(RTOOLS_LOCAL) in $(R_HOME}/etc$(R_ARCH)/Makeconf # < note: CXXFLAGS = -O3 -Wall $(DEBUGFLAG) -std=c++0x -mtune=core2 > mpfr.settings <- Rcpp:::Rcpp.plugin.maker( include.before= "#include <mpfr.h>", libs= "-lgmp -lmpfr" ) registerPlugin( "RcppMpfr", mpfr.settings ) # Test mpfr .dll access mpfr.Rcpp.source <- ' Rprintf(" MPFR library: %-12s\\n MPFR header: %s (based on %d.%d.%d)\\n", mpfr_get_version(), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL); return Rcpp::wrap( std::string("OK") ); ' mpfr.Rcpp.test <- cxxfunction( signature(), body= mpfr.Rcpp.source, plugin= "RcppMpfr", verbose= FALSE ) cat( mpfr.Rcpp.test(), '\n') ## Access to Rmpfr ##### # To utilize the Rmpfr .dll functions for processing the Rmpfr SEXP parameters # a junction was made linking the src path of the mpfr to a new `include` # path in the Rmpfr package path. # # Inclusion of the Mpfr_utils caused some issues though; # 1) REVprintf is not defined by R_ext/Print.h when __cpluscplus id defined # unless R_USE_C99_IN_CXX is defined. # 2) allocVector is not decalred unless R_NO_REMAP is not defined. # ... # Yet, with 1 defined and 2 not defined and passing -std=c++0x to GCC there is # a macro argument length error in codecvt.h included by Rostream.h's inclusion # of iomanip and __GXX_EXPERIMENTAL_CXX0X. # # Not passing -std=c++0x allowed successful compilation, but I'll need it. # suppressMessages( require( Rmpfr ) ) Rmpfr.Rcpp.include.before <-' #define R_USE_C99_IN_CXX #undef R_NO_REMAP #include <Rmpfr_utils.h> #include <Syms.h> ' Rmpfr.Rcpp.include.after <-' #include <R_ext/Rdynload.h> ' Rmpfr.settings <- Rcpp:::Rcpp.plugin.maker( include.before= Rmpfr.Rcpp.include.before, include.after= Rmpfr.Rcpp.include.after, LinkingTo=c('Rmpfr',"Rcpp"), libs="-lgmp -lmpfr" ) registerPlugin( "RcppRmpfr", Rmpfr.settings ) Rmpfr.Rcpp.include <- ' // Typedefs... // Doing this for each signature in Rmpfr that is used should not be too bad, // but it would be nice not to have to. typedef SEXP (*FUNC)(void); FUNC p_R_mpfr_get_version = (FUNC) R_GetCCallable("Rmpfr", "R_mpfr_get_version"); ' Rmpfr.Rcpp.source <- ' Rprintf(" MPFR library: %-12s\\n MPFR header: %s (based on %d.%d.%d)\\n", mpfr_get_version(), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL); return p_R_mpfr_get_version(); ' Rmpfr.Rcpp.test <- cxxfunction( signature(), includes= Rmpfr.Rcpp.include, body= Rmpfr.Rcpp.source, plugin= "RcppRmpfr", verbose= FALSE ) cat( Rmpfr.Rcpp.test(), '\n') | [ And if you want to look into doing more of an integration (a la > | RcppArmadillo, > | RcppGSL, RcppEigen, ...), then the Rcpp-extending vignette shows you > how to > | modify as<>() and wrap() to get automatic converters going. But you > | surely > | don't need to do this for a first attempt to compute your stuff. I > just > | mention it as you say 'R mpfr bridge' -- this would be the Rcpp way > of > | doing > | it. ] > | > | The Rcpp-extending vignette is what I originally thought would be the > answer. > | Good thing I asked first! ;) > > It's somewhat scarier reading material but it nudges ever so gently into > Template Programming... You do *not* need to go there just to call mpfr. > > Well, in the end it looks like this is essentially what I'll need to do... After looking around at the options I think what I need to do is use the mpfrc++ library. Only two headers and works on top of gmp and mpfr, but I do wonder one thing about using it as an extension... It includes its own dlmalloc, is this a death blow for using it as either an extension/package, RcppMpfr++ package? -- Sincerely, Thell
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel