There are comments in various places, including R-extensions ?5.4 suggesting that .Fortran is (nearly) deprecated and hinting that use of .Call is more efficient and now preferred for packages. I understand and greatly appreciate its use with dyn.load() and R CMD SHLIB for development workflow. In an effort to modernize my quantreg package I wanted to solicit some advice about whether it was worthwhile to move away from .Fortran, and if so how this might be most expeditiously carried out. As things currently stand my src directory has, in addition to couple dozen .f files, a file called quantreg_init.c that contains #include <R_ext/RS.h> #include <stdlib.h> // for NULL #include <R_ext/Rdynload.h> /* .Fortran calls */ extern void F77_NAME(brutpow)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(combin)(void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(crqf)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); ? static const R_FortranMethodDef FortranEntries[] = { {"brutpow", (DL_FUNC) &F77_NAME(brutpow), 14}, {"combin", (DL_FUNC) &F77_NAME(combin), 7}, {"crqf", (DL_FUNC) &F77_NAME(crqf), 26}, ... void R_init_quantreg(DllInfo *dll) { R_registerRoutines(dll, CEntries, NULL, FortranEntries, NULL); R_useDynamicSymbols(dll, FALSE); } This was originally setup by an experienced R person in about 2006, but has always been rather opaque to me; I just follow the template to add fortran functions. My questions are: what would I need to do beyond replacing .Fortran calls by .Call in my R code? And would it help? Obviously, what I?m dreading is being told that all those ?void?s would have to be specified more explicitly even though they are already specified in the fortran. My willingness to embarrass myself by writing this message was triggered by comparing timings of a prototype function in R and its fortranization in which the prototype was actually faster. Thanks in advance for any suggestions.
To make C prototypes for routines defined in a *.f file you can use gfortran's -fc-prototypes-external flag. You still have to convert 'name_' to 'F77_NAME(name). bill at Bill-T490:~/packages/quantreg/src$ gfortran -fc-prototypes-external -fsyntax-only boot.f ... [elided defs of complex types] ... /* Prototypes for external procedures generated from boot.f by GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0. Use of this interface is discouraged, consider using the BIND(C) feature of standard Fortran instead. */ void pwy_ (int *m, int *n, int *k, int *m5, int *n2, double *a, double *c, double *b, double *t, double *toler, int *ift, double *x, double *e, int *s, double *wa, double *wb); void xys_ (int *mofn, int *m, int *n, int *k, int *mofn5, int *n2, double *a, double *b, double *tau, double *toler, int *ift, double *x, double *e, int *s, double *wa, double *wb, double *aa, double *bb, int *ss); void wxy_ (int *m, int *n, int *k, int *m5, int *n2, double *a, double *b, double *tau, double *toler, int *ift, double *x, double *e, int *s, double *wa, double *wb, double *aa, double *bb, double *w); #ifdef __cplusplus } #endif bill at Bill-T490:~/packages/quantreg/src$ gfortran --version GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. On Sat, Dec 19, 2020 at 9:05 AM Koenker, Roger W <rkoenker at illinois.edu> wrote:> There are comments in various places, including R-extensions ?5.4 > suggesting that .Fortran is (nearly) > deprecated and hinting that use of .Call is more efficient and now > preferred for packages. I understand > and greatly appreciate its use with dyn.load() and R CMD SHLIB for > development workflow. > In an effort to modernize my quantreg package I wanted to solicit some > advice > about whether it was worthwhile to move away from .Fortran, and if so how > this > might be most expeditiously carried out. > > As things currently stand my src directory has, in addition to couple > dozen .f > files, a file called quantreg_init.c that contains > > #include <R_ext/RS.h> > #include <stdlib.h> // for NULL > #include <R_ext/Rdynload.h> > > /* .Fortran calls */ > extern void F77_NAME(brutpow)(void *, void *, void *, void *, void *, void > *, void *, void *, void *, void *, void *, void *, void *, void *); > extern void F77_NAME(combin)(void *, void *, void *, void *, void *, void > *, void *); > extern void F77_NAME(crqf)(void *, void *, void *, void *, void *, void *, > void *, void *, void *, void *, void *, void *, void *, void *, void *, > void *, void *, void *, void *, void *, void *, void *, void *, void *, > void *, void *); > > ? > > static const R_FortranMethodDef FortranEntries[] = { > {"brutpow", (DL_FUNC) &F77_NAME(brutpow), 14}, > {"combin", (DL_FUNC) &F77_NAME(combin), 7}, > {"crqf", (DL_FUNC) &F77_NAME(crqf), 26}, > > ... > > void R_init_quantreg(DllInfo *dll) > { > R_registerRoutines(dll, CEntries, NULL, FortranEntries, NULL); > R_useDynamicSymbols(dll, FALSE); > } > This was originally setup by an experienced R person in about 2006, but has > always been rather opaque to me; I just follow the template to add fortran > functions. My questions are: what would I need to do beyond replacing > .Fortran calls by .Call in my R code? And would it help? Obviously, what > I?m dreading is being told that all those ?void?s would have to be > specified > more explicitly even though they are already specified in the fortran. My > willingness to > embarrass myself by writing this message was triggered by comparing > timings of a prototype function in R and its fortranization in which the > prototype was actually faster. Thanks in advance for any suggestions. > > > > > > > > > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
On Sat, 19 Dec 2020 17:04:59 +0000 "Koenker, Roger W" <rkoenker at illinois.edu> wrote:> There are comments in various places, including R-extensions ?5.4 > suggesting that .Fortran is (nearly) deprecated and hinting that use > of .Call is more efficient and now preferred for packages.My understanding of ?5.4 and 5.5 is that explicit routine registration is what's important for efficiency, and your package already does that (i.e. calls R_registerRoutines()). The only two things left to add would be types (REALSXP/INTSXP/...) and styles (R_ARG_IN, R_ARG_OUT/...) of the arguments of each subroutine. Switching to .Call makes sense if you want to change the interface of your native subroutines to accept arbitrary heavily structured SEXPs (and switching to .External could be useful if you wanted to play with evaluation of the arguments). -- Best regards, Ivan P.S. I think that this question is better asked in the r-package-devel at r-project.org mailing list instead of R-devel.
On 2020-12-19 18:04, Koenker, Roger W wrote:> There are comments in various places, including R-extensions ?5.4 suggesting that .Fortran is (nearly) > deprecatedThis scares me somewhat: Where in ?5.4 do you find that suggestion? My package eha is built upon a stand-alone Fortran 77 program from the early eighties (emanating from an appendix in [1]) and has served me well over the years, I see no reason at all to switch to .Call for that old stuff. But of course, if .Fortran will be deprecated ... Can someone confirm if, and if so when, that will happen? Regarding speed, as I understand it, it is a question of making many (short) calls to .Fortran for solving one problem. If you make only one or just a few calls to .Fortran (the case in eha), no problem. [1] Kalbfleisch & Prentice (1980). The Statistical Analysis of Failure Time Data. G?ran Brostr?m : and hinting that use of .Call is more efficient and now preferred for packages. I understand> and greatly appreciate its use with dyn.load() and R CMD SHLIB for development workflow. > In an effort to modernize my quantreg package I wanted to solicit some advice > about whether it was worthwhile to move away from .Fortran, and if so how this > might be most expeditiously carried out. > > As things currently stand my src directory has, in addition to couple dozen .f > files, a file called quantreg_init.c that contains > > #include <R_ext/RS.h> > #include <stdlib.h> // for NULL > #include <R_ext/Rdynload.h> > > /* .Fortran calls */ > extern void F77_NAME(brutpow)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); > extern void F77_NAME(combin)(void *, void *, void *, void *, void *, void *, void *); > extern void F77_NAME(crqf)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); > > ? > > static const R_FortranMethodDef FortranEntries[] = { > {"brutpow", (DL_FUNC) &F77_NAME(brutpow), 14}, > {"combin", (DL_FUNC) &F77_NAME(combin), 7}, > {"crqf", (DL_FUNC) &F77_NAME(crqf), 26}, > > ... > > void R_init_quantreg(DllInfo *dll) > { > R_registerRoutines(dll, CEntries, NULL, FortranEntries, NULL); > R_useDynamicSymbols(dll, FALSE); > } > This was originally setup by an experienced R person in about 2006, but has > always been rather opaque to me; I just follow the template to add fortran > functions. My questions are: what would I need to do beyond replacing > .Fortran calls by .Call in my R code? And would it help? Obviously, what > I?m dreading is being told that all those ?void?s would have to be specified > more explicitly even though they are already specified in the fortran. My willingness to > embarrass myself by writing this message was triggered by comparing > timings of a prototype function in R and its fortranization in which the > prototype was actually faster. Thanks in advance for any suggestions. > > > > > > > > > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >