Linuxbrew / legacy-linuxbrew

:skull: This repository is defunct, because it has been split into https://github.com/Linuxbrew/brew and https://github.com/Linuxbrew/homebrew-core
http://linuxbrew.sh
Other
2.23k stars 295 forks source link

Add BLAS and LAPACK to Linuxbrew #1075

Closed ahundt closed 8 years ago

ahundt commented 8 years ago

Please follow the general troubleshooting steps first:

Please replace this line with a brief summary of your issue AND if reporting a build issue include the link from:

brew gist-logs <formula> (where <formula> is the name of the formula that failed to build).

https://github.com/Homebrew/homebrew-science/issues/3543 https://gist.github.com/4ece9ffc0a110e9ecbbe140f5a58fa4a

Feature/Formula Requests:

One specific example is that the blas/lapack assumptions differ from OS X, and cryptic error messages result.

OS X homebrew makes a set of assumptions regarding what software is already available. Linuxbrew can't make these same assumptions. Can we make these differences be dealt with in an easy to understand and fix manner, avoiding cryptic compiler errors?

A simple fix for this case would be to add an openblas recommended dependency to suite-sparse, but it is probably worth thinking about other cases that most likely exist.

sjackman commented 8 years ago

A simple fix for this case would be to add an openblas recommended dependency to suite-sparse, but it is probably worth thinking about other cases that most likely exist.

Mac has a default/canonical implementation of BLAS/LAPACK, Accelerate.framework. What should the default implementation of BLAS/LAPACK be? @Homebrew/science I don't know much about this area myself. I believe there's an existing issue for this somewhere in either Linuxbrew / Homebrew-science.

For simpler dependencies the solution is simply to add the dependency to the Linuxbrew formula. e.g. depends_on "libxml2" unless OS.mac?

ahundt commented 8 years ago

I don't think @homebrew/science will reach anyone. @dpo is perhaps the most likely person to ask? However, he sent me over here :-)

depends_on "libxml2" unless OS.mac? looks like a decent workaround temporarily on specific OS versions. @dpo would it be acceptable if I submitted a pull request to homebrew/science to that effect?

Regarding the existing blas issue, I think this is the issue you are talking about: https://github.com/Homebrew/homebrew-science/issues/7

However, I've run into this sort of problem in other non-blas cases. For example I think xz Isn't in ubuntu but is needed to install something. I made an issue here in the past about it. Is there any way that type of issue where dependencies not encapsulated by brew could be made easier to figure out in general?

Furthermore, what if the underlying OS provides a dependency it in the non mac case? That's probably something that would happen if you use dsl linux vs ubuntu, for example.

dpo commented 8 years ago

About BLAS, there's https://github.com/Homebrew/homebrew-science/pull/2889 that was closed recently. You might want to give it a try and perhaps pick it up? It was also trying to accommodate custom BLAS/LAPACK.

Perhaps brew doctor in Linuxbrew could warn when BLAS/LAPACK are missing?

I'd love to have a more reliable BLAS dependency for Linux. For now, we have to resort to logic such as https://github.com/Homebrew/homebrew-science/blob/master/superlu.rb#L47, which works as long as a BLAS/LAPACK is installed.

I'm also open to a formula for ATLAS with accompanying LAPACK. That's essentially what you get when you install prebuilt binaries from a Linux package manager. The formula would be keg only on OSX, but wouldn't need to be on Linux. It could be part of the BLAS requirement above.

eiennohito commented 8 years ago

As a side comment, Intel MKL is free for any use right now (registration is required however). https://software.intel.com/en-us/articles/free_mkl

Personally, I would like to use it as BLAS/LAPACK implementation.

dpo commented 8 years ago

I don't think MKL is available for 10.9 unfortunately. It could be supported (via the BLAS requirement) but I don't think it should be the default.

eiennohito commented 8 years ago

Probably should not be a default one, but it should be possible to use it as an implementation.

sjackman commented 8 years ago

Linuxbrew should have :blas and :lapack requirements (do they come as a pair, or does one depend on the other?) that checks for BLAS/LAPACK libraries and has a default_formula of a reasonable default BLAS/LAPACK implementation. Which implementation should that be? Does openblas provide both BLAS and LAPACK? Does ATLAS?

sjackman commented 8 years ago

However, I've run into this sort of problem in other non-blas cases. For example I think xz Isn't in ubuntu but is needed to install something.

We're adding these missing dependencies to Linuxbrew as they're uncovered. Submit a pull request to add to that formula depends_on "xz" unless OS.mac?

dpo commented 8 years ago

@sjackman openblas supplies both BLAS and LAPACK and we already have a formula for it. Usually both are needed at the same time so I don't think we need two requirements; just :blas would probably do.

ATLAS only supplies an optimized BLAS, but it's then a simple matter of building an optimized LAPACK library against it. I propose we go with openblas.

sjackman commented 8 years ago

The default_formula of the :blas requirement will be atlas. The default_formula of the :lapack requirement wil be openblas. openblas will depends_on :blas => :recommended Make sense?

sjackman commented 8 years ago

@dpo Would you like to submit a PR for atlas? It would be nice to get the :blas and :lapack requirements into Homebrew so that we can use depends_on :lapack rather than depends_on :lapack unless OS.mac?

dpo commented 8 years ago

The default_formula of the :blas requirement will be atlas. The default_formula of the :lapack requirement wil be openblas. openblas will depends_on :blas => :recommended Make sense?

openblas supplies both BLAS and LAPACK. There's no need to have two requirements because BLAS and LAPACK are used together in 99.99% of cases.

I'm proposing we only have a :blas requirement with either: 1) openblas as default_formula, or 2) atlas as default_formula, which will install ATLAS together with a LAPACK library built against it.

sjackman commented 8 years ago

I'd prefer that formula dependencies model the actual dependencies. atlas has no dependencies and installs only itself. openblas depends upon some implementation of BLAS (:recommended) and alternatively uses its own implementation of BLAS. The default implementation of BLAS is atlas. The user can at their discretion use a different implementation of BLAS that provides libblas.so. The default implementation of LAPACK is openblas. The :blas requirement should check that libblas.so is installed. The :lapack requirement should check that liblapack.so is installed. If it makes more sense to have only one requirement named :blas, it should check that both libblas.so and liblapack.so are installed. I find that confusing myself.

dpo commented 8 years ago

When things calm down for me I'll have a shot at an ATLAS formula. One source of trouble with ATLAS is that LAPACK must be built at the same time, so they might have to appear in the same formula, but I'll check.

openblas depends upon some implementation of BLAS (:recommended) and alternatively uses its own implementation of BLAS.

OpenBLAS provides the BLAS, it can't depend on an external BLAS. It's BLAS and LAPACK packaged into a single libopenblas library.

sjackman commented 8 years ago

One source of trouble with ATLAS is that LAPACK must be built at the same time

Ah, that would change things. That link mentions netlib LAPACK. Is there an equivalent option for openblas LAPACK?

OpenBLAS provides the BLAS, it can't depend on an external BLAS. It's BLAS and LAPACK packaged into a single libopenblas library.

I thought OpenBLAS could make use of ATLAS BLAS?

Thanks for answering my questions, Dominique. I'm trying to sort out for myself how all these packages interoperate.

dpo commented 8 years ago

Sorry if this is all a bit fuzzy. There is only one BLAS and there is only one LAPACK. Their source code is available on Netlib and they're usually called the "standard" BLAS and the "standard" LAPACK. Their mission is to perform common vector and (dense) matrix operations (such as vector addition, matrix-vector product, matrix-matrix product, certain matrix factorizations, etc.) more or less efficiently by taking advantage of cache size or other architectural factors. However, they were written in such a way that many of their subroutines depend on parameters. When people talk about "optimized" BLAS and LAPACK, they mean that a certain search procedure has been applied to those parameters so as to produce the lowest possible run time (or Gflops, or throughput, or something else).

ATLAS is a wrapper around BLAS that performs such a search on the local architecture at install time. My understanding (but I should double check) is that if requested at install time, it will also work on parameters exposed in LAPACK.

OpenBLAS is the same as the standard BLAS and LAPACK with certain parts rewritten in assembly to be closer to the metal. There's probably a parameter search in there too.

The Accelerate framework on OSX provides exactly the same thing, except that the search procedure is proprietary to Apple. The MKL is the same, but proprietary to Intel (the MKL also contains other stuff). The ACML is the same, but proprietary to AMD. Etc, etc.

I hope this clarifies a bit. In almost all applications where the BLAS is needed, LAPACK is also needed. In all applications where LAPACK is needed, the BLAS is needed. That's why it makes some sense to package them together. They go hand in hand.

sjackman commented 8 years ago

Thanks for the explanation, Dominique. That helps a lot. I've just discovered that homebrew/dupes/lapack, which is netlib BLAS/LAPACK, provides both libblas.so and liblapack.so! The simplest solution for Linuxbrew would be that formula that depend on these libraries should

depends_on "homebrew/dupes/lapack" unless OS.mac?

That's problem not the best solution, but it's a good starting point for how should we improve on that. The next increment would be a :lapack (or :blas) requirement that checks whether libblas.so and liblapack.so are already installed and so satisfy the requirement, and otherwise have a default_formula "homebrew/dupes/lapack".

openblas provides neither libblas.so nor liblapack.so. It provides libopenblas.so. Does that library provide the same interface as (i.e. satisfy) libblas.so and liblapack.so? If so, perhaps on Linux openblas should create symlinks from libopenblas.so to libblas.so and liblapack.so. What do you think?

homebrew/dupes/lapack and openblas conflict because they both install include/lapacke.h, even though their libraries are named differently.

Do we need ATLAS if we already have two BLAS/LAPACK implementation to choose from?

dpo commented 8 years ago

Didn't know about homebrew/dupes/lapack. It's a good starting point but it won't be efficient.

openblas provides neither libblas.so nor liblapack.so. It provides libopenblas.so. Does that library provide the same interface as (i.e. satisfy) libblas.so and liblapack.so?

It does.

If so, perhaps on Linux openblas should create symlinks from libopenblas.so to libblas.so and liblapack.so. What do you think?

That's a good point. It's easy to amend the formula, but it's keg only because on OSX libblas.dylib and liblapack.dylib point to the Accelerate framework. Perhaps openblas shouldn't be keg_only on Linux?

Do we need ATLAS if we already have two BLAS/LAPACK implementation to choose from?

According to the LAPACK README,

The distribution tar file [...] also contains the Fortran77
reference implementation of the Basic Linear Algebra Subprograms
(the Level 1, 2, and 3 BLAS) needed by LAPACK.  However this code is
intended for use only if there is no other implementation of the BLAS
already available on your machine; the efficiency of LAPACK depends
very much on the efficiency of the BLAS.

But I suggest we go ahead and I'll work on ATLAS when I get a chance. I just gave it a quick try and it doesn't build out of the box.

dpo commented 8 years ago

Let's go with openblas: http://math-atlas.sourceforge.net/atlas_install/node60.html

sjackman commented 8 years ago

Perhaps openblas shouldn't be keg_only on Linux?

keg_only :provided_by_osx is ignored on Linuxbrew, so it's not :keg_only! =)

sjackman commented 8 years ago

That's a good point. It's easy to amend the formula, Let's go with openblas.

Great! Do we want a :blas requirement, or do we want to depends_on "openblas" unless OS.mac??

sjackman commented 8 years ago

Debian's libopenblas-dev provides libblas.so and liblapack.so in a subdirectory named /usr/lib/openblas-base and also /usr/lib/libopenblas.so. https://packages.debian.org/sid/amd64/libopenblas-dev/filelist

dpo commented 8 years ago

We're already doing depends_on "openblas" unless OS.mac? in formulas such as superlu. How would the :blas requirement work? Do nothing on OSX and use openblas on Linux? Frankly we should be using veclibfort on OSX instead of using the buggy Accelerate directly, but that might not fly because it depends_on :fortran.

sjackman commented 8 years ago

Let's stick with depends_on "openblas" unless OS.mac?.

How would the :blas requirement work? Do nothing on OSX and use openblas on Linux?

Pretty much. For extra functionality, it could check whether libblas.so and liblapack.so are already provided and do nothing if they do exist. For example installed by homebrew/dupes/lapack or symlinked by the user to their personal preferred version.

dpo commented 8 years ago

https://github.com/Homebrew/homebrew-science/pull/3570 https://github.com/Homebrew/homebrew-science/pull/3571

sjackman commented 8 years ago

Thanks for these PR, Dominique!

sjackman commented 8 years ago

Fixed by @dpo in Homebrew/homebrew-science#3570