From Fedora Project Wiki
(Note that we need proper sonames)
m
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{Draft}}
 
{{Draft}}
 +
 
= Introduction =
 
= Introduction =
  
Besides being implementations, BLAS and LAPACK are also API standards for basic linear algebra operations (such as vector and matrix multiplication).
+
Besides being implementations, BLAS and LAPACK are also API standards for basic linear algebra operations (such as vector and matrix multiplication). Many implementations of these API exist. The reference implementation of BLAS and LAPACK from Netlib is very stable but is not as fast as optimized ones such as ATLAS and OpenBLAS.
  
Many implementations of these API exist. The reference implementation of BLAS and LAPACK from netlib is very stable but is not as fast as optimized ones such as ATLAS and OpenBLAS.
+
Implementations of BLAS:
  
Implementations of BLAS:
+
* blas - Reference implementation from Netlib.
 +
* atlas - Automatically Tuned Linear Algebra Software.
 +
* blis - BLAS-like Library Instantiation Software framework.
 +
* openblas - OpenBLAS, an optimized BLAS based on GotoBLAS2.
  
*    blas - Reference implementation from netlib
+
Both BLIS and OpenBLAS provide several flavors: a sequential version, a threaded one, and another with OpenMP support (all of them with or without support for 64-bit integers).
*    atlas - Automatically Tuned Linear Algebra Software
 
*    openblas - OpenBLAS, an optimized BLAS based on GotoBLAS2
 
  
 
Implementations of LAPACK:
 
Implementations of LAPACK:
  
*   lapack - Reference implementation from netlib
+
* lapack - Reference implementation from Netlib.
*   ATLAS and OpenBLAS both provide an optimized subset of LAPACK
+
* ATLAS, BLIS and OpenBLAS provide an optimized subset of LAPACK.
  
Due to implementation differences, it is important that all components of a particular software stack link to the same BLAS/LAPACK implementation. Also, users may want to choose a particular implementation that works best for them at run time.  This guideline gives a structure that can enforce the first while allowing the second.
+
Due to implementation differences, it is important that all components of a particular software stack link to the same BLAS/LAPACK implementation. Also, users may want to choose a particular implementation that works best for them at run time.  This guideline gives a structure that can enforce the first while allowing the second, as well as providing a transparent fallback mechanism to Netlib's reference implementation for those symbols not included in the selected backend.
  
= BLAS/LAPACK implementations =
+
= BLAS/LAPACK wrapper =
  
Implementations of a BLAS and/or LAPACK library must build versions of their libraries with the libblas.so.3 and liblapack.so3 sonames containing the appropriate symbols and ship them in %{_libdir}/IMPLEMENTATION-NAME/.  Each implementation may have multiple IMPLEMENTATION-NAMEs, e.g. for serial and parallel versions.
+
[https://www.mpi-magdeburg.mpg.de/projects/flexiblas FlexiBLAS] is a framework that wraps both BLAS and LAPACK APIs in a single library. BLAS/LAPACK consumers must link against FlexiBLAS, and this wrapper is able to redirect calls to a selected optimized backend with negligible overhead. It also provides transparent fallback to Netlib's reference implementation if a certain symbol is not present in the selected backend. These are the main features:
  
For example, atlas would have:
+
* Provides a 100% BLAS and LAPACK compatible ABI/API, with interfaces for both 32- and 64-bit integers.
 +
* Runtime exchangeable BLAS and LAPACK backend without recompilation via an environment variable.
 +
* Integration of user-owned BLAS libraries without administrator privileges, even in system-wide installed programs.
 +
* Works with OpenBLAS, ATLAS, Intel MKL, ACML, ...
 +
* Flexible per-system/user/host configuration files.
 +
* Basic profiling support.
  
%files
+
FlexiBLAS provides a common interface, as well as fallbacks to Netlib's reference implementation:
...
 
%{_libdir}/%{name}-serial/libblas.so.3
 
%{_libdir}/%{name}-serial/liblapack.so.3
 
%{_libdir}/%{name}-threaded/libblas.so.3
 
%{_libdir}/%{name}-threaded/liblapack.so.3
 
  
If ILP64 (64-bit integer) implementations are available, they should be provided as wellFor openblas:
+
%files netlib
 +
%{_libdir}/flexiblas.so.x
 +
%{_libdir}/flexiblas/libflexiblas_netlib.so
 +
%{_libdir}/flexiblas/libflexiblas_fallback_lapack.so
 +
   
 +
%files netlib64
 +
%{_libdir}/flexiblas64.so.x
 +
%{_libdir}/flexiblas64/libflexiblas_netlib.so
 +
%{_libdir}/flexiblas64/libflexiblas_fallback_lapack.so
  
%files
+
and, finally, several wrappers for different implementations under different names:
...
 
%{_libdir}/%[name}-serial/libblas64.so.3
 
%{_libdir}/%{name}-serial/liblapack64.so.3
 
%{_libdir}/%{name}-serial/libblas64_.so.3
 
%{_libdir}/%{name}-serial/liblapack64_.so.3
 
  
== System level BLAS/LAPACK selection ==
+
%files atlas
 +
%{_libdir}/flexiblas/libflexiblas_atlas.so
 +
 +
%files blis-serial
 +
%{_libdir}/flexiblas/libflexiblas_blis-serial.so
 +
 +
%files blis-threads
 +
%{_libdir}/flexiblas/libflexiblas_blis-threads.so
 +
 +
%files blis-openmp
 +
%{_libdir}/flexiblas/libflexiblas_blis-openmp.so
 +
 +
%files openblas-serial
 +
%{_libdir}/flexiblas/libflexiblas_openblas-serial.so
 +
 +
%files openblas-threads
 +
%{_libdir}/flexiblas/libflexiblas_openblas-threads.so
 +
 +
%files openblas-openmp
 +
%{_libdir}/flexiblas/libflexiblas_openblas-openmp.so
 +
 +
plus the 64-bit versions for BLIS and OpenBLAS under %{_libdir}/flexiblas64 in 64-bit architectures. These are sub-packaged separately to avoid pulling the whole stack of implementations. The netlib and netlib64 sub-packages require a default implementation that is currently set to openblas-serial:
  
To allow system level selection of the desired BLAS/LAPACK implementation, alternatives are used, selecting which path is desired for /etc/ld.so.conf.d/blas-%{arch}.conf.  
+
%global default_backend openblas-serial
 +
 +
%package        netlib
 +
Requires:      %{name}%{?_isa} = %{version}-%{release}
 +
Requires:      %{name}-%{default_backend}%{?_isa} = %{version}-%{release}
 +
 +
%package        netlib64
 +
Requires:      %{name}%{?_isa} = %{version}-%{release}
 +
  Requires:      %{name}-%{default_backend}64%{?_isa} = %{version}-%{release}
  
<pre>
+
= Packaging guidelines =
Requires(post): %{_sbindir}/update-alternatives
 
Requires(postun): %{_sbindir}/update-alternatives
 
  
%install
+
== BLAS/LAPACK implementations ==
...
 
mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d
 
touch %{buildroot}%{_sysconfdir}/ld.so.conf.d/blas-%{_arch}.conf
 
echo %{_libdir}/%{name}-serial > %{buildroot}%{_sysconfdir}/ld.so.conf.d/blas-%{_arch}.conf-%{name}-serial
 
  
%post
+
Implementations of BLAS and/or LAPACK available in Fedora do not need to change anything.
%{_sbindir}/update-alternatives --install %{_sysconfdir}/ld.so.conf.d/blas-%{_arch}.conf \
 
  blas %{_sysconfdir}/ld.so.conf.d/blas-%{_arch}.conf-%{name}-serial 60
 
/sbin/ldconfig
 
  
%postun
+
== BLAS/LAPACK dependent packages ==
if [ $1 -eq 0 ] ; then
 
  %{_sbindir}/update-alternatives --remove blas %{_sysconfdir}/ld.so.conf.d/blas-%{_arch}.conf-%{name}-serial
 
fi
 
/sbin/ldconfig
 
</pre>
 
  
Current established priorities are 30 for atlas and 60 for openblas.
+
Consumers of any subset of BLAS and/or LAPACK must compile against FlexiBLAS:
  
Also, we provide libblas/liblapack:
+
BuildRequires: pkgconfig(flexiblas)
  
  %if %{_lib} == "lib64"
+
if the package requires the 32-bit interface (this is the most common case), or a conditional BuildRequires such as
Provides: libblas.so.3()(64bit)
+
 
  Provides: liblapack.so.3()(64bit)
+
  %if 0%{?__isa_bits} == 64
 +
  BuildRequires: pkgconfig(flexiblas64)
 
  %else
 
  %else
  Provides: libblas.so.3
+
  BuildRequires: pkgconfig(flexiblas)
Provides: liblapack.so.3
 
 
  %endif
 
  %endif
  
== User level BLAS/LAPACK selection ==
+
if the package uses the 64-bit interface when available. Another possibility would be to build 64-bit versions for 64-bit architectures as subpackages. However, note that if the package '''only''' supports this 64-bit interface, then 32-bit architectures must be excluded.
 
 
Environment modules are used to provide user level selection of the desired BLAS/LAPACK implementation. For each IMPLEMENTATION-NAME, the implementation package will provide an environment module, e.g.:
 
 
 
#%Module 1.0
 
# ATLAS module for loading serial atlas library
 
conflict                blas
 
prepend-path            LD_LIBRARY_PATH /usr/lib64/atlas-serial
 
 
 
as %{_datadir}/modulefiles/blas/atlas-serial.  The implementation must then require an environment module implementation:
 
 
 
Requires: environment(modules)
 
 
 
Because many (all except the reference?) BLAS/LAPACK implementations are combined BLAS/LAPACK libraries, we do not support separate specification of BLAS and LAPACK, only combinations that are explicitly known to work.
 
  
== Consistent LAPACK versions ==
+
In any case, by compiling against FlexiBLAS, they will automatically use the system-wide default backend, and will benefit from any other system/user/host-selected optimized subset of routines.
  
Most optimized BLAS implementations also offer a subset of optimized LAPACK functions.  They must then fill out the rest of the LAPACK API from the reference netlib LAPACK, either via static LAPACK library or a bundled version.  The reference LAPACK interface is slowly changing so it is important that the LAPACK API version be consistent across all LAPCK implementations on a specific release.  This is most easily handled by linking to the static LAPACK reference library.
+
= Backend selection =
  
= BLAS/LAPACK dependent packages =
+
== System-level selection ==
  
== Generic Usage ==
+
A package compiled against FlexiBLAS pulls out the corresponding flexiblas-netlib(64) subpackage, which in turn requires the default optimized backend, e.g., flexiblas-openblas-serial(64). This is set via the "default=IMPLEMENTATION-NAME" key (by default, default=openblas-serial), present in the main configuration file shipped in the main subpackages:
If the BLAS/LAPACK consumer does not require special compile time configuration for different BLAS/LAPACK implementations, it should simply build against the reference implementation:
 
  
  BuildRequires: blas-devel
+
  %files netlib
  BuildRequires: lapack-devel
+
  %config(noreplace) %{_sysconfdir}/flexiblasrc
 +
 +
%files netlib64
 +
%config(noreplace) %{_sysconfdir}/flexiblas64rc
  
so that they end up linking to libblas.so.3 and liblapack.so.3, thus allowing the implementation to be switched at run time.
+
To allow system-level selection of other BLAS/LAPACK implementations, more backends must be installed in the first place (e.g., flexiblas-atlas, flexiblas-blis-serial...), and then they can be swapped system-wide via the flexiblas CLI tool, or just by modifying the "default" key in the configuration file by hand.
  
== Compile time configuration ==
+
== User-level selection ==
  
If the consumer requires special configuration for different implementations, it should provide versions compiled with each implementation.
+
Persistent user-level selection of system-provided BLAS/LAPACK implementations can be done via the CLI tool:
  
= End-User Documentation =
+
$ flexiblas set IMPLEMENTATION-NAME
 +
$ flexiblas64 set IMPLEMENTATION-NAME
  
End users will load the implementation they desire with:
+
provided the sub-package for IMPLEMENTATION-NAME is installed.
  
module load blas/IMPLEMENTATION-NAME
+
Non-persistent user-level selection can be triggered via an environment variable:
  
TODO - choose a distribution default?
+
$ FLEXIBLAS=IMPLEMENTATION-NAME ./yourapp
 +
$ FLEXIBLAS64=IMPLEMENTATION-NAME ./yourapp64
  
 +
User-level selection of user-owned BLAS/LAPACK libraries can be achieved just by changing IMPLEMENTATION-NAME with a path to any custom BLAS/LAPACK-compatible library in the examples above.
  
 
[[Category:Packaging guidelines drafts]]
 
[[Category:Packaging guidelines drafts]]

Latest revision as of 15:43, 30 June 2020

Warning.png
This page is a draft only
It is still under construction and content may change. Do not rely on the information on this page.

Introduction

Besides being implementations, BLAS and LAPACK are also API standards for basic linear algebra operations (such as vector and matrix multiplication). Many implementations of these API exist. The reference implementation of BLAS and LAPACK from Netlib is very stable but is not as fast as optimized ones such as ATLAS and OpenBLAS.

Implementations of BLAS:

  • blas - Reference implementation from Netlib.
  • atlas - Automatically Tuned Linear Algebra Software.
  • blis - BLAS-like Library Instantiation Software framework.
  • openblas - OpenBLAS, an optimized BLAS based on GotoBLAS2.

Both BLIS and OpenBLAS provide several flavors: a sequential version, a threaded one, and another with OpenMP support (all of them with or without support for 64-bit integers).

Implementations of LAPACK:

  • lapack - Reference implementation from Netlib.
  • ATLAS, BLIS and OpenBLAS provide an optimized subset of LAPACK.

Due to implementation differences, it is important that all components of a particular software stack link to the same BLAS/LAPACK implementation. Also, users may want to choose a particular implementation that works best for them at run time. This guideline gives a structure that can enforce the first while allowing the second, as well as providing a transparent fallback mechanism to Netlib's reference implementation for those symbols not included in the selected backend.

BLAS/LAPACK wrapper

FlexiBLAS is a framework that wraps both BLAS and LAPACK APIs in a single library. BLAS/LAPACK consumers must link against FlexiBLAS, and this wrapper is able to redirect calls to a selected optimized backend with negligible overhead. It also provides transparent fallback to Netlib's reference implementation if a certain symbol is not present in the selected backend. These are the main features:

  • Provides a 100% BLAS and LAPACK compatible ABI/API, with interfaces for both 32- and 64-bit integers.
  • Runtime exchangeable BLAS and LAPACK backend without recompilation via an environment variable.
  • Integration of user-owned BLAS libraries without administrator privileges, even in system-wide installed programs.
  • Works with OpenBLAS, ATLAS, Intel MKL, ACML, ...
  • Flexible per-system/user/host configuration files.
  • Basic profiling support.

FlexiBLAS provides a common interface, as well as fallbacks to Netlib's reference implementation:

%files netlib
%{_libdir}/flexiblas.so.x
%{_libdir}/flexiblas/libflexiblas_netlib.so
%{_libdir}/flexiblas/libflexiblas_fallback_lapack.so

%files netlib64
%{_libdir}/flexiblas64.so.x
%{_libdir}/flexiblas64/libflexiblas_netlib.so
%{_libdir}/flexiblas64/libflexiblas_fallback_lapack.so

and, finally, several wrappers for different implementations under different names:

%files atlas
%{_libdir}/flexiblas/libflexiblas_atlas.so

%files blis-serial
%{_libdir}/flexiblas/libflexiblas_blis-serial.so

%files blis-threads
%{_libdir}/flexiblas/libflexiblas_blis-threads.so

%files blis-openmp
%{_libdir}/flexiblas/libflexiblas_blis-openmp.so

%files openblas-serial
%{_libdir}/flexiblas/libflexiblas_openblas-serial.so

%files openblas-threads
%{_libdir}/flexiblas/libflexiblas_openblas-threads.so

%files openblas-openmp
%{_libdir}/flexiblas/libflexiblas_openblas-openmp.so

plus the 64-bit versions for BLIS and OpenBLAS under %{_libdir}/flexiblas64 in 64-bit architectures. These are sub-packaged separately to avoid pulling the whole stack of implementations. The netlib and netlib64 sub-packages require a default implementation that is currently set to openblas-serial:

%global default_backend openblas-serial

%package        netlib
Requires:       %{name}%{?_isa} = %{version}-%{release}
Requires:       %{name}-%{default_backend}%{?_isa} = %{version}-%{release}

%package        netlib64
Requires:       %{name}%{?_isa} = %{version}-%{release}
Requires:       %{name}-%{default_backend}64%{?_isa} = %{version}-%{release}

Packaging guidelines

BLAS/LAPACK implementations

Implementations of BLAS and/or LAPACK available in Fedora do not need to change anything.

BLAS/LAPACK dependent packages

Consumers of any subset of BLAS and/or LAPACK must compile against FlexiBLAS:

BuildRequires: pkgconfig(flexiblas)

if the package requires the 32-bit interface (this is the most common case), or a conditional BuildRequires such as

%if 0%{?__isa_bits} == 64
BuildRequires: pkgconfig(flexiblas64)
%else
BuildRequires: pkgconfig(flexiblas)
%endif

if the package uses the 64-bit interface when available. Another possibility would be to build 64-bit versions for 64-bit architectures as subpackages. However, note that if the package only supports this 64-bit interface, then 32-bit architectures must be excluded.

In any case, by compiling against FlexiBLAS, they will automatically use the system-wide default backend, and will benefit from any other system/user/host-selected optimized subset of routines.

Backend selection

System-level selection

A package compiled against FlexiBLAS pulls out the corresponding flexiblas-netlib(64) subpackage, which in turn requires the default optimized backend, e.g., flexiblas-openblas-serial(64). This is set via the "default=IMPLEMENTATION-NAME" key (by default, default=openblas-serial), present in the main configuration file shipped in the main subpackages:

%files netlib
%config(noreplace) %{_sysconfdir}/flexiblasrc

%files netlib64
%config(noreplace) %{_sysconfdir}/flexiblas64rc

To allow system-level selection of other BLAS/LAPACK implementations, more backends must be installed in the first place (e.g., flexiblas-atlas, flexiblas-blis-serial...), and then they can be swapped system-wide via the flexiblas CLI tool, or just by modifying the "default" key in the configuration file by hand.

User-level selection

Persistent user-level selection of system-provided BLAS/LAPACK implementations can be done via the CLI tool:

$ flexiblas set IMPLEMENTATION-NAME
$ flexiblas64 set IMPLEMENTATION-NAME

provided the sub-package for IMPLEMENTATION-NAME is installed.

Non-persistent user-level selection can be triggered via an environment variable:

$ FLEXIBLAS=IMPLEMENTATION-NAME ./yourapp
$ FLEXIBLAS64=IMPLEMENTATION-NAME ./yourapp64

User-level selection of user-owned BLAS/LAPACK libraries can be achieved just by changing IMPLEMENTATION-NAME with a path to any custom BLAS/LAPACK-compatible library in the examples above.