[Rcpp-devel] Example of rcpp usage with Rmpfr, mpfr, gmp.
Thell Fowler
tbfowler4 at gmail.com
Wed Apr 25 18:32:05 CEST 2012
On Sun, Apr 22, 2012 at 12:13 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
> On 22 April 2012 at 11:41, Thell Fowler wrote:
> | On Sun, Apr 22, 2012 at 10:49 AM, Dirk Eddelbuettel <edd at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120425/7a2a6878/attachment.html>
More information about the Rcpp-devel
mailing list