Re: [Rd] Calling a LAPACK subroutine from R

2019-09-12 Thread Göran Broström
Thanks Berend, I got curious and checked your package, and no errors. 
However, two open questions:


1. You invoke the call to dgemv from a Fortran subroutine  that is 
called from a C function, which in turn is called in R by .Call. I go 
directly via .Fortran, no C involved, except by "base R", see 2. below.


2. I am still wondering why your route gets away with avoiding "the 12th 
hidden argument" FCLEN, see R-devel/include/R_ext/BLAS.h:


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);

when my direct route doesn't?

Göran

On 2019-09-12 09:15, Berend Hasselman wrote:

Followup:

I have checked my package nleqslv which uses dgemv only from Fortran, on 
Kubuntu 18.04 with the development version of R.
No errors or problems.

Berend



On 12 Sep 2019, at 08:57, Berend Hasselman  wrote:


I have tried what I proposed in a virtual Kubuntu 18.04 which uses gfortran 7.4.
I used the latest development version of R.

It worked just as on macOS.

Berend



On 11 Sep 2019, at 22:07, Göran Broström  wrote:

Berend,

I do not think this works with gfortran 7+. I am calling the BLAS subroutine 
dgemv from Fortran code in my package eha, and the check (with R-devel) gives:

gmlfun.f:223: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,

Type of a Fortran subroutine is matched against type of a C function?! My 
conclusion is that it is impossible to call a BLAS subroutine with a character 
parameter from Fortran code (nowadays). Calling from C code is fine, on the 
other hand(!).

I have recently asked about this on R-pkg-devel, but not received any useful 
answers, and my submission to CRAN is rejected. I solve it by making a personal 
copy of dgemv and changing the character parameter to integer, and adding Jack 
Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard Hanson as authors of 
eha. And a Copyright note, all in the DESCRIPTION file. Ugly but what can I do 
(except rewriting the Fortran code in C with f2c)?

Göran

On 2019-09-11 21:38, Berend Hasselman wrote:

The Lapack library is loaded automatically by R itself when it needs it  for 
doing some calculation.
You can force it to do that with a (dummy) solve for example.
Put this at start of your script:

# dummy code to get LAPACK library loaded
X1 <- diag(2,2)
x1 <- rep(2,2)
# X1;x1
z <- solve(X1,x1)

followed by the rest of your script.
You will get a warning (I do) that  "passing a character vector  to .Fortran is not 
portable".
On other systems this may gave fatal errors. This is quick and very dirty. 
Don't do it.
I believe there is a better and much safer way to achieve what you want.
Here goes.
Create a folder (directory) src in the directory where your script resides.
Create a wrapper for "dpbtrf" file in a file xdpbtrf.f that takes an integer 
instead of character

c intermediate for dpbtrf
  SUBROUTINE xDPBTRF( kUPLO, N, KD, AB, LDAB, INFO )
c  .. Scalar Arguments ..
  integer kUPLO
  INTEGER INFO, KD, LDAB, N
c  .. Array Arguments ..
  DOUBLE PRECISION   AB( LDAB, * )
  character UPLO
c convert integer argument to character
  if(kUPLO .eq. 1 ) then
  UPLO = 'L'
  else
  UPLO = 'U'
  endif
  call dpbtrf(UPLO,N,KD,AB,LDAB,INFO)
  return
  end

Instead of a character argument UPLO it takes an integer argument kUPLO.
The meaning should be obvious from the code.
Now create a shell script in the folder of your script to generate a dynamic 
library to be loaded in your script:

# Build a binary dynamic library for accessing Lapack dpbtrf
# syntax checking
SONAME=xdpbtrf.so
echo Strict syntax checking
echo --
gfortran -c -fsyntax-only -fimplicit-none -Wall src/*.f || exit 1
LAPACK=$(R CMD config LAPACK_LIBS)
R CMD SHLIB --output=${SONAME} src/*.f ${LAPACK} || exit 1

To load the dynamic library xdpbtrf.so  change your script into this

dyn.load("xdpbtrf.so")
n <- 4L
phi <- 0.64
AB <- matrix(0, 2, n)
AB[1, ] <- c(1, rep(1 + phi^2, n-2), 1)
AB[2, -n] <- -phi
round(AB, 3)
AB.ch <- .Fortran("xdpbtrf", kUPLO=1L, N = as.integer(n),
KD = 1L, AB = AB, LDAB = 2L, INFO = 
as.integer(0))$AB
AB.ch

and you are good to go.
You should always do something  as described above when you need to pass 
character arguments to Fortran code.
All of this was tested and run on macOS using the CRAN version of R.
Berend Hasselman

On 11 Sep 2019, at 15:47, Giovanni Petris  wrote:

Sorry for cross-posting, but I realized my question might be more appropriate 
for r-devel...

Thank you,
Giovanni

_

Re: [Rd] Calling a LAPACK subroutine from R

2019-09-12 Thread Berend Hasselman
Followup:

I have checked my package nleqslv which uses dgemv only from Fortran, on 
Kubuntu 18.04 with the development version of R.
No errors or problems.

Berend


> On 12 Sep 2019, at 08:57, Berend Hasselman  wrote:
> 
> 
> I have tried what I proposed in a virtual Kubuntu 18.04 which uses gfortran 
> 7.4.
> I used the latest development version of R.
> 
> It worked just as on macOS.
> 
> Berend
> 
> 
>> On 11 Sep 2019, at 22:07, Göran Broström  wrote:
>> 
>> Berend,
>> 
>> I do not think this works with gfortran 7+. I am calling the BLAS subroutine 
>> dgemv from Fortran code in my package eha, and the check (with R-devel) 
>> gives:
>> 
>> gmlfun.f:223: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,
>> 
>> Type of a Fortran subroutine is matched against type of a C function?! My 
>> conclusion is that it is impossible to call a BLAS subroutine with a 
>> character parameter from Fortran code (nowadays). Calling from C code is 
>> fine, on the other hand(!).
>> 
>> I have recently asked about this on R-pkg-devel, but not received any useful 
>> answers, and my submission to CRAN is rejected. I solve it by making a 
>> personal copy of dgemv and changing the character parameter to integer, and 
>> adding Jack Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard Hanson as 
>> authors of eha. And a Copyright note, all in the DESCRIPTION file. Ugly but 
>> what can I do (except rewriting the Fortran code in C with f2c)?
>> 
>> Göran
>> 
>> On 2019-09-11 21:38, Berend Hasselman wrote:
>>> The Lapack library is loaded automatically by R itself when it needs it  
>>> for doing some calculation.
>>> You can force it to do that with a (dummy) solve for example.
>>> Put this at start of your script:
>>> 
>>> # dummy code to get LAPACK library loaded
>>> X1 <- diag(2,2)
>>> x1 <- rep(2,2)
>>> # X1;x1
>>> z <- solve(X1,x1)
>>> 
>>> followed by the rest of your script.
>>> You will get a warning (I do) that  "passing a character vector  to 
>>> .Fortran is not portable".
>>> On other systems this may gave fatal errors. This is quick and very dirty. 
>>> Don't do it.
>>> I believe there is a better and much safer way to achieve what you want.
>>> Here goes.
>>> Create a folder (directory) src in the directory where your script resides.
>>> Create a wrapper for "dpbtrf" file in a file xdpbtrf.f that takes an 
>>> integer instead of character
>>> 
>>> c intermediate for dpbtrf
>>>  SUBROUTINE xDPBTRF( kUPLO, N, KD, AB, LDAB, INFO )
>>> c  .. Scalar Arguments ..
>>>  integer kUPLO
>>>  INTEGER INFO, KD, LDAB, N
>>> c  .. Array Arguments ..
>>>  DOUBLE PRECISION   AB( LDAB, * )
>>>  character UPLO
>>> c convert integer argument to character
>>>  if(kUPLO .eq. 1 ) then
>>>  UPLO = 'L'
>>>  else
>>>  UPLO = 'U'
>>>  endif
>>>  call dpbtrf(UPLO,N,KD,AB,LDAB,INFO)
>>>  return
>>>  end
>>> 
>>> Instead of a character argument UPLO it takes an integer argument kUPLO.
>>> The meaning should be obvious from the code.
>>> Now create a shell script in the folder of your script to generate a 
>>> dynamic library to be loaded in your script:
>>> 
>>> # Build a binary dynamic library for accessing Lapack dpbtrf
>>> # syntax checking
>>> SONAME=xdpbtrf.so
>>> echo Strict syntax checking
>>> echo --
>>> gfortran -c -fsyntax-only -fimplicit-none -Wall src/*.f || exit 1
>>> LAPACK=$(R CMD config LAPACK_LIBS)
>>> R CMD SHLIB --output=${SONAME} src/*.f ${LAPACK} || exit 1
>>> 
>>> To load the dynamic library xdpbtrf.so  change your script into this
>>> 
>>> dyn.load("xdpbtrf.so")
>>> n <- 4L
>>> phi <- 0.64
>>> AB <- matrix(0, 2, n)
>>> AB[1, ] <- c(1, rep(1 + phi^2, n-2), 1)
>>> AB[2, -n] <- -phi
>>> round(AB, 3)
>>> AB.ch <- .Fortran("xdpbtrf", kUPLO=1L, N = as.integer(n),
>>>KD = 1L, AB = AB, LDAB = 2L, INFO = 
>>> as.integer(0))$AB
>>> AB.ch
>>> 
>>> and you are good to go.
>>> You should always do something  as described above when you need to pass 
>>> character arguments to Fortran code.
>>> All of this was tested and run on macOS using the CRAN version of R.
>>> Berend Hasselman
 On 11 Sep 2019, at 15:47, Giovanni Petris  wrote:
 
 Sorry for cross-posting, but I realized my question might be more 
 appropriate for r-devel...
 
 Thank you,
 Giovanni
 
 
 From: R-help  on behalf of Giovanni Petris 
 
 Sent: Tuesday, September 10, 2019 16:44
 To: r-h...@r-project.org
 Subject: [R] Calling a LAPACK subroutine from R
 
 Hello R-helpers!
 
 I am trying to call a LAPACK subroutine directly from my R code using 
 .Fortran(), but R cannot find the symbol name

Re: [Rd] Calling a LAPACK subroutine from R

2019-09-11 Thread Berend Hasselman


I have tried what I proposed in a virtual Kubuntu 18.04 which uses gfortran 7.4.
I used the latest development version of R.

It worked just as on macOS.

Berend


> On 11 Sep 2019, at 22:07, Göran Broström  wrote:
> 
> Berend,
> 
> I do not think this works with gfortran 7+. I am calling the BLAS subroutine 
> dgemv from Fortran code in my package eha, and the check (with R-devel) gives:
> 
> gmlfun.f:223: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,
> 
> Type of a Fortran subroutine is matched against type of a C function?! My 
> conclusion is that it is impossible to call a BLAS subroutine with a 
> character parameter from Fortran code (nowadays). Calling from C code is 
> fine, on the other hand(!).
> 
> I have recently asked about this on R-pkg-devel, but not received any useful 
> answers, and my submission to CRAN is rejected. I solve it by making a 
> personal copy of dgemv and changing the character parameter to integer, and 
> adding Jack Dongarra, Jeremy Du Croz, Sven Hammarling, and Richard Hanson as 
> authors of eha. And a Copyright note, all in the DESCRIPTION file. Ugly but 
> what can I do (except rewriting the Fortran code in C with f2c)?
> 
> Göran
> 
> On 2019-09-11 21:38, Berend Hasselman wrote:
>> The Lapack library is loaded automatically by R itself when it needs it  for 
>> doing some calculation.
>> You can force it to do that with a (dummy) solve for example.
>> Put this at start of your script:
>> 
>> # dummy code to get LAPACK library loaded
>> X1 <- diag(2,2)
>> x1 <- rep(2,2)
>> # X1;x1
>> z <- solve(X1,x1)
>> 
>> followed by the rest of your script.
>> You will get a warning (I do) that  "passing a character vector  to .Fortran 
>> is not portable".
>> On other systems this may gave fatal errors. This is quick and very dirty. 
>> Don't do it.
>> I believe there is a better and much safer way to achieve what you want.
>> Here goes.
>> Create a folder (directory) src in the directory where your script resides.
>> Create a wrapper for "dpbtrf" file in a file xdpbtrf.f that takes an integer 
>> instead of character
>> 
>> c intermediate for dpbtrf
>>   SUBROUTINE xDPBTRF( kUPLO, N, KD, AB, LDAB, INFO )
>> c  .. Scalar Arguments ..
>>   integer kUPLO
>>   INTEGER INFO, KD, LDAB, N
>> c  .. Array Arguments ..
>>   DOUBLE PRECISION   AB( LDAB, * )
>>   character UPLO
>> c convert integer argument to character
>>   if(kUPLO .eq. 1 ) then
>>   UPLO = 'L'
>>   else
>>   UPLO = 'U'
>>   endif
>>   call dpbtrf(UPLO,N,KD,AB,LDAB,INFO)
>>   return
>>   end
>> 
>> Instead of a character argument UPLO it takes an integer argument kUPLO.
>> The meaning should be obvious from the code.
>> Now create a shell script in the folder of your script to generate a dynamic 
>> library to be loaded in your script:
>> 
>> # Build a binary dynamic library for accessing Lapack dpbtrf
>> # syntax checking
>>  SONAME=xdpbtrf.so
>> echo Strict syntax checking
>> echo --
>> gfortran -c -fsyntax-only -fimplicit-none -Wall src/*.f || exit 1
>> LAPACK=$(R CMD config LAPACK_LIBS)
>> R CMD SHLIB --output=${SONAME} src/*.f ${LAPACK} || exit 1
>> 
>> To load the dynamic library xdpbtrf.so  change your script into this
>> 
>> dyn.load("xdpbtrf.so")
>> n <- 4L
>> phi <- 0.64
>> AB <- matrix(0, 2, n)
>> AB[1, ] <- c(1, rep(1 + phi^2, n-2), 1)
>> AB[2, -n] <- -phi
>> round(AB, 3)
>> AB.ch <- .Fortran("xdpbtrf", kUPLO=1L, N = as.integer(n),
>> KD = 1L, AB = AB, LDAB = 2L, INFO = 
>> as.integer(0))$AB
>> AB.ch
>> 
>> and you are good to go.
>> You should always do something  as described above when you need to pass 
>> character arguments to Fortran code.
>> All of this was tested and run on macOS using the CRAN version of R.
>> Berend Hasselman
>>> On 11 Sep 2019, at 15:47, Giovanni Petris  wrote:
>>> 
>>> Sorry for cross-posting, but I realized my question might be more 
>>> appropriate for r-devel...
>>> 
>>> Thank you,
>>> Giovanni
>>> 
>>> 
>>> From: R-help  on behalf of Giovanni Petris 
>>> 
>>> Sent: Tuesday, September 10, 2019 16:44
>>> To: r-h...@r-project.org
>>> Subject: [R] Calling a LAPACK subroutine from R
>>> 
>>> Hello R-helpers!
>>> 
>>> I am trying to call a LAPACK subroutine directly from my R code using 
>>> .Fortran(), but R cannot find the symbol name. How can I register/load the 
>>> appropriate library?
>>> 
 ### AR(1) Precision matrix
 n <- 4L
 phi <- 0.64
 AB <- matrix(0, 2, n)
 AB[1, ] <- c(1, rep(1 + phi^2, n-2), 1)
 AB[2, -n] <- -phi
 round(AB, 3)
>>>  [,1]  [,2]  [,3] [,4]
>>> [1,]  1.00  1.41  1.411
>>> [2,] -0.64 -0.64 -0.640
 
 ### Cholesk