[R-pkg-devel] R, BLAS, and FCLEN (solved, really!)

Göran Broström gor@n@bro@trom @end|ng |rom umu@@e
Fri Sep 13 14:50:36 CEST 2019



On 2019-09-13 12:34, Göran Broström wrote:
> Dear Tomas,
> 
> your explanation matches exactly my expectation, but not my experience. 
> I uploaded (to CRAN) version 2.7.5 yesterday, and there I use, in  the 
> Fortran function gmlfun, directly called by .Fortran:
> 
>        call cdgemv(trans, nn, antcov, one, covar, nn, beta, ione, one,
>       &     score, ione)
> 
> that is, the C wrapper of dgemv (my home-brew)
> 
> No warnings from R-devel CMD check --as-cran, and when installed it runs 
> fine.
> 
> However, if I change that call to
> 
>         call dgemv(trans, nn, antcov, one, covar, nn, beta, ione, one,
>       &     score, ione)
> 
> that is, a direct call to the Fortran subroutine dgemv, I get, from 
> R-devel CMD check --as-cran,
> 
> gmlfun.f:224:1: warning: type of ‘dgemv’ does not match original 
> declaration [-Wlto-type-mismatch]
>        &     score, ione)
>   ^
> /home/gobr0002/R/src/R-devel/include/R_ext/BLAS.h:107:1: note: type 
> mismatch in parameter 12
>   F77_NAME(dgemv)(const char *trans, const int *m, const int *n,
>   ^

This error message was triggered by my mistake in the change from cdgemv 
to dgemv: I forgot to change 'trans' back from type INTEGER to 
CHARACTER. Our final conclusion (for now) is then:

Yes, you can call BLAS subroutines directly from Fortran code, even in 
packages! Many thanks to Tomas!

Excuse my confusion,

G,

> 
> and when I install and run, I get error:
> 
>  > library(eha)
> Loading required package: survival
>  > fit <- coxreg(Surv(enter, exit, event) ~ ses, data = mort, geometric 
> = TRUE)
> Error in geome.fit(X, Y, rs, strats, offset, init, max.survs, method,  :
>    BLAS/LAPACK routine 'DGEMV ' gave error code -1
>  >
>  > sessionInfo()
> R version 3.6.1 (2019-07-05)
> Platform: x86_64-pc-linux-gnu (64-bit)
> Running under: Ubuntu 19.04
> ...
> Matrix products: default
> BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.8.0
> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.8.0
> ...
> Other attached packages:
> [1] eha_2.7.5.1000    survival_2.44-1.1
> -------------
> 
> To summarize: The calls from C code are fixed and work fine. Direct call 
> from fortran "level 1" gives error, from "level 2" is fine. "level 1" is 
> fortran code directly called by .Fortran, "level 2" is fortran code 
> called from fortran code called by .Fortran.
> 
> This was done with
> 
> R Under development (unstable) (2019-08-31 r77115). I could try a more 
> recent version of R-devel.
> 
> About a 'small reproducible example': It is not that easy to shrink the 
> eha package to include only the relevant fortran code, since there are 
> subtle interdependencies in the package code. It would take a 
> considerable amount of time (for me) to create that package.
> I can make eha_2.7.5.tar.gz available, but it was sent in to CRAN 
> yesterday.
> 
> Göran
> 
> On 2019-09-13 11:07, Tomas Kalibera wrote:
>> Dear Göran,
>>
>> I can reproduce the problem with eha version 2.6.0. The reason for the 
>> type mismatch, and hence the LTO warning, is _not_ the calls to dgemv 
>> from Fortran code, but the calls to dgemv from the C code from the 
>> other source files in your package. There is no need to go through 
>> wrappers when calling dgemv from Fortran (as long as both modules are 
>> compiled with the same compiler, or with compatible compilers).
>>
>> When you fix all the calls to dgemv in your C source files to use 
>> "FCONE", as documented in WRE, the warning about the call to dgemv 
>> from geomsup.f will go away (yes, the warnings from the LTO 
>> linker/compiler are confusing). There is no need for creating any 
>> wrappers for BLAS/LAPACK calls.
>>
>> One can check that the generated calls from the Fortran are correct 
>> e.g. via compiling with -fdump-tree-all and then dumping
>> $ egrep -e '(^;;)|(dgemv)' eha.so.ltrans0.232t.optimized | grep dgemv -B1
>> (the file name above will depend on the exact version of your compiler)
>>
>> ;; Function d2_loglik_ph (d2_loglik_ph, funcdef_no=77, decl_uid=4474, 
>> cgraph_uid=103, symbol_order=990)
>>    dgemv_ (&trans, mb_497(D), nn_499(D), &alf, z_502(D), mb_497(D), 
>> b_503(D), &one, &Rf_beta, ezb_501, &one);
>> -- 
>> ;; Function d2_loglik_phexp (d2_loglik_phexp, funcdef_no=87, 
>> decl_uid=4470, cgraph_uid=100, symbol_order=1108)
>>    dgemv_ (&trans, mb_253(D), nn_255(D), &alf, z_258(D), mb_253(D), 
>> b_259(D), &one, &Rf_beta, ezb_257, &one);
>> -- 
>> ;; Function gmlfun (gmlfun_, funcdef_no=98, decl_uid=4484, 
>> cgraph_uid=108, symbol_order=874)
>>    dgemv_ (&"N"[1]{lb: 1 sz: 1}, nn_68(D), antcov_63(D), &C.7966, 
>> covar_83(D), nn_68(D), beta_84(D), &C.7965, &C.7964, score_81(D), 
>> &C.7963, 1);
>> -- 
>> ;; Function geomsup (geomsup_, funcdef_no=116, decl_uid=4498, 
>> cgraph_uid=117, symbol_order=823)
>>    dgemv_ (&"N"[1]{lb: 1 sz: 1}, nn_55(D), antcov_51(D), &C.9626, 
>> covar_89(D), nn_55(D), startbeta_83(D), &C.9625, &C.9624, score_87(D), 
>> &C.9623, 1);
>> -- 
>> ;; Function sup (sup, funcdef_no=128, decl_uid=4335, cgraph_uid=7, 
>> symbol_order=1772)
>>    dgemv_ (&trans, &nn, &p, &one, covar_281(D), &nn, beta_340(D), 
>> &ione, &one, score_230, &ione);
>>
>> You can see that the calls to dgemv from gmlfun and geomsup are fine 
>> (from Fortran code), the other are bad (from C code).  Indeed, one 
>> would have found out also by creating a minimal reproducible example - 
>> it is always useful, even when not attempting to report a bug.
>>
>> Best
>> Tomas
>>
>> On 9/13/19 12:07 AM, Göran Broström wrote:
>>>
>>>
>>> On 2019-09-12 09:13, Martin Maechler wrote:
>>>>>>>>> Göran Broström
>>>>>>>>>      on Wed, 11 Sep 2019 13:36:40 +0200 writes:
>>>>
>>>>      > A followup question: Is it possible to call a BLAS/LAPACK 
>>>> subroutine,
>>>>      > where one parameter is character, from FORTRAN (77) code 
>>>> called by
>>>>      > .Fortran? (No problem "in the past".)
>>>>
>>>> [as there wasn't a reply till now : ]
>>>>
>>>> Yes, that should continue to be possible.
>>>>
>>>>      > And if yes, how?
>>>>
>>>> I'm sorry I don't know (and currently lack the time to try to find 
>>>> out)...
>>>
>>> I solved it by writing a C wrapper (for the BLAS subroutine dgemv) 
>>> cdgemv:
>>>
>>> #define USE_FC_LEN_T
>>> #include <Rconfig.h>
>>> #include <R_ext/BLAS.h>
>>> #ifndef FCONE
>>> # define FCONE
>>> #endif
>>> #include <R.h>
>>> #include "cdgemv.h"
>>>
>>> void F77_SUB(cdgemv)(const int *trans, const int *m, const int *n,
>>>              const double *alpha, const double *a,
>>>                      const int *lda,
>>>              const double *x, const int *incx,
>>>                      const double *beta,
>>>              double *y, const int *incy){
>>>    char trams;
>>>
>>>    if (*trans == 1){
>>>       trams = 'N';
>>>       F77_CALL(dgemv)(&trams, m, n, alpha, a, lda, x, incx, beta, y,
>>>                       incy FCONE);
>>>    }else
>>>       Rprintf("trans has wrong value\n");
>>>    }
>>> }
>>>
>>> which I call from Fortran. Curiously, a Fortran wrapper also seems to 
>>> work.
>>>
>>> G,
>>>>
>>>> Martin
>>>>
>>>>      >   Documentation describes calls from C to Fortran and
>>>>      > vice versa, but not this situation (AFAICS).
>>>>
>>>>      > Yes, I know that .Fortran is not well seen these days, but my 
>>>> fortran
>>>>      > code is ancient, from the before-R era, and I would like to 
>>>> leave it as-is.
>>>>
>>>>      > G,
>>>>
>>>>      > Den 2019-09-01 kl. 21:46, skrev Göran Broström:
>>>>      >>
>>>>      >>
>>>>      >> On 2019-08-31 18:47, Göran Broström wrote:
>>>>      >>> I'm having difficulties updating my package eha: When I run 
>>>> standard
>>>>      >>> checks 'at home' everything is fine, but 'CRAN-submissions' 
>>>> reports
>>>>      >>> (among other things):
>>>>      >>>
>>>>      >>> geomsup.f:324:9: warning: type of ‘dgemv’ does not match 
>>>> original
>>>>      >>> declaration [-Wlto-type-mismatch]
>>>>      >>>    324 |      &     one, score, ione)
>>>>      >>>        |         ^
>>>>      >>> /home/tmp/R-d-gcc-LTO/include/R_ext/BLAS.h:107:1: note: 
>>>> type mismatch
>>>>      >>> in parameter 12
>>>>      >>>    107 | F77_NAME(dgemv)(const char *trans, const int *m, 
>>>> const int *n,
>>>>      >>>        | ^
>>>>      >>>
>>>>      >>> This is odd since the LAPACK subroutine dgemv takes only 11
>>>>      >>> parameters. However, in include/R_ext/BLAS.h we have
>>>>      >>>
>>>>      >>> F77_NAME(dgemv)(const char *trans, const int *m, const int *n,
>>>>      >>>          const double *alpha, const double *a, const int *lda,
>>>>      >>>          const double *x, const int *incx, const double *beta,
>>>>      >>>          double *y, const int *incy FCLEN);
>>>>      >>>
>>>>      >>> with a 12th parameter FCLEN?? How am I supposed to fix 
>>>> this, and what
>>>>      >>> the ... is FCLEN? googling leads to nothing useful (for 
>>>> me). It seems
>>>>      >>> as if R is redefining some standard LAPACK routines.
>>>>      >>>
>>>>      >>> Also a note I do not understand (in this context):
>>>>      >>>
>>>>      >>> note: type ‘void’ should match type ‘long int’
>>>>      >>>
>>>>      >>> Any help is much appreciated.
>>>>      >>>
>>>>      >>> Best, Göran
>>>>      >>>
>>>>      >>> PS. How can I trigger these Warnings 'at home'?
>>>>      >>
>>>>      >> See https://www.stats.ox.ac.uk/pub/bdr/LTO/README.txt 
>>>> (thanks to Uwe
>>>>      >> Ligges).
>>>>      >>
>>>>      >> Another relevant document seems to be (2019-05-15):
>>>>      >>
>>>>      >> 
>>>> https://developer.r-project.org/Blog/public/2019/05/15/gfortran-issues-with-lapack/index.html 
>>>>
>>>>      >>
>>>>      >>
>>>>      >> First sentence:
>>>>      >> "Recent version of the GNU Fortran compiler (7, 8, 9) include
>>>>      >> optimizations that break interoperability between C and 
>>>> Fortran code
>>>>      >> with BLAS/LAPACK."
>>>>      >>
>>>>      >> And later:
>>>>      >> "For the time being, everyone should use 
>>>> -fno-optimize-sibling-calls
>>>>      >> with GFortran version 7 and newer."
>>>>      >>
>>>>      >> G,
>>>>      >>
>>>>      >>> ______________________________________________
>>>>      >>> R-package-devel using r-project.org mailing list
>>>>      >>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>>      >>
>>>>      >> ______________________________________________
>>>>      >> R-package-devel using r-project.org mailing list
>>>>      >> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>>
>>>>      > ______________________________________________
>>>>      > R-package-devel using r-project.org mailing list
>>>>      > https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>>
>>>
>>> ______________________________________________
>>> R-package-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>
>>
> 
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel



More information about the R-package-devel mailing list