From 653ab0d1ce4e9cb34b2c381559da5dd07a95e238 Mon Sep 17 00:00:00 2001
From: Iñaki Úcar <iucar@fedoraproject.org>
Date: Jan 27 2022 10:08:55 +0000
Subject: [PATCH 1/3] add BLAS/LAPACK guidelines


---

diff --git a/guidelines/modules/ROOT/nav.adoc b/guidelines/modules/ROOT/nav.adoc
index 2ba46c7..a941ba4 100644
--- a/guidelines/modules/ROOT/nav.adoc
+++ b/guidelines/modules/ROOT/nav.adoc
@@ -65,6 +65,7 @@
 ** xref:Tcl.adoc[Tcl/Tk extensions]
 
 * Other Domain-specific Guidelines
+** xref:BLAS_LAPACK.adoc[BLAS/LAPACK]
 ** xref:CronFiles.adoc[CronFiles]
 ** xref:Drupal7.adoc[Drupal7]
 ** xref:Emacs.adoc[Emacs]
diff --git a/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
new file mode 100644
index 0000000..3951ed0
--- /dev/null
+++ b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
@@ -0,0 +1,164 @@
+= Linear Algebra Libraries
+:toc:
+
+== Introduction
+
+BLAS (Basic Linear Algebra Subprograms) and LAPACK (Linear Algebra PACKage)
+are routines that provide standard building blocks for performing a wide range of linear algebra operations operations.
+There are stable reference implementations from https://netlib.org/[Netlib] written in Fortran,
+with C interfaces available (called CBLAS and LAPACKE respectively),
+as well as several optimized implementations providing fast subsets of these APIs.
+
+=== Available implementations
+
+* `blas`, `lapack` - Netlib's reference implementation of the Fortran and C interfaces.
+* `atlas` - Automatically Tuned Linear Algebra Software.
+* `blis` - BLAS-like Library Instantiation Software framework.
+* `openblas` - OpenBLAS, an optimized BLAS based on GotoBLAS2.
+
+ATLAS, BLIS and OpenBLAS provide BLAS and a subset of LAPACK.
+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).
+
+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
+via https://www.mpi-magdeburg.mpg.de/projects/flexiblas[FlexiBLAS].
+
+=== BLAS/LAPACK wrapper
+
+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:
+
+* 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 and BLIS, as well as non-free alternatives such as Intel MKL, ACML...
+* Flexible per-system/user/host configuration files.
+* Basic profiling support.
+
+[NOTE]
+====
+Fedora ships `openblas-openmp` as the system-wide default backend.
+====
+
+== Packaging BLAS/LAPACK dependent packages
+
+Consumers of any subset of BLAS and/or LAPACK MUST compile against FlexiBLAS (unless not supported; see below).
+
+[NOTE]
+====
+.Exceptions
+* Although support for LAPACKE is planned, the few packages using this interface are not yet supported by FlexiBLAS as of v3.1.2.
+  These packages MUST link against OpenBLAS instead, or `lapack` if the routines used are not supported by this backend.
+  Current exceptions of this type include `opencv`, `scamp` and `sextractor`.
+* On rare occasions, a package may use an exceptional feature present in a particular backend
+  and cannot be adapted to FlexiBLAS by any means.
+  In such cases, the package MUST link against this backend.
+  Current exceptions of this type include `julia` (linked against OpenBLAS) and `psfex` (linked against ATLAS).
+====
+
+=== Build requirements
+
+First, only FlexiBLAS's development package MUST be listed in `BuildRequires`:
+
+....
+BuildRequires: flexiblas-devel
+....
+
+Alternatively, packages using `pkg-config` SHOULD express this dependency as
+
+....
+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.
+However, note that if the package '''only''' supports this 64-bit interface,
+then 32-bit architectures MUST be excluded.
+
+=== Configuration
+
+Packages using `pkg-config` will automatically obtain the proper paths to the headers and libraries.
+Similarly, CMake-based projects using `FindBLAS` will automatically detect
+and configure the proper flags for FlexiBLAS (since CMake v3.19),
+and no further action will be required from the packager.
+
+Unfortunately, many upstream projects present heterogeneous ways of accessing these APIs.
+In a best-case scenario, the building framework may define specific options to explicitly set the BLAS and/or LAPACK libraries.
+More commonly, the packager MUST ensure that `+%{_includedir}/flexiblas+` and `+%{_libdir}/flexiblas+`
+are injected as header and library locations in the proper flags and configuration files.
+In rare occasions, hardcoded paths in source files MUST be modified, and patches MAY be required.
+The packager SHOULD work with upstream to standardize the way in which these libraries are detected and configured.
+
+[IMPORTANT]
+====
+To ensure that the program has been properly linked against FlexiBLAS,
+the packager MUST check that the `Requires` are correct,
+i.e., `libflexiblas` is listed, but not `libblas`, `liblapack` or any other backend.
+====
+
+=== Tests
+
+Optimized BLAS/LAPACK backends are much faster than Netlib's reference implementation,
+but in return results may vary a little.
+Consequently, tests that are too tight (with too small tolerances) may fail.
+In these cases, the packager SHOULD enable the reference implementation in the `%check` section as follows:
+
+....
+export FLEXIBLAS=netlib
+....
+
+or, alternatively, via `FLEXIBLAS64` for builds using 64-bit integers.
+
+== 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 (i.e., `flexiblas-openblas-openmp(64)`).
+This is set via the "default=IMPLEMENTATION-NAME" key (by default, `default=openblas-openmp`),
+present in the main configuration file shipped in the main subpackages,
+`+%{_sysconfdir}/flexiblasrc+` and `+%{_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.
diff --git a/guidelines/modules/ROOT/pages/index.adoc b/guidelines/modules/ROOT/pages/index.adoc
index 47270ba..2bb4f9e 100644
--- a/guidelines/modules/ROOT/pages/index.adoc
+++ b/guidelines/modules/ROOT/pages/index.adoc
@@ -3147,6 +3147,7 @@ Some applications, languages and build systems
 have specific guidelines written for them, located on their own pages:
 
 * xref:Ada.adoc[Ada]
+* xref:BLAS_LAPACK.adoc[BLAS/LAPACK]
 * xref:C_and_C++.adoc[C and {cpp}]
 * xref:CMake.adoc[CMake]
 * xref:D.adoc[D]

From abdc6a8cdf799423770989b84d5e18385224dbf2 Mon Sep 17 00:00:00 2001
From: Iñaki Úcar <iucar@fedoraproject.org>
Date: Jan 27 2022 10:08:55 +0000
Subject: [PATCH 2/3] simplify BuildRequires section, add a few more details to the configuration


---

diff --git a/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
index 3951ed0..757dcb7 100644
--- a/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
+++ b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
@@ -72,30 +72,22 @@ First, only FlexiBLAS's development package MUST be listed in `BuildRequires`:
 BuildRequires: flexiblas-devel
 ....
 
-Alternatively, packages using `pkg-config` SHOULD express this dependency as
+which brings all the necessary development files,
+both for the 32-bit (the most common) and the 64-bit integer interface.
 
-....
-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.
-However, note that if the package '''only''' supports this 64-bit interface,
-then 32-bit architectures MUST be excluded.
+[IMPORTANT]
+====
+If the package *only* supports the interface for 64-bit integers,
+then 32-bit architectures MUST be excluded
+(see xref:index.adoc#_arch_specific_runtime_and_build_time_dependencies[Arch-Specific Runtime and Build-Time Dependencies]).
+====
 
 === Configuration
 
-Packages using `pkg-config` will automatically obtain the proper paths to the headers and libraries.
+The packager MUST specify `flexiblas` or `flexiblas64`
+(for the 32-bit or 64-bit interface respectively)
+as both the BLAS and LAPACK library names where applicable,
+and packages using `pkg-config` will automatically obtain the proper flags for the headers and libraries.
 Similarly, CMake-based projects using `FindBLAS` will automatically detect
 and configure the proper flags for FlexiBLAS (since CMake v3.19),
 and no further action will be required from the packager.
@@ -103,7 +95,9 @@ and no further action will be required from the packager.
 Unfortunately, many upstream projects present heterogeneous ways of accessing these APIs.
 In a best-case scenario, the building framework may define specific options to explicitly set the BLAS and/or LAPACK libraries.
 More commonly, the packager MUST ensure that `+%{_includedir}/flexiblas+` and `+%{_libdir}/flexiblas+`
-are injected as header and library locations in the proper flags and configuration files.
+(or `+%{_includedir}/flexiblas64+` and `+%{_libdir}/flexiblas64+`)
+are injected as header and library locations in the proper flags and configuration files,
+and/or `-lflexiblas` (or `-lflexiblas64`) is provided to the linker.
 In rare occasions, hardcoded paths in source files MUST be modified, and patches MAY be required.
 The packager SHOULD work with upstream to standardize the way in which these libraries are detected and configured.
 

From 4ac203da355fa225bde7459006e4d2753f2dc8c9 Mon Sep 17 00:00:00 2001
From: Iñaki Úcar <iucar@fedoraproject.org>
Date: Jan 27 2022 10:09:17 +0000
Subject: [PATCH 3/3] remove duplicated word


---

diff --git a/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
index 757dcb7..5638522 100644
--- a/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
+++ b/guidelines/modules/ROOT/pages/BLAS_LAPACK.adoc
@@ -4,7 +4,7 @@
 == Introduction
 
 BLAS (Basic Linear Algebra Subprograms) and LAPACK (Linear Algebra PACKage)
-are routines that provide standard building blocks for performing a wide range of linear algebra operations operations.
+are routines that provide standard building blocks for performing a wide range of linear algebra operations.
 There are stable reference implementations from https://netlib.org/[Netlib] written in Fortran,
 with C interfaces available (called CBLAS and LAPACKE respectively),
 as well as several optimized implementations providing fast subsets of these APIs.

