Dear all, I am currently trying to create a package wrapping Fortran90 code, the RRTMG radiative transfer model( http://rtweb.aer.com/rrtm_frame.html). I am doing this on a Linux workstation, with gcc/gfortran, in case this matters. The code heavily relies on F90 features, in particular modules, which seem to clash with R's assumptions for calling compiled code. What I have done: -compiled the files to mod/object files using gfortran -am able to create a dynamic link library "librrtmg.so" Further experiments: - dyn.load('librrtmg.so') works -. with "objdump -T librrtmg.so", I have found the following function symbols to call: 1. __rrtmg_lw_init_MOD_rrtmg_lw_ini (the initialization of the code) 2. __rrtmg_?w_rad_MOD_rrtmg_lw (the actual main function I want to call to do the calculations) - These symbols are found via "is.loaded", but only without specifying "type='FORTRAN'" (I have experimented with upper/lowercase letters as well as dropping the leading underscores) - I have not been able to call these routines via the ".Fortran" interface. - I do managed to call a simple F90 subroutine (with similar argument list, for experimentation) via the ".C" interface. However, I am not able to pass 2D field of type "DOUBLE", but always get a crash. Is there any official way for calling Fortran90 libraries which I missed (I have both searched through the documentation and this list)? Any advice how to go about this? My best idea at the moment seems to be to write a simple C wrapper for the Fortran routines, and call the wrapper from R. If needed, I can also post some code from my experiments. I'd actually like to get something which could be submitted to CRAN out of this (are there any other packages depending on Fortran90 code?) Thanks in advance for any help, Hartwig Deneke
Dear Hartwig, I think there are many packages that use F90 code and you should really be able to call it by following the advices in the R-exts manual. There are no major differences with F77 and you do not need a C wrapper. Maybe you might start with a simple example like this one. start file foo.f90 ******************* SUBROUTINE foo(X,M,N,S) IMPLICIT NONE integer:: M,N real*8:: X(M,N),S S = sum(X); END SUBROUTINE foo end file foo.f90 ******************* compile: gfortran -shared foo.f90 -o foo.so open R ************************ dyn.load("foo.so") is.loaded("foo") TRUE m <- matrix(1,nrow=4,ncol=3) storage.mode(m) <- "double" S <- double(1) .Fortran("foo",m,nrow(m),ncol(m),S) [[1]] [,1] [,2] [,3] [1,] 1 1 1 [2,] 1 1 1 [3,] 1 1 1 [4,] 1 1 1 [[2]] [1] 4 [[3]] [1] 3 [[4]] [1] 12 ciao Simone On Tue, Dec 29, 2009 at 10:26 AM, Hartwig Deneke <hartwig.deneke@gmail.com>wrote:> Dear all, > > I am currently trying to create a package wrapping Fortran90 code, the > RRTMG radiative transfer model( http://rtweb.aer.com/rrtm_frame.html). > I am doing this on a Linux workstation, with gcc/gfortran, in case > this matters. The code heavily relies on F90 features, in particular > modules, which seem to clash with R's assumptions for calling compiled > code. > > What I have done: > -compiled the files to mod/object files using gfortran > -am able to create a dynamic link library "librrtmg.so" > > Further experiments: > - dyn.load('librrtmg.so') works > -. with "objdump -T librrtmg.so", I have found the following function > symbols to call: > 1. __rrtmg_lw_init_MOD_rrtmg_lw_ini (the initialization of the code) > 2. __rrtmg_öw_rad_MOD_rrtmg_lw (the actual main function I want > to call to do the calculations) > - These symbols are found via "is.loaded", but only without specifying > "type='FORTRAN'" (I have experimented with upper/lowercase letters as > well as dropping the leading underscores) > - I have not been able to call these routines via the ".Fortran" interface. > - I do managed to call a simple F90 subroutine (with similar argument > list, for experimentation) via the ".C" interface. However, I am not > able to pass 2D field of type "DOUBLE", but always get a crash. > > Is there any official way for calling Fortran90 libraries which I > missed (I have both searched through the documentation and this list)? > Any advice how to go about this? My best idea at the moment seems to > be to write a simple C wrapper for the Fortran routines, and call the > wrapper from R. If needed, I can also post some code from my > experiments. I'd actually like to get something which could be > submitted to CRAN out of this (are there any other packages depending > on Fortran90 code?) > > Thanks in advance for any help, > Hartwig Deneke > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- ______________________________________________________ Simone Giannerini Dipartimento di Scienze Statistiche "Paolo Fortunati" Universita' di Bologna Via delle belle arti 41 - 40126 Bologna, ITALY Tel: +39 051 2098262 Fax: +39 051 232153 http://www2.stat.unibo.it/giannerini/ ______________________________________________________ [[alternative HTML version deleted]]
2009/12/29 Simone Giannerini <sgiannerini at gmail.com>:> Dear Hartwig, > > I think there are many packages that use F90 code and you should really be > able to call it by following the advices in the R-exts > manual. There are no major differences with F77 and you do not need a C > wrapper. Maybe you might start with a simple example like this one. >....(helpful example removed)...> open R ************************ > dyn.load("foo.so") > is.loaded("foo") > > TRUEDear Simone (and others reading), first of all thanks for your helpful example. While I did something similar yesterday, it did give me a simple example to start from which worked, and find a nice approach to solving my problems. A brief summary of the origin of my problems, which are related to the use of Fortran90 module declarations. It is perfectly possible to call Fortran90 code compiled with gfortran. Compiling a subroutine/function "foo" will produce a symbol "foo_" in the dynamic library. If, however, the subroutine is contained in a module named "modname", the symbol will be called "__modname_MOD_foo". In this case, it will not be found by the ".Fortran" call or a call to "is.loaded", at least I have not found any way to do this. However, for my purposes, I have simply added a set of wrapper subroutines to the library (which I planned to add anyway for other reasons, in particular to reduce the number of arguments), which forwards the calls to the module functions, and everything seems to work all right. Kind Regards, Hartwig