sethrfore / homebrew-r-srf

Custom Homebrew R formula with tcl-tk support and additional options
59 stars 15 forks source link

Openblas seems not to be linked in R under MacOS big sur #35

Closed AlfredSAM closed 3 years ago

AlfredSAM commented 3 years ago

Hello, I just follow the instructions in https://www.btskinner.io/code/install-r-with-openblas-and-openmp-on-macos-mojave/ to install R in homebrew to have more capabilities. My main purpose is to employ optimized BLAS and LAPACK in matrix computation in R, and openblas is a good choice. After installation following the instructions above, I find

r$> capabilities()
       jpeg         png        tiff       tcltk         X11        aqua
       TRUE        TRUE        TRUE       FALSE        TRUE        TRUE
   http/ftp     sockets      libxml        fifo      cledit       iconv
       TRUE        TRUE        TRUE        TRUE       FALSE        TRUE
        NLS     profmem       cairo         ICU long.double     libcurl
       TRUE        TRUE        TRUE        TRUE        TRUE        TRUE

Furthermore,

r$> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-apple-darwin20.1.0 (64-bit)
Running under: macOS Big Sur 10.16

Matrix products: default
BLAS:   /usr/local/Cellar/r/4.0.3/lib/R/lib/libRblas.dylib
LAPACK: /usr/local/Cellar/r/4.0.3/lib/R/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] compiler_4.0.3

It seems that the matrix computation is still linked to the default ones but not openblas. Could you please give some advice?

Thanks in advance!

Best, Alfred

sethrfore commented 3 years ago

Well, I'm not exactly sure what's going on with openblas being unlinked. However, it is easy to manually link it after compiling R via:

ln -sf /usr/local/opt/openblas/lib/libopenblas.dylib /usr/local/opt/r/lib/libRblas.dylib

This should provide you with a temporary solution until things get sorted. If it doesn't check back...

AlfredSAM commented 3 years ago

@sethrfore Thanks for your advice, and I just revise the command a bit to adapt to the location of file:

cd /usr/local/Cellar/r/4.0.3/lib/R/lib/
ln -sf /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib libRblas.dylib

Now the output of sessionInfo() in R:

R version 4.0.3 (2020-10-10)
Platform: x86_64-apple-darwin20.1.0 (64-bit)
Running under: macOS Big Sur 10.16

Matrix products: default
BLAS:   /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib
LAPACK: /usr/local/Cellar/r/4.0.3/lib/R/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] compiler_4.0.3 tools_4.0.3

I run the following test codes in R

library(microbenchmark)
d <- 1e3
x <- matrix(rnorm(d^2), d, d)
microbenchmark(tcrossprod(x), solve(x), svd(x), times = 10L)

With the default blas dylib, I get

Unit: milliseconds
          expr       min        lq      mean    median       uq      max
 tcrossprod(x)  387.7482  389.5427  487.9902  396.1272  398.417 1335.200
      solve(x)  694.0954  701.7495 1057.1447  705.9870 1876.158 1879.456
        svd(x) 3337.0319 3343.8298 3912.0627 3393.3246 3404.419 8703.339
 neval
    10
    10
    10

With openblas the process is speeded up

Unit: milliseconds
          expr        min        lq      mean    median        uq
 tcrossprod(x)   9.687316  10.39118  11.71318  11.05980  13.15659
      solve(x)  46.651533  48.17120  50.51495  50.49237  52.31853
        svd(x) 478.638765 480.78752 493.92534 494.66471 500.32174
      max neval
  14.2844    10
  55.2037    10
 522.1357    10

I am still not quite sure why the installation process cannot link the openblas, but I find the following symbolic lnks in my openblas folder:

</openblas/0.3.12_1/lib/
cmake/
pkgconfig/
libblas.dylib -> /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib
liblapack.dylib -> /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib
libopenblas.0.dylib -> /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib
libopenblas.a -> /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.a [RO]
libopenblas.dylib -> /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib
libopenblasp-r0.3.12.a [RO]
libopenblasp-r0.3.12.dylib

Therefore, I just need to link libopenblasp-r0.3.12.dylib to the corresponding R blas dylib file.

One more question, if I also hope to link the optimized lapack to libRlapack.dylib, how could I do so? You know, openblas does not provide the optimized lapack. Could you have any advice?

On the other hand, after upgrading to big sur I find the optimized built-in blas/lapack disappear, which should be in

/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Versions/Current/libBLAS.dylib
/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Versions/Current/libLAPACK.dylib

This is the key reason why I need to find another optimized packages to boost matrix computation in R.

Thanks so much for your advice and your project!

sethrfore commented 3 years ago

Short answer is, I'm not sure why openblas is not being linked and I've no idea what's going on with Accelerate.Framework. Quite a bit of stuff has changed with Big Sur and it is not currently supported by Homebrew for a variety of reasons. I suspect these issues relate to whatever is going on there. My best suggestion remains manually linking openblas as indicated previously and with regard to lapack, I've no idea. I'm always open to suggestions, though! I'm sure some of this stuff will get straightened out with time. But in the short term, I'm sorry but I've got no further insights for you.

AlfredSAM commented 3 years ago

Thanks so much for your advice! Thanks to your great job, I can still employ high-speed computation in the new system. I will also keep exploring the new system, and share with you the information if I make progress. Thanks so much again!

sethrfore commented 3 years ago

No problem, always glad to help in whatever way I can! Keep me posted if you find a solution to the problem... I'll be happy to merge it into the master formula. Good luck!

AlfredSAM commented 3 years ago

Sure, have a good day!

rileytwo commented 3 years ago

I think this may be the reason for the accelerate dylibs not being present:

New in macOS Big Sur 11 beta, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. (62986286)

edit: I should note that I only know enough about linkers in macOS (or any system, really) to know that I don't know anything. I've found a post on hacker news and a pull request urllib3 repo that suggest the changes in Big Sur only affect how shared libraries are read.

sethrfore commented 3 years ago

Is this what the desired output of sessionInfo() should look like:

Platform: x86_64-apple-darwin20.1.0 (64-bit)
Running under: macOS Big Sur 11.0.1

Matrix products: default
BLAS/LAPACK: /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] SuppDists_1.1-9.5 Matrix_1.2-18     devtools_2.3.2    usethis_1.6.3    

loaded via a namespace (and not attached):
 [1] magrittr_2.0.1    pkgload_1.1.0     lattice_0.20-41   R6_2.5.0         
 [5] rlang_0.4.8       fansi_0.4.1       tools_4.0.3       pkgbuild_1.1.0   
 [9] grid_4.0.3        sessioninfo_1.1.1 cli_2.2.0         withr_2.3.0      
[13] ellipsis_0.3.1    remotes_2.2.0     assertthat_0.2.1  digest_0.6.27    
[17] rprojroot_2.0.2   crayon_1.3.4      processx_3.4.4    callr_3.5.1      
[21] fs_1.5.0          ps_1.4.0          testthat_3.0.0    memoise_1.1.0    
[25] glue_1.4.2        compiler_4.0.3    desc_1.2.0        prettyunits_1.1.1

If so, a solution is appending -lopenblas to line 77 so that it reads:

ENV.append "LDFLAGS", "-L#{Formula["openblas"].opt_lib} -lopenblas"

I've already compiled and benchtested R with this edit and everything seems to work fine. However, before I merge this into master, I want confirmation this is what the desired output should be.

sethrfore commented 3 years ago

I've also created a temporary branch dev-openblas-bigsur that implements these changes for testing.

AlfredSAM commented 3 years ago

Is this what the desired output of sessionInfo() should look like:

Platform: x86_64-apple-darwin20.1.0 (64-bit)
Running under: macOS Big Sur 11.0.1

Matrix products: default
BLAS/LAPACK: /usr/local/Cellar/openblas/0.3.12_1/lib/libopenblasp-r0.3.12.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] SuppDists_1.1-9.5 Matrix_1.2-18     devtools_2.3.2    usethis_1.6.3    

loaded via a namespace (and not attached):
 [1] magrittr_2.0.1    pkgload_1.1.0     lattice_0.20-41   R6_2.5.0         
 [5] rlang_0.4.8       fansi_0.4.1       tools_4.0.3       pkgbuild_1.1.0   
 [9] grid_4.0.3        sessioninfo_1.1.1 cli_2.2.0         withr_2.3.0      
[13] ellipsis_0.3.1    remotes_2.2.0     assertthat_0.2.1  digest_0.6.27    
[17] rprojroot_2.0.2   crayon_1.3.4      processx_3.4.4    callr_3.5.1      
[21] fs_1.5.0          ps_1.4.0          testthat_3.0.0    memoise_1.1.0    
[25] glue_1.4.2        compiler_4.0.3    desc_1.2.0        prettyunits_1.1.1

If so, a solution is appending -lopenblas to line 77 so that it reads:

ENV.append "LDFLAGS", "-L#{Formula["openblas"].opt_lib} -lopenblas"

I've already compiled and benchtested R with this edit and everything seems to work fine. However, before I merge this into master, I want confirmation this is what the desired output should be.

Yes! This is the expected result! Great job!

AlfredSAM commented 3 years ago

I've also created a temporary branch dev-openblas-bigsur that implements these changes for testing.

I am looking forward to the push to the master branch! Thanks so much!

sethrfore commented 3 years ago

Merged. You're welcome!