Skip to content

Openblas?

5 messages · Göran Broström, Dirk Eddelbuettel

#
Hello,

I thought that I should try openblas when building a CRAN package 
containing lots of old (twentieth century) C-code with frequent calls to 
blas and lapack routines. I have the following options on my Ubuntu 
20.04 machine:

    Selection    Path                           Priority   Status
------------------------------------------------------------
* 0            openblas-pthread/libblas.so.3   100      auto mode
   1            blas/libblas.so.3               10      manual mode
   2            openblas-openmp/libblas.so.3    95      manual mode
   3            openblas-pthread/libblas.so.3   100     manual mode

I tried all four alternatives by timing one particular function call and 
got quite surprising (to me) results:

Selection        user   system elapsed
0               3.279    1.839   1.900
1               0.899    0.052   0.953
2             158.948    3.661  20.915
3               3.277    1.894   1.908

Comments on that? To me it seems clear that openblas (0, 2, 3) has 
nothing to offer me, as my C code stands now. Is the problem that 
openblas uses C versions of blas? I am using the Fortran version via

F77_CALL(name)

I tried adding

PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)

to src/Makevars, but then I got

...undefined symbol: dsytri_

when compiling.

G?ran
#
G?ran,

This is not an easy email to reply to because it _contains nothing
reproducible_.
On 15 July 2020 at 13:24, G?ran Brostr?m wrote:
| Hello,
| 
| I thought that I should try openblas when building a CRAN package 
| containing lots of old (twentieth century) C-code with frequent calls to 
| blas and lapack routines. I have the following options on my Ubuntu 
| 20.04 machine:
| 
|     Selection    Path                           Priority   Status
| ------------------------------------------------------------
| * 0            openblas-pthread/libblas.so.3   100      auto mode
|    1            blas/libblas.so.3               10      manual mode
|    2            openblas-openmp/libblas.so.3    95      manual mode
|    3            openblas-pthread/libblas.so.3   100     manual mode
| 
| I tried all four alternatives by timing one particular function call and 
| got quite surprising (to me) results:
| 
| Selection        user   system elapsed
| 0               3.279    1.839   1.900
| 1               0.899    0.052   0.953
| 2             158.948    3.661  20.915
| 3               3.277    1.894   1.908
| 
| Comments on that?

How could I comment?  I do not know what code you ran.

| To me it seems clear that openblas (0, 2, 3) has 
| nothing to offer me, as my C code stands now. Is the problem that 
| openblas uses C versions of blas? I am using the Fortran version via
| 
| F77_CALL(name)
| 
| I tried adding
| 
| PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
| PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)

This is missing LAPACK and BLAS so ...
| 
| to src/Makevars, but then I got
| 
| ...undefined symbol: dsytri_

... so get a _linker error_ about missing symbols.
 
| when compiling.

You meant linking, not compiling.

Dirk
#
On 2020-07-15 14:36, Dirk Eddelbuettel wrote:
Thanks Dirk,

Sorry about that, but my real question was (see below): "Is the problem 
that openblas uses C versions of blas?" That is, do I need to change

F77_CALL(name)(...);

to

cblas_name(...);

everywhere? And if so, is this really a good idea with old code?

I'll try to extract a reproducible example from the package (eha) where 
I run it.

G?ran
#
On 15 July 2020 at 16:13, G?ran Brostr?m wrote:
| On 2020-07-15 14:36, Dirk Eddelbuettel wrote:
| > 
| > G?ran,
| > 
| > This is not an easy email to reply to because it _contains nothing
| > reproducible_.
| 
| Thanks Dirk,
| 
| Sorry about that, but my real question was (see below): "Is the problem 
| that openblas uses C versions of blas?" That is, do I need to change
| 
| F77_CALL(name)(...);
| 
| to
| 
| cblas_name(...);
| 
| everywhere? And if so, is this really a good idea with old code?

I don't think so. At the end of the day it comes from "higher up" (say,
crossprod()) and is just passed down.

Remember, at the end it's all assembler :)

| I'll try to extract a reproducible example from the package (eha) where 
| I run it.

+1

Dirk
#
Here is the reproducible example (very educational ...):
----------------------------------------------------------
$ wget http://ehar.se/data/reex_0.1.1.tar.gz
$ R CMD INSTALL reex_0.1.1.tar.gz

{with "status = 1: blas/libblas.so.3, and lapack..}
$ R

 > library("reex")
 > system.time(res <- coxfunk(beta = 1, X = X, rs = rs, what = 2))
#   user  system elapsed
#  0.093   0.000   0.093

 > q()

{Change to "status 2; openmp/libblas.so.3", and lapack..}

$ R
 > library(reex)
 > system.time(res <- coxfunk(beta = 1, X = X, rs = rs, what = 2))
#   user  system elapsed
# 72.050   1.006   6.123
 >
 > system.time(res <- coxfunk(beta = 1, X = X, rs = rs, what = 1))
#   user  system elapsed
#  0.088   0.000   0.088
-----------------------------------------------------------
Comment:
## what = 1 calculates loglik and score, what = 2 in addition hessian
## "Extra" code when what = 2:

if (*what >= 2){ /* Second derivatives: */
     F77_CALL(dsyr)(&up, p, (wsc + i),
               (x + (*p) * i), &ione,
	      sumd2score, p FCONE);
}


and

if (*what >= 2){
     alpha = -alpha;
     F77_CALL(daxpy)(&p2, &alpha, sumd2score, &ione,
		    d2loglik, &ione);
     alpha = -alpha / sumscore;
     F77_CALL(dsyr)(&up, p, &alpha, sumdscore, &ione,
		   d2loglik, p FCONE);
}

Full C and R code in package.

G?ran
On 2020-07-15 16:32, Dirk Eddelbuettel wrote: