[R-pkg-devel] R_registerRoutines, etc.

Rolf Turner r.turner at auckland.ac.nz
Sun Apr 23 05:15:19 CEST 2017


Thanks for trying, but your example blows me away completely.

cheers,

Rolf

On 23/04/17 14:47, Avraham Adler wrote:
> On Sat, Apr 22, 2017 at 6:13 PM, Rolf Turner <r.turner at auckland.ac.nz> wrote:
>>
>> The foregoing "official" way would seem to apply to functions called by
>> ".Call" (which I never use; it is way over my head).  What about functions
>> called by ".Fortran()" or ".C()"?
>>
>>> |     (b) For the sake of completeness, how *does* one replace the "void
>>> *"
>>> |         constructions with "actual types" in a correct manner?
>>> |
>>> |          Example:  In my init.c file I currently have (as produced by
>>> |          package_native_routine_registration_skeleton()) :
>>> |
>>> | > extern void F77_NAME(mnnd)(void *, void *, void *, void *, void *);
>>> |
>>> |          The code in mnnd.f reads:
>>> |
>>> | > subroutine mnnd(x,y,n,dminbig,dminav)
>>> | > implicit double precision(a-h,o-z)
>>> | > .....
>>> |
>>> |          I.e. the "actual types are "double precision",
>>> |          "double precision", "integer", "double precision",
>>> |          "double precision".
>>> |
>>> |          So in this case I should (?) replace
>>> |
>>> | > extern void F77_NAME(mnnd)(void *, void *, void *, void *, void *);
>>> |
>>> |          by .... what?  Can anyone tell me?
>>>
>>> No idea. I don't deal in Fortran. C++ is more than enough fun for me ;-)
>>
>>
>> Well, C++ is too much for me.  I find Fortran generally very easy.  Be that
>> as it were, are there any Fortran users out there who can answer my
>> question, above?
>>
>
> I cannot answer your question completely, as I use .Call() to call
> Fortran from R via C instead of using .Fortran—from what I have read
> and researched, it is faster.
>
> That being said, maybe this will help. Given a subroutine in Fortran
> which starts like:
>
>     subroutine ddelap_f(x, nx, a, na, b, nb, l, nl, lg, pmfv) bind(C,
> name="ddelap_f")
>
>     integer(kind = c_int), intent(in), value         :: nx, na, nb, nl
>     ! Sizes
>     real(kind = c_double), intent(in), dimension(nx) :: x
>     ! Observations
>     real(kind = c_double), intent(out), dimension(nx):: pmfv
>     ! Result
>     real(kind = c_double), intent(in)                :: a(na), b(nb),
> l(nl)! Parameters
>     integer(kind = c_int), intent(in)                :: lg
>     ! Log flag
>     integer                                          :: i
>     ! Integer
>
> The corresponding C code which calls it is
>
>     void ddelap_f(double *x, int nx, double *a, int na, double *b, int
> nb, double *l, int nl,
>                   int *lg, double *ret);
>
> and the actual code called by R is:
>
>     extern SEXP ddelap_C(SEXP x, SEXP alpha, SEXP beta, SEXP lambda, SEXP lg){
>       const int nx = LENGTH(x);
>       const int na = LENGTH(alpha);
>       const int nb = LENGTH(beta);
>       const int nl = LENGTH(lambda);
>       SEXP ret;
>       PROTECT(ret = allocVector(REALSXP, nx));
>       ddelap_f(REAL(x), nx, REAL(alpha), na, REAL(beta), nb,
> REAL(lambda), nl, INTEGER(lg), REAL(ret));
>       UNPROTECT(1);
>       return(ret);
>     }
>
> Also, I don't use the "automatic" concatenation of the "c_" to my
> Fortran functions, but name them individually and use Fortran 2003 ISO
> C bindings (except for booleans).
>
> If it helps, take a look at the source code at
> <https://bitbucket.org/aadler/delaporte>. As of now, it passes all R
> checks and so must have appeased the registration requirements 8-)
>
> Thank you,
>
> Avi
>



More information about the R-package-devel mailing list