fortran-lang / stdlib

Fortran Standard Library
https://stdlib.fortran-lang.org
MIT License
1.03k stars 162 forks source link

Interfaces and wrappers: BLAS #450

Open awvwgk opened 3 years ago

awvwgk commented 3 years ago

Description

To support linear algebra operations we want to have interfaces/wrappers for BLAS and LAPACK, maybe even to BLACS, PBLAS and ScaLAPACK at some point. Before we start working on a high-level API, there are additional stages to consider. For this issue I want to focus on BLAS only, because the size of the problem is much more limited than the other linear algebra libraries and we can flesh out the workflow

  1. How to include BLAS in stdlib?
    • building (reference) BLAS from source with fpm and/or CMake sounds like a bad idea (performance), but might be a fallback
    • linking against system BLAS and optimized BLAS libraries like MKL or OpenBLAS
  2. How due we provide the BLAS functionality?
    • interface modules like BLAS95 are available
    • do we reproduce the actual reference BLAS interface (doesn't include intent in the dummy arguments)
    • do we overload the names to drop the s/d/c/z prefixes
    • are the interfaces part of stdlib or bundled from a separate project
  3. How do we abstract the operations available in BLAS?
    • how many layers of abstractions do we want?
    • just simple wrapper to infer dimensions
    • overloaded operators
arjenmarkus commented 3 years ago

One additional thing: as the source code does not use modules, we are "polluting" the namespace with the names of the BLAS routines. So an additional step might be to put the individual routines into modules to avoid that.

Another aspect is the use of routines such as DMACH1 (not in LAPACK and BLAS, but similar routines are). Some of these venerable packages require you to adjust the code for specific machines. With Fortran in its current incarnation we can rely on intrinsic functions for most of these.

Op vr 2 jul. 2021 om 13:52 schreef Sebastian Ehlert < @.***>:

Description

To support linear algebra operations we want to have interfaces/wrappers for BLAS and LAPACK, maybe even to BLACS, PBLAS and ScaLAPACK at some point. Before we start working on a high-level API, there are additional stages to consider. For this issue I want to focus on BLAS only, because the size of the problem is much more limited than the other linear algebra libraries and we can flesh out the workflow

  1. How to include BLAS in stdlib?
    • building (reference) BLAS from source with fpm and/or CMake sounds like a bad idea (performance), but might be a fallback
    • linking against system BLAS and optimized BLAS libraries like MKL or OpenBLAS
  2. How due we provide the BLAS functionality?
    • interface modules like BLAS95 are available
    • do we reproduce the actual reference BLAS interface (doesn't include intent in the dummy arguments)
    • do we overload the names to drop the s/d/c/z prefixes
    • are the interfaces part of stdlib or bundled from a separate project
  3. How do we abstract the operations available in BLAS?
    • how many layers of abstractions do we want?
    • just simple wrapper to infer dimensions
    • overloaded operators

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/fortran-lang/stdlib/issues/450, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAN6YR6EX4HDKZCIZD5Y7ITTVWSADANCNFSM47WSLGFA .

awvwgk commented 3 years ago

@arjenmarkus I think the namespace pollution can't be helped, at least if we want to rely on optimized BLAS libraries. Putting the routines into modules would produce ABI issues unless we export them with bind(C), which kind of defeats the purpose of cleaning up the global namespace with modules in the first place.

ivan-pi commented 3 years ago

It will be good to study how NumPy embeds BLAS: Accelerated BLAS/LAPACK libraries

Kind of ironically for the fallback BLAS NumPy depends on a f2c'd version of BLAS which is patched to replace any new constructs with legacy constructs that work with f2c.

awvwgk commented 3 years ago

I was surprised to see a new release of LAPACK 3.10.0 on netlib just a few days ago, now also featuring free format source code. Therefore, I doubt that NumPy's f2c'ing strategy will be viable in the long run, maybe the transpilers planned for LFortran will be a viable alternative for NumPy at some point.

arjenmarkus commented 3 years ago

The fact that the code is on github as well, makes life a lot easier for fpm as well.

Op vr 2 jul. 2021 om 16:17 schreef Sebastian Ehlert < @.***>:

I was surprised to see a new release of LAPACK 3.10.0 on netlib http://netlib.org/lapack/lapack-3.10.0.html just a few days ago, now also featuring free format source code. Therefore, I doubt that NumPy's f2c'ing strategy will be viable in the long run, maybe the transpilers planned for LFortran will be a viable alternative for NumPy at some point.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fortran-lang/stdlib/issues/450#issuecomment-873033231, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAN6YR2O4UBJCS4EKBINZODTVXC6BANCNFSM47WSLGFA .

awvwgk commented 2 years ago

Is there interest in moving this project forward? I have an implementation of a pretty complete BLAS interface library as fpm package, which could be included in stdlib: https://github.com/awvwgk/blas-interface

There are two variants in this package, a pure variant with added intent arguments or a plain variant reflecting exactly the interface exported by the reference LAPACK project.

perazz commented 6 months ago

Integrating BLAS and LAPACK support in stdlib

Apologies if I hijack this discussion for updating it, there are already several BLAS/LAPACK issues open.

I agree with @awvwgk on the need to link against platform-optimized libraries. To do this, I think we ought to start simple, with a build of the reference BLAS/LAPACK, because:

I'm using numpy as an example: it has several options managed by the build process (fpm can't do this now), but anyways uses f2c copies of BLAS and LAPACK embedded in the repo in case none are available.

So I've been putting together a nearly-complete, Modern-Fortran version of BLAS and LAPACK which is ~90% automated from the Reference-LAPACK repo (license allows embedding in code provided that copyright is retained). Please note this is not an interface, but just a modern Fortran reimplementation: https://github.com/perazz/fortran-lapack

I would love to see that merge into stdlib. (note that we may then adopt @awvwgk's interfaces IMHO). My questions are:

Thanks and regards. @fortran-lang/stdlib @fortran-lang/admins

jvdp1 commented 6 months ago

Thank you @perazz for this work!

So I've been putting together a nearly-complete, Modern-Fortran version of BLAS and LAPACK which is ~90% automated from the Reference-LAPACK repo (license allows embedding in code provided that copyright is retained). Please note this is not an interface, but just a modern Fortran reimplementation: https://github.com/perazz/fortran-lapack

Impressive work!

I would love to see that merge into stdlib. (note that we may then adopt @awvwgk's interfaces IMHO). My questions are:

  • Is there any support for this idea to move forward?

I support totally this, and would be a very good addition for stdlib and hopefully the Fortran community.

  • Should this Modernized BLAS/LAPACK be: 1) part of stdlib; 2) an independent Fortran-lang repo?

I think it would be good to integrate it in stdlib. However, during its development, a separate branch might be needed.

3) kept in sync with Netlib-lapack, or we may be begin branching our own Modern Fortran implementation from it?

  • I also like the idea of an fpm metapackage that could handle different linking options, but that would come later I think.

Once the issues regarding fpm and stdlib due to the use of fypp are solved, such linking options will be possible with fpm, right? I guess it should be already possible with CMake.

  • Modularized BLAS/LAPACK functions do not pollute the namespace, in case somewhere else the C/F77-style names are used, looks nice compared to the F77 version?

Not sure to understand your question.

perazz commented 6 months ago

Thank you @jvdp1, let's make it happen then!

I see that I can make progress pretty fast on the separate repo, so take your time, and when ready, we can merge it to the linear algebra branch with a PR. I think it may even be more convenient to leave it as a separate repo until folks want try out and give feedback the modern APIs, because they can do it easily with fpm. Both options will work.

Once the issues regarding fpm and stdlib due to the use of fypp are solved, such linking options will be possible with fpm, right? I guess it should be already possible with CMake.

I think so. IMHO All that's needed is the ability to define/undefine a macro flag to tell the library whether the internal implementation, or the external library, should be used. This is no problem for CMake, but maybe not even for the stdlib-fpm branch: one could just require the user to add a well-named macro at the package level, I imagine something like

[dependencies]
stdlib = "*"

[preprocess]
[preprocess.cpp]
macros = ["STDLIB_WITH_EXTERNAL_BLAS"]
perazz commented 6 months ago

Not sure to understand your question.

I meant that if one wants to use the local implementation, they can just call use stdlib_linalg_blas, only: stdlib_dgeev from the internal implementation because there will never be duplicate routines with the default dgeev name.

gnikit commented 6 months ago

Thanks for the initiative @perazz, it's good to see this (collection of) issue(s) get traction!

I think we ought to start simple, with a build of the reference BLAS/LAPACK

I very much agree with this and the two points below it. Let's get something working and in the hands of users, and we can iterate on the solution as feedback arrives.

  • Is there any support for this idea to move forward?

Yes, at least from me, but I would like us to converge towards some design principles (see below).

  • Should this Modernized BLAS/LAPACK be: 1) part of stdlib; 2) an independent Fortran-lang repo? 3) kept in sync with Netlib-lapack, or we may be begin branching our own Modern Fortran implementation from it?

It depends. If we are to use the same architectural design as it's currently used in stdlib it should be 1). There have been discussions in the past that brought up the fact that stdlib is distributed in a monolithic manner and we should try and modularise it's components, similar to C++'s Boost (my analogy). If we were to start moving in that direction then it should be 2), emphasis given that this repo lives under Fortran-lang.

Another solution that I would consider is doing 1) and 2), with the repo being a Git submodule in the main stdlib repo. This way the development (manual, automated, or semi-automated) can be isolated from the main stdlib repo, but still adhere to the monolithic manner that we currently deploy. fpm (v0.10.0) might struggle with Git submodules but I can think of at least 2 solutions to this problem.

I believe that the 3rd point is not mutually exclusive to 1) and 2). If updating the reference BLAS/LAPACK in some manner, that does include a lot of manual work is possible, I would be in favour of that, if on the other hand it is not (for any number of reasons) we can use a reimplementation. Either way, I think we should provide a fallback version of BLAS/LAPACK packaged with stdlib (as it has been mentioned in the thread already).

  • I also like the idea of an fpm metapackage that could handle different linking options, but that would come later I think.
  • Modularized BLAS/LAPACK functions do not pollute the namespace, in case somewhere else the C/F77-style names are used, looks nice compared to the F77 version?

I agree with both of these. The only thing that I would caution is to make it very clear to users that whatever fpm options we use to get this to work are highly experimental and might change/be removed in the future. To that end it might be worth adding an experimental table in fpm manifest where we can field test such features and then either make mainstream or deprecated (with a warning of at least 1 release).


I think doing this will finally bring stdlib's linalg capabilities on-par or beyond a lot of other languages and frameworks. Thanks @perazz for advocating and spearheading this effort!